Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What to do about cx parameter in infallible public API?

17 views
Skip to first unread message

Igor Bukanov

unread,
Feb 2, 2012, 11:34:12 AM2/2/12
to dev-tech-js-en...@lists.mozilla.org
With the removal of multithreaded JS objects and runtime the JSContext
*cx argument that many infallible public API take is either no longer
necessary or can be replaced with JSRuntime *. The list of such API is
at least:

extern JS_PUBLIC_API(void *)
JS_GetPrivate(JSContext *cx, JSObject *obj);

extern JS_PUBLIC_API(JSBool)
JS_SetPrivate(JSContext *cx, JSObject *obj, void *data);

extern JS_PUBLIC_API(JSBool)
JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32_t index, jsval *vp);

extern JS_PUBLIC_API(JSBool)
JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32_t index, jsval v);

extern JS_PUBLIC_API(void)
JS_FlushCaches(JSContext *cx);

extern JS_PUBLIC_API(void)
JS_ClearScope(JSContext *cx, JSObject *obj);

extern JS_PUBLIC_API(JSOperationCallback)
JS_GetOperationCallback(JSContext *cx);

extern JS_PUBLIC_API(void)
JS_TriggerOperationCallback(JSContext *cx);

extern JS_PUBLIC_API(void)
JS_TriggerRuntimeOperationCallback(JSRuntime *rt);

extern JS_PUBLIC_API(JSBool)
JS_IsRunning(JSContext *cx);

and probably other.

This unnecessary cx complicates life for the callers when they just
want to query the JS object or engine. The callers are forced often to
either pass cx through layers of non js-code or even create a
temporary dummy cx like recent statistics gathering patches were
forced to do.

So what should be done about this? Is it OK to just drop the cx or
replace it with rt?

Wes Garland

unread,
Feb 2, 2012, 12:26:01 PM2/2/12
to Igor Bukanov, dev-tech-js-en...@lists.mozilla.org
IMO -- if cx is not necessary it should be dropped from API. This is a
relatively easy change for embedders. Similarly, when only rt is needed,
it should be used instead of passing cx. In the long, it makes things
easier for everybody, legacy-embedding-maintainers included.

A much bigger change for embedders will be managing only a single cx per
thread if we are storing cx data in TLS or something. If that IS the case,
I wonder if we should have an API which lets users cache/restore the TLS
for the active cx. This would let embedders refactor thus:

cx1 = JS_NewContext(rt);
cx2 = JS_NewContext(rt);
JS_BeginRequest(cx1);
doStuff(cx1);
JS_EndRequest(cx1);
JS_BeginRequest(cx2);
doStuff(cx2);
JS_EndRequest(cx2);
JS_BeginRequest(cx1);
doMoreStuff(cx1);
JS_EndRequest(cx1);

becomes

JS_ActivateNewContext(rt);
doStuff();
hnd = JS_ActivateNewContext(rt);
doStuff();
JS_ReactivateContext(hnd);
doMoreStuff();

???

Just throwing ideas out there.

Wes
> _______________________________________________
> dev-tech-js-engine-internals mailing list
> dev-tech-js-en...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals
>



--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Dave Mandelin

unread,
Feb 3, 2012, 4:24:15 PM2/3/12
to
On Feb 2, 9:26 am, Wes Garland <w...@page.ca> wrote:
> IMO -- if cx is not necessary it should be dropped from API.  This is a
> relatively easy change for embedders.  Similarly, when only rt is needed,
> it should be used instead of passing cx.   In the long, it makes things
> easier for everybody, legacy-embedding-maintainers included.

I was going to say it would be nice to try to think ahead and avoid
future API churn (e.g., say there is a method where it doesn't need
any parameter now, but might someday need an rt if it were to use
caching), but it sounds like you are saying that kind of churn is not
too bad. In that case, I totally agree with the idea of just using the
minimal parameters (i.e., nothing ideally, otherwise rt).

> A much bigger change for embedders will be managing only a single cx per
> thread if we are storing cx data in TLS or something. If that IS the case,
> I wonder if we should have an API which lets users cache/restore the TLS
> for the active cx.

I wish I knew more about how multiple contexts are being used. Are you
talking about using cx1 and cx2 from threads T1 and T2, or something
else?

Dave

> This would let embedders refactor thus:
>
> cx1 = JS_NewContext(rt);
> cx2 = JS_NewContext(rt);
> JS_BeginRequest(cx1);
> doStuff(cx1);
> JS_EndRequest(cx1);
> JS_BeginRequest(cx2);
> doStuff(cx2);
> JS_EndRequest(cx2);
> JS_BeginRequest(cx1);
> doMoreStuff(cx1);
> JS_EndRequest(cx1);
>
> becomes
>
> JS_ActivateNewContext(rt);
> doStuff();
> hnd = JS_ActivateNewContext(rt);
> doStuff();
> JS_ReactivateContext(hnd);
> doMoreStuff();
>
> ???
>
> Just throwing ideas out there.
>
> Wes
>
> > dev-tech-js-engine-intern...@lists.mozilla.org

Igor Bukanov

unread,
Feb 3, 2012, 5:52:18 PM2/3/12
to Wes Garland, dev-tech-js-en...@lists.mozilla.org
On 2 February 2012 18:26, Wes Garland <w...@page.ca> wrote:
> A much bigger change for embedders will be managing only a single cx per
> thread if we are storing cx data in TLS or something.

TLS is not exactly free and explicit cx parameter could in fact be
faster. But the issue for this thread is orthogonal to that - it is
really about API that can not fail and that do not need the cx
argument after removal of multi-threaded runtime support.

> JS_BeginRequest(cx1);

Note that the JS_BeginRequest and friends will be removed in not so
distant future. The engine no longer needs them, but the browser still
depends on the internal counters, see
https://bugzilla.mozilla.org/show_bug.cgi?id=722345

Igor Bukanov

unread,
Feb 7, 2012, 6:40:40 AM2/7/12
to Dave Mandelin, dev-tech-js-en...@lists.mozilla.org
On 3 February 2012 22:24, Dave Mandelin <dman...@mozilla.com> wrote:
> I was going to say it would be nice to try to think ahead and avoid
> future API churn (e.g., say there is a method where it doesn't need
> any parameter now, but might someday need an rt if it were to use
> caching),

AFAICS in all cases with those API the engine can access the JSRuntime
instance using thing->compartment()->rt or similar.

Wes Garland

unread,
Feb 7, 2012, 9:59:59 AM2/7/12
to Dave Mandelin, dev-tech-js-en...@lists.mozilla.org
On 3 February 2012 16:24, Dave Mandelin <dman...@mozilla.com> wrote:

> I wish I knew more about how multiple contexts are being used. Are you
> talking about using cx1 and cx2 from threads T1 and T2, or something
> else?
>

There are several patterns in use in embeddings which aren't in use in the
browser. I'm trying to think of a few examples, if I'm slightly
incoherent it's because I am currently nearly decaffeinated. :)

One pattern is where multiple contexts are on the go, with only one running
at any time, supporting separate applications, with separate global
variables. Think of, say, a web server running multiple applications.
They need to be in the same runtime because they can share objects, but
they need to be in different contexts because ... I dunno...maybe they need
different standard classes for security sandboxing?

Mike Moening uses a pattern something like that, ISTR he keeps
pre-initialized cx's around so that his server can handle connections
quickly. Maybe Mike can chime in here, is there a way to link him to this
thread if he is not on the list?

Another is where you have a debugger written in JS debugging JS programs.
You don't want the debugger and the debuggee running in the same context.

In GPSEE, we have to keep an extra context around on the main thread for
some reason, too. I forget the exact details at the moment. I think it's
because we need to JS_free() memory after all our JS code has been garbage
collected, and the only way to insure that the garbage gets collected is to
destroy the context.

Wes
0 new messages