Bug 675553 has landed. According to a simple grep, we’ve gone from 31656 PRBools to 3562 PRBools and from 1914 PRPackedBool to 14 PRPackedBool. The remaining ones are mostly in C code or code passing data to C.

PR_TRUE (18774 -> 17953) and PR_FALSE (22973 -> 20195) haven’t been affected as much, but now it’s your turn. Feel free to correct any PR_TRUEs or PR_FALSEs you see along the way.

Another script is available to convert any PR_TRUEs or PR_FALSEs on the lines your patches touch. It operates in the same way as the first script.

]]>2mwuhttp://blog.mozilla.org/mwu/?p=692011-07-29T06:15:49Z2011-07-29T06:15:49ZIn order to switch Mozilla away from PRBools and to real boolean types, it’s necessary to first fix any code that relies on PRBool being a plain integer. This can be accomplished by ensuring every assignment to a PRBool or return from a function returning PRBool is in fact a boolean.

I wrote a clang plugin to do this called BoolCheck. It’s like Taras’ Prcheck, except based on clang instead of elsa. BoolCheck borrows Prcheck’s tests but everything else was written from scratch.

The most complicated part of this is determining whether something is a valid boolean or not. As it turns out, PRBool isn’t the only boolean type in the mozilla code. Every once in a while, another (custom) boolean type gets assigned to a PRBool. In order to make sure that type is always used as a boolean and not a integer, that type is added to the list of types being checked for correctness.

In the end, we need to check about twelve different boolean types to ensure PRBool is only ever assigned booleans.

PRBool

PRPackedBool

JSBool

JSPackedBool

cairo_bool_t

pixman_bool_t

gboolean

PKIX_Boolean

CK_BBOOL

mdb_bool

mork_bool

realGLboolean

The actual number can vary by platform since types like gboolean would only be seen on Linux/gtk, but other platforms usually introduce their own boolean type in place of gboolean. The plugin takes a file containing a list of these types to check for boolean correctness so it can easily be used to help other projects switch to real booleans.

]]>8mwuhttp://blog.mozilla.org/mwu/?p=652011-07-27T03:39:27Z2011-07-27T03:39:27ZBug 664907 has landed on mozilla-central. This enables symlinks in chrome packaging while omnijar is enabled. So, if you are:

Working on files which are in the chrome directory (listed in a jar manifest)

Working on files which are not preprocessed

Not on Windows

Running builds out of dist/bin (or the OSX equivalent)

then running make after changes won’t be necessary. Depending on the type of files you’re working on, starting Firefox with -purgecaches is probably required, but it’s still faster than running make.

]]>0mwuhttp://blog.mozilla.org/mwu/?p=552011-07-23T07:37:03Z2011-07-23T07:30:41ZOnce upon a time, there was a tool called prcheck which checked usage of PRBools and made sure only righteous 1s and 0s were assigned to PRBools. The goal was to correct all the uses of PRBool and hopefully turn PRBool into a Real Boolean.

This didn’t happen, though many abuses of PRBool were corrected along the way.

But, there may be hope now. A new PRBool checking tool based on clang has lead to a numberofpatches correcting various misuses of PRBool across the Mozilla codebase. The abuses of PRBool are varied and creative, but they all tend to fall under two categories:

Using PRBool when some other type would be more appropriate or vice versa. (bug 671190 and bug 671417)

Returning NS_ERROR_* codes in functions that return PRBool. This is particularly bad as error codes are likely to be treated as true, and true usually means success. (bug 671185)

With the help of this clang plugin, a bit of manual build fixing, and some hours lost in gdb, we can typedef PRBool as a (real) bool. The local build here is capable of starting up, passing make check, and passing all but one xpcshell test.

More updates and code release of this clang plugin to come.

]]>4mwuhttp://blog.mozilla.org/mwu/?p=482010-09-11T00:14:11Z2010-09-11T00:14:11ZBug 533038 has landed. Extensions are no longer unpacked by default when installed. If an extension with an id such as {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d} is installed, it will show up in the profile extensions directory as a file named {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}.xpi instead of a directory named {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}. This was done to reduce the startup impact of having too many files from extensions. It will also make it possible to fix startup cache/fastload invalidation by stat’ing the extensions directory.

Extension developers should note that they can opt back into unpacked installation by adding <em:unpack>true</em:unpack> to their install.rdf. Extensions with dictionaries, binary components, or window icons are most likely to be incompatible with packed installation.

Due to the entire extension being packed, developers no longer need to pack their chrome files into jars for better startup performance. If a developer chooses to keep packing the chrome files into jars, any jars inside the xpi should not be compressed since compressed jars inside the xpi use more memory to access. The files within the jar within the xpi, however, can continue to be compressed without much impact.

]]>17mwuhttp://blog.mozilla.org/mwu/?p=82010-08-14T08:18:52Z2010-08-14T00:28:59ZWhat is omnijar?

Omnijar is a new packaging format. It’s expected to be enabled by default for Firefox 4.0b5.

The difference that omnijar makes can been seen comparing the file listings of builds before and after omnijar:

There are 61 files with omnijar. The omnijar build has 76.4% less files. Or, as I like to think of it, the non-omnijar build has 324.6% more files.

How does it work?

A comparison of different packaging formats in Mozilla

Flat packaging. The original. Just files in directories.

Jar packaging. A more sophisticated way. Files in the chrome directory are packed into jars.

Omnijar packaging. The third generation packaging format. Every file that can be placed into a jar is packed into omni.jar.

All the files that are now gone have been packed into a file named omni.jar.

Why?

It’s faster.

Storing related files in a jar is more efficient than scattering files across the filesystem. Flat packaging causes a sort of high level fragmentation where related files might be stored far apart on the disk and result in wasted time seeking. Keeping everything in a file minimizes fragmentation. Startup time is generally improved. Omnijar also paves the way for other startup optimizations.

It’s useful for developers

Omnijar improves performance for users, but it also provides a handy feature for developers – omnijar packaging can be easily converted into flat packaging. To do so, unzip the omni.jar file and delete it. Any file can then be directly edited.

Developers building Firefox with omnijar enabled (–enable-chrome-format=omni) should know that the build in the dist/bin directory is flat packaged. Files are only packed into the omnijar after packaging with |make package|.