mozilla-central: Now with 88.7% less PRBool!

September 29th, 2011 by mwu

3263 files changed, 30182 insertions(+), 30183 deletions(-)

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.

A script is available to help unbitrot your mercurial patch queue. More info is available in the post on dev-planning.

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.

The Twelve Booleans of Mozilla

July 28th, 2011 by mwu

In 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.

BoolCheck can check code like this:

typedef void (*prboolFuncPointerType)(PRBool i, double j, PRBool k);

prboolFuncPointerType* f;

void foo() {
  int foo = 12;
  PRBool zoo = 13;
  (*f)(foo, 44, 99);

and output errors like this:

% clang++ -c -Xclang -load -Xclang ../ -Xclang -add-plugin -Xclang boolcheck -Xclang -plugin-arg-boolcheck -Xclang -load-type-list -Xclang -plugin-arg-boolcheck -Xclang test-bools error: Literal is not a valid boolean
  PRBool zoo = 13;
               ^~ error: Non-boolean expression
  (*f)(foo, 44, 99);
       ^~~ error: Literal is not a valid boolean
  (*f)(foo, 44, 99);
3 errors generated.

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
  • 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.

Symlinks enabled on omnijar builds

July 26th, 2011 by mwu

Bug 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.

Killing PRBool with clang and a little bit of fire

July 23rd, 2011 by mwu

Once 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 number of patches 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.

Extensions now installed packed

September 10th, 2010 by mwu

Bug 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.

Omnijar. How does it work?

August 13th, 2010 by mwu

What 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:
« Read the rest of this entry »