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

Lock contention and performance problems

6 views
Skip to first unread message

gurkhali

unread,
Nov 17, 2009, 7:57:45 PM11/17/09
to
I am also running into lock contention performance problems mentioned
in this thread <http://groups.google.com/group/mozilla.dev.tech.js-
engine/browse_thread/thread/d70153f89d8d0736/f259b8abdd767642?
lnk=gst&q=mutex#f259b8abdd767642>. Instantiating interpretor per
thread seems to work great and I am running with JS_THREADSAFE option.
The only catch now seem to be that each of the runtime is creating a
back ground thread.

I have some pretty strict requirements on the ability to create
threads per-core and was wondering if there was any way to prevent the
back ground thread (if at all). Or to put it another way, if this is
the GC running in the thread, I is there any way to make the GCdo the
clean up inline (execution thread) similar to TCL (which actually has
a reference count based GC; if you want to call it that).

I noticed a comment on that thread saying that building without
JS_THREADSAFE appeared to eliminate the worker thread but it appears
lack of the JS_THREADSAFE option comes with its own set of warning
<https://bugzilla.mozilla.org/show_bug.cgi?id=509857>. Looks like that
bug is still open and I wonder if there are other possible known bugs
going down that path.

So Is there any official word on whether we can run without
JS_THREADSAFE in this situation. If not then what is the best way to
control the background thread behavior?

tia,
Bhushan

Jason Orendorff

unread,
Nov 18, 2009, 3:18:11 PM11/18/09
to
On 11/17/2009 06:57 PM, gurkhali wrote:
> [...] Instantiating interpretor per

> thread seems to work great and I am running with JS_THREADSAFE option.
> The only catch now seem to be that each of the runtime is creating a
> back ground thread.

Ah - yes, we ship all calls to free() off to a background thread, for
performance. We don't really need a background thread per runtime, so I
filed a bug:

Bug 529526 - SpiderMonkey launches one JSBackgroundThread per JSRuntime
https://bugzilla.mozilla.org/show_bug.cgi?id=529526

You could change this to a single global JSBackgroundThread. You can use
PR_CallOnce to make sure the thread is only launched once. If you're
willing to write the patch, I think we'll take it.

-j

gurkhali

unread,
Nov 18, 2009, 5:50:34 PM11/18/09
to
Sure I can take a stab at the patch.

Ok then that leads me to the other question then. Why does the helper
thread not get created when JS_THREADSAFE is not enabled? On the post
I referred to earlier Brenden mentioned that barring some possible
issues, creating multiple non-sharing runtime on different threads are
supported without the JS_THREADSAFE option. But some of the earlier
posts (shown below) explicitly prohibit that. I suspect that things
have changed since 2006 but I wanted to make sure that was the case.

Can you please comment on where we stand currently. I would be more
than happy to find fix bugs found along the way but I don't want to
spend time in the weeds if its not some thing that the engine is
designed for.

http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/3c3980fde4e2fd50/ff6280eab3e5f70b?lnk=gst&q=JS_THREADSAFE#ff6280eab3e5f70b

http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/95f9bc2f67a3d608/27c207eb5f1ae6ae?lnk=gst&q=JS_THREADSAFE#27c207eb5f1ae6ae

Bhushan

On Nov 18, 12:18 pm, Jason Orendorff <jorendo...@mozilla.com> wrote:
> On 11/17/2009 06:57 PM, gurkhali wrote:
>
> > [...]  Instantiating interpretor per
> > thread seems to work great and I am running with JS_THREADSAFE option.
> > The only catch now seem to be that each of the runtime is creating a
> > back ground thread.
>
> Ah - yes, we ship all calls to free() off to a background thread, for
> performance. We don't really need a background thread per runtime, so I
> filed a bug:
>

> Bug 529526 - SpiderMonkey launches one JSBackgroundThread per JSRuntimehttps://bugzilla.mozilla.org/show_bug.cgi?id=529526

Jason Orendorff

unread,
Nov 23, 2009, 10:37:58 AM11/23/09
to
On 11/18/2009 04:50 PM, gurkhali wrote:
> Sure I can take a stab at the patch.
>
> Ok then that leads me to the other question then. Why does the helper
> thread not get created when JS_THREADSAFE is not enabled?

Without JS_THREADSAFE we avoid anything that would require linking NSPR,
that's all.

> On the post
> I referred to earlier Brenden mentioned that barring some possible
> issues, creating multiple non-sharing runtime on different threads are
> supported without the JS_THREADSAFE option. But some of the earlier
> posts (shown below) explicitly prohibit that. I suspect that things
> have changed since 2006 but I wanted to make sure that was the case.
>
> Can you please comment on where we stand currently. I would be more
> than happy to find fix bugs found along the way but I don't want to
> spend time in the weeds if its not some thing that the engine is
> designed for.

The engine is designed to avoid sharing state between runtimes. There is
one known spot in dtoa where we don't do this, and that's bug 509857
which you linked earlier.

There might be one or two more hiding in the engine. I would be a little
surprised. Like Brendan, I would be more than happy to land patches
fixing this unnecessary limitation.

-j

Puneet Sharma

unread,
Dec 17, 2009, 9:14:06 AM12/17/09
to dev-tech-...@lists.mozilla.org, Rajesh N
Hi,

Whenever I evaluate a script, over an object say O, having variable
assignment cum declaration without being declared by keyword 'var', then
that variable is accessible even after JS_ClearScope is done on object O
i.e. on clearing all properties of O.
For eg. A = 10; here, A is not declared as property of object O.

But, in case of var A = 10; A is not visible once JS_ClearScope is done. It
is working fine.

Somewhere I got to know that declaration without keyword 'var' are created
as property of global root object. Now, problem is that I can not do
JS_ClearScope over root object, which will clear all JS functions,
InitStandard classes.

Now, solution for this can be:
1. Don't allow assignment without 'var' keyword, i.e. throw an exception
2. Or clear root object such that all functions and initStandard classes are
retained.
3. Change JS behavior such that variables are declared on some other object
instead of global root object.

Please suggest if I can implement any of above solutions and if yes then
how? Thanks.


Regards
Puneet


Jason Orendorff

unread,
Dec 17, 2009, 2:53:06 PM12/17/09
to
On 12/17/2009 08:14 AM, Puneet Sharma wrote:
> Hi,
>
> Whenever I evaluate a script, over an object say O, having variable
> assignment cum declaration without being declared by keyword 'var', then
> that variable is accessible even after JS_ClearScope is done on object O
> i.e. on clearing all properties of O.
> For eg. A = 10; here, A is not declared as property of object O.
>
> But, in case of var A = 10; A is not visible once JS_ClearScope is done. It
> is working fine.

This happens for exactly the same reason that when you do

with (Math) {
A = sin(PI/6);
}

or

function f() {
A = 10;
}
f();

the new variable A is a property the global object, not a property of
Math or a local variable in f. That's just how the scoping rules of the
language are.

I think embedders often use `with` or the moral equivalent
(JS_EvaluateScript on non-global objects) in an attempt to make their
scripting environment a little sweeter. It's a mistake. Let me give you
a concrete example of why this is bad.

Browsers actually do this for event handlers. If you write

<script>function validateName(name) {...}</script>
...
<input id="name" onchange="validateName(value)">

then `value` finds the .value property of the input-element object. This
is bad because every time a new version of the browser comes out, and
there's a shiny new property or method on input-element objects, there
is a chance your code will break. The `value` will still work fine. But
if browsers were to add an `validateName` method to input objects, your
web page would start calling that instead of the global function you
defined!

For this reason, among others, Web developers are now told not to use
event handler attributes at all, but rather to register event listeners
once the document finishes loading, which looks like this:

<script>
$(function() {
$("#name").change(function () {
validateName(this.value);
});
}); // it's actually quite a bit worse if you don't have jquery!
</script>
...
<input id="name">

Note what has happened. The onchange= scoping behavior was intended as a
convenience for users. Instead of "validateName(this.value)", they could
just write "validateName(value)". But it didn't work out that way. Code
that looked fine turned out to be fragile. To avoid the fragility, users
have to write a lot more code than if the browsers had just avoided this
"convenience" hack to begin with.

Even worse, when browsers consider adding new methods to elements, they
have to give them names that are unlikely to collide with any real-world
Web content--that is, verbose clunky names. This one little hack has
managed to make *all future Web APIs* a bit worse.


If you still aren't convinced, you do have a few options:

> Now, solution for this can be:
> 1. Don't allow assignment without 'var' keyword, i.e. throw an exception

You can do this by turning on JSOPTION_STRICT and JSOPTION_WERROR. But
note that this will cause *other* dubious JS code to throw exceptions
too. In particular, m.x will throw if the property doesn't exist.

> 2. Or clear root object such that all functions and initStandard
> classes are retained.

If your global object has a resolve hook that creates these functions
and standard classes lazily, on demand, then you can JS_ClearScope
without too many ill effects. The main issue is that you will get a new
Array constructor after each time you clear, and `x instanceof Array`
will say `false` if `x` is an instance of an earlier constructor and not
the current Array.

> 3. Change JS behavior such that variables are declared on some other
> object instead of global root object.

Right. A common technique is just to have separate global objects. For
example, in your browser every Web page gets its own global object; this
way pages can't interfere with or snoop on each other.

-j

0 new messages