Is only one JSContext allowed per thread in JS 76?

Hi,

A quick question if I may...
Am I correct in thinking that only one JSContext is allowed per thread in JS 76 (even if it is the main thread)?
I'm assuming that this must be the case as in js::NewContext pretty much the first thing it checks is
 
 MOZ_RELEASE_ASSERT(!TlsContext.get());

and this asserts on a debug build if I try to create a second context.

In the older releases you used to be able to have a single JSRuntime but multiple JSContexts on a single thread and we made use of that. Each 'script' had its own Context but they were all running concurrently on a single thread.
My (no doubt incorrect) understanding was that back then Spidermonkey could be built 'threadsafe' so that was OK. I thought that threadsafe builds were the default in newer releases though.

Only being able to have a single Context per thread seems to be a backward step to me and it's going to be a massive problem for our embedding.
What was the rationale behind requiring it and do I have any alternatives other than making each Context a separate thread?

Many thanks

Miles
0
Miles
6/26/2020 7:38:03 AM
mozilla.dev.tech.js-engine 2051 articles. 0 followers. Post Follow

4 Replies
20 Views

Similar Articles

[PageSpeed] 26

On Friday, 26 June 2020 08:38:04 UTC+1, Miles  wrote:
> Hi,
>=20
> A quick question if I may...
> Am I correct in thinking that only one JSContext is allowed per thread in=
 JS 76 (even if it is the main thread)?
> I'm assuming that this must be the case as in js::NewContext pretty much =
the first thing it checks is
> =20
>  MOZ_RELEASE_ASSERT(!TlsContext.get());
>=20
> and this asserts on a debug build if I try to create a second context.
>=20
> In the older releases you used to be able to have a single JSRuntime but =
multiple JSContexts on a single thread and we made use of that. Each 'scrip=
t' had its own Context but they were all running concurrently on a single t=
hread.
> My (no doubt incorrect) understanding was that back then Spidermonkey cou=
ld be built 'threadsafe' so that was OK. I thought that threadsafe builds w=
ere the default in newer releases though.
>=20
> Only being able to have a single Context per thread seems to be a backwar=
d step to me and it's going to be a massive problem for our embedding.
> What was the rationale behind requiring it and do I have any alternatives=
 other than making each Context a separate thread?
>=20
> Many thanks
>=20
> Miles

As a follow up/supplemental question, if you can only have one JSContext on=
 a thread, can a context have multiple global objects? From my understandin=
g all the standard classes etc are made using a global object.
Does that mean that if I have two scripts that I want to keep completely se=
parate I can create two different global objects in one context, initialise=
 the standard classes for each global object and then compile and execute t=
he scripts separately in the different globals?
Are the variables, classes etc completely separate and independent?
If so, I think that will allow me to do what I need.

Many thanks

Miles
0
Miles
6/26/2020 12:17:07 PM
On Fri, Jun 26, 2020 at 9:40 AM Miles <miles.thornton@arup.com> wrote:

> Am I correct in thinking that only one JSContext is allowed per thread in
> JS 76 (even if it is the main thread)?
>

Correct.


> Only being able to have a single Context per thread seems to be a backward
> step to me and it's going to be a massive problem for our embedding.
> What was the rationale behind requiring it and do I have any alternatives
> other than making each Context a separate thread?
>

We used to depend on having multiple contexts per runtime in Gecko, but it
was really hard to reason about them because it wasn't very clear what a
JSContext represented exactly. So this was simplified to just having one
context per runtime / thread. Can you say more about why your embedding
need multiple contexts? What doesn't work if you create one context?

Thanks,
Jan
0
Jan
6/26/2020 12:20:21 PM
On Fri, Jun 26, 2020 at 2:20 PM Miles <miles.thornton@arup.com> wrote:

> As a follow up/supplemental question, if you can only have one JSContext
> on a thread, can a context have multiple global objects? From my
> understanding all the standard classes etc are made using a global object.
> Does that mean that if I have two scripts that I want to keep completely
> separate I can create two different global objects in one context,
> initialise the standard classes for each global object and then compile and
> execute the scripts separately in the different globals?
> Are the variables, classes etc completely separate and independent?
>

Yes you can create multiple global objects with JS_NewGlobalObject, switch
between them with JSAutoRealm, and compile/execute code in each
realm/global separately.

Hope this helps.
Jan
0
Jan
6/26/2020 12:34:23 PM
On 6/26/20 5:20 AM, Jan de Mooij wrote:
> On Fri, Jun 26, 2020 at 9:40 AM Miles <miles.thornton@arup.com> wrote:
>
>> Only being able to have a single Context per thread seems to be a backward
>> step to me and it's going to be a massive problem for our embedding.
>> What was the rationale behind requiring it and do I have any alternatives
>> other than making each Context a separate thread?
>>
> We used to depend on having multiple contexts per runtime in Gecko, but it
> was really hard to reason about them because it wasn't very clear what a
> JSContext represented exactly. So this was simplified to just having one
> context per runtime / thread. Can you say more about why your embedding
> need multiple contexts? What doesn't work if you create one context?

You can still do a runtime per thread. They will be completely isolated 
from each other. (Well, there's some limited sharing you can do by 
having one toplevel runtime that all the other runtimes parent to, but 
that's for very limited read-only constant data IIUC.)

If you need them to communicate with each other, you'd have to create a 
messaging system to send JSON data (for very simply structured data) or 
structured clone buffers between them. Or I suppose these days you could 
also use SharedArrayBuffers and Atomics, but that'd only be for plain 
bits, not objects or strings or any other GC things.


0
Steve
6/26/2020 3:17:35 PM
Reply: