Same-compartment realms

58 views
Skip to first unread message

Jan de Mooij

unread,
Jun 4, 2018, 12:25:44 PM6/4/18
to JS Internals list
Hi all,

There were some questions about realms and how they relate to compartments
and globals, so this is a brief overview of the JS changes we're making for
bug 1357862 [0].

A JSCompartment used to represent two things (since compartment-per-global):

1. A global object and data associated with it. The spec calls this a
realm [1].
2. Some sort of (security) membrane/sandbox: objects within a
compartment can reference each other directly, but cross-compartment
wrappers (proxies) are needed when compartment A wants to reference an
object in compartment B.

One problem with this is that websites often use iframes and each frame
needs to have its own global object, so we currently end up with multiple
compartments and CCW overhead is a serious performance cliff.

To address this, we're splitting JSCompartment in two different classes:
JS::Compartment (storing the wrapper map and representing the security
concept) and JS::Realm (one realm per global, most of the state that used
to be in JSCompartment is now in JS::Realm). Then it will be possible for
Gecko (and the JS shell, of course [2]) to put multiple realms in the same
compartment and objects in these realms can then just reference each other
directly without wrapper overhead. Wrappers will still be necessary for
realms that live in different compartments.

There will still be a "current" global/realm, cx->realm(): AutoCompartment
has been renamed to AutoRealm and now enters a realm. The interpreter and
the JITs will be able to make cross-realm calls and so they'll have to
update cx->realm_ before/after scripted/native calls. This means all stack
frames within a single Activation will be same-compartment but not
necessarily same-realm.

Each JSScript belongs to a single realm. For objects, things are a bit more
complicated: because cross-compartment wrappers will be shared by all
realms in the compartment, it doesn't make a lot of sense to use
|wrapper->realm()|, |wrapper->global()| or |AutoRealm ar(cx, wrapper)|.
We'll have to do an audit for each of these and change the default behavior
to assert or return nullptr if we have a CCW [3]. We also have to audit all
assertSameCompartment calls and change some of them to assert same-realm
instead [4].

On the Gecko side there will be other changes (for document.domain and
WindowProxy/Location security checks), but this shouldn't really affect
SpiderMonkey.

So we now have the following three concepts:

- Zone: the GC unit. This typically stores things related to
allocation/GC. In the browser, there's roughly one zone per tab. Each zone
has a list of compartments.


- Compartment: all about security and wrappers (please don't add new
fields to this unless really necessary, prefer Realm or Zone). Each
compartment has a list of realms.


- Realm: a global object and things related to it.

I hope this helps. Let me know if you have any questions/concerns.

Jan

[0] https://bugzilla.mozilla.org/show_bug.cgi?id=1357862
[1] https://tc39.github.io/ecma262/#sec-code-realms
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1466501
[3] https://bugzilla.mozilla.org/show_bug.cgi?id=1466112
[4] https://bugzilla.mozilla.org/show_bug.cgi?id=1466118

Paul Bone

unread,
Jun 5, 2018, 1:50:56 AM6/5/18
to Jan de Mooij, JS Internals list
On Mon, Jun 04, 2018 at 06:25:32PM +0200, Jan de Mooij wrote:
> Hi all,
>
> I hope this helps. Let me know if you have any questions/concerns.

Could you explain (or point me to an explaination) of what Realms are for?
I've gathered that they're a TC39 thing that's being added, maybe for
security? but since they don't restrict references between realms the way
compartments and CCWs do, maybe I'm mistaken? Why add them?

I expect the answer is in one of the references or almost-common knowledge,
but I seem to have missed it, sorry.

--
Paul Bone
http://paul.bone.id.au

Jan de Mooij

unread,
Jun 5, 2018, 3:27:08 AM6/5/18
to Paul Bone, JS Internals list
On Tue, Jun 5, 2018 at 7:50 AM, Paul Bone <pb...@mozilla.com> wrote:

> Could you explain (or point me to an explaination) of what Realms are for?
> I've gathered that they're a TC39 thing that's being added, maybe for
> security? but since they don't restrict references between realms the way
> compartments and CCWs do, maybe I'm mistaken? Why add them?
>
> I expect the answer is in one of the references or almost-common knowledge,
> but I seem to have missed it, sorry.
>

Realms are a TC39 thing, but they're not new - a "realm" is just a global
object and things associated with it (for instance, each global object has
its own copy of Object.prototype and other builtin functions and
prototypes). See https://tc39.github.io/ecma262/#sec-code-realms

So if you have a website with 10 <iframe>s, there will be 11 global objects
and currently that means there must be 11 compartments. We're changing that
so there will still be 11 globals/realms, but it will be possible to have
less than 11 compartments because we will be able to group multiple
globals/realms in one compartment. This will eliminate CCW overhead and
that's why we're doing this.

There is a TC39 proposal to add APIs to create new realms etc, but that's
unrelated to this project (I only heard about that last week).

Jan

Jan de Mooij

unread,
Jun 5, 2018, 3:56:37 AM6/5/18
to Paul Bone, JS Internals list
On Tue, Jun 5, 2018 at 9:26 AM, Jan de Mooij <jdem...@mozilla.com> wrote:

> There is a TC39 proposal to add APIs to create new realms etc, but that's
> unrelated to this project (I only heard about that last week).
>

To clarify: it's not entirely unrelated because if we *do* implement this
new proposal, perf will be much better with same-compartment realms so
that's great. However, the reason we started working on same-compartment
realms is to improve perf on existing websites (even websites written
decades ago).

Jan

Paul Bone

unread,
Jun 5, 2018, 8:33:03 PM6/5/18
to Jan de Mooij, JS Internals list
On Tue, Jun 05, 2018 at 09:26:58AM +0200, Jan de Mooij wrote:
> On Tue, Jun 5, 2018 at 7:50 AM, Paul Bone <pb...@mozilla.com> wrote:
>
> > Could you explain (or point me to an explaination) of what Realms are for?
> > I've gathered that they're a TC39 thing that's being added, maybe for
> > security? but since they don't restrict references between realms the way
> > compartments and CCWs do, maybe I'm mistaken? Why add them?
> >
> > I expect the answer is in one of the references or almost-common knowledge,
> > but I seem to have missed it, sorry.
> >
>
> Realms are a TC39 thing, but they're not new - a "realm" is just a global
> object and things associated with it (for instance, each global object has
> its own copy of Object.prototype and other builtin functions and
> prototypes). See https://tc39.github.io/ecma262/#sec-code-realms
>
> So if you have a website with 10 <iframe>s, there will be 11 global objects
> and currently that means there must be 11 compartments. We're changing that
> so there will still be 11 globals/realms, but it will be possible to have
> less than 11 compartments because we will be able to group multiple
> globals/realms in one compartment. This will eliminate CCW overhead and
> that's why we're doing this.

Thanks Jan, that makes sense.
Reply all
Reply to author
Forward
0 new messages