Running Extension Code In Another Process

Friday, December 3rd, 2010

In order to support running Jetpack-style extensions in another process, Firefox 4 has support for running arbitrary JavaScript code in a separate process. Although this code was designed primarily to support the Jetpack SDK, Firefox and extensions can use this support to run arbitrary code in a separate process.

Running code in a separate process has advantages similar to running code in a separate thread. The running code will not block the main Firefox user interface. An added advantage is crash protection: if the code causes a crash, it will not take down the entire browser. There may also be some performance benefits from separating the garbage collection heaps and avoiding XPCOM overhead.

The basic steps to start a subprocess and run code in it are as follows:

var process = Components.classes[";1"].
process.evalScript("Put your JS here");
// When you are done with the process, you should explicitly destroy it.

Of course, running a script in another process isn’t that useful unless you can communicate with it. This is accomplished by passing messages back and forth. To send a message to the remote process, use process.sendMessage:

process.sendMessage("messageName", param...)

To receive messages from the remote process, register a receiver function:

process.registerReceiver("messageName, function(messageName, argument...) { ... });

The remote process has access to a similar set of global functions, as well as the ability to create sandboxes and use ctypes. For more information about the full capabilities, see the Mozilla Developer Center documentation. Note that code running in a jetpack-style process does not have access to XPCOM, because XPCOM is not started in the jetpack process; it runs code using only the JavaScript engine.

If an extension is using ctypes to work with third-party code or OS libraries, I strongly encourage that extension to consider running the code in a separate process for crash protection. If an extension has long-running or computationally expensive tasks, it might make sense to move those into a separate process as well. If nothing else, it will make it much easier to measure the CPU and memory usage of that code separate from the rest of Firefox.