(There's a tl;dr at the bottom if you don't want to read the whole thing).

Hello all,

For B2G we have found the memory overhead of a compartment for each JSM/JS
component to be too high for the device.  We have explored various
techniques to lower the overhead of a compartment, but unfortunately those
fixes that would help at all are either too risky for or cannot be
completed in time for Gecko 18.  We have decided instead to consolidate all
JSMs and JS components into a single compartment in B2G.

Because of architectural changes to the JS engine since
compartment-per-global landed, that means that all JSMs and JS components
will share a single global object.  Currently component and module loading
works by creating a new global for each script and executing the script
against that global.  Constructs like 'var', 'let', 'const', and
'function', when executed at global scope, set properties on the global
object that the JS component loader can grab.  When the pref that we've
added is set, we will use the same global for every script and instead
execute the script as a function with a 'this' object unique to each
script.  At function scope, 'var', 'let', 'const', and 'function' will not
create properties that are accessible outside the function.  To work around
this, we have changed to set properties via assignment on the 'this'
object.  At global scope this has essentially the same effect as the
existing setup, and at function scope we can now access the properties
after the function has executed.

Executing the scripts as functions avoids most of the ways they would
interfere with each other.  It does not, however, fix bareword assignments
(which will still create global properties) or things like mucking with
Object.prototype.  Fortunately these issues appear to be quite rare in our
code.  We decided to make these changes globally, even though we will not
be turning this on for Firefox, to avoid trying to determine exactly what
is used in B2G and what is not.

tl;dr: Code in Gecko must now set "magic" properties (such as
EXPORTED_SYMBOLS, the symbols themselves, and NSGetFactory) on the 'this'
object instead of implicitly on the global via 'var', 'let', 'function',
'const', etc

So:

const EXPORTED_SYMBOLS = ["Foo", "Bar"];
let Foo = 3;
function Bar() { dump("hi"); }
var NSGetModule = ...;

becomes

this.EXPORTED_SYMBOLS = ["Foo", "Bar"];
this.Foo = 3;
this.Bar = function Bar() { dump("hi"); }
this.NSGetModule = ...;

- Kyle
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to