Closed
Bug 503694
Opened 15 years ago
Closed 15 years ago
TM: Code run off an event handler is never traced
Categories
(Core :: JavaScript Engine, defect, P1)
Tracking
()
RESOLVED
FIXED
Tracking | Status | |
---|---|---|
status1.9.2 | --- | beta1-fixed |
People
(Reporter: Dpeelen, Assigned: graydon)
References
()
Details
(Whiteboard: fixed-in-tracemonkey)
Attachments
(4 files)
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2a1pre) Gecko/20090701 Minefield/3.6a1pre
Starting with Gecko/20090701 Minefield/3.6a1pre, enabling or disabling javascript.options.jit.content no longer result in a performance difference on Greg Reimer's loop benchmark test (see url).
Previous enabling JIT resulted in a significant speed up.
To be clear:
Works in: Gecko/20090630 Minefield/3.6a1pre
Broke in: Gecko/20090701 Minefield/3.6a1pre
Reproducible: Always
Comment 1•15 years ago
|
||
I get slow script warnings in the current trunk. Using 20090629 I get no such warnings. In my current trunk build I get forEach ~206000ms.
Reporter | ||
Comment 2•15 years ago
|
||
The slow script warning has is probably to blame for that 206000ms. Increase the value in dom.max_script_run_time to prevent that.
However, that you get the no script warning in the first place does indicate current trunk is slower, it's about twice as slow as it used to be by my calculations. (well, its as slow as it previous was with jit disabled).
Comment 3•15 years ago
|
||
Need to confirm and find the regressing changeset.
/be
Keywords: regressionwindow-wanted
Updated•15 years ago
|
Flags: blocking1.9.2+
Comment 4•15 years ago
|
||
Did three runs of the test for 2009-06-30 and 2009-07-01 averaged the results and calculated a simple percentage change, positive is slower, negative is faster.
Many of the tests are multiples of 100% slower.
Changesets involved http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=b1b2f9a366ca&tochange=d54a92a63aa7
All of the above was tested in a new profile. Something is wrong with one of my profiles. Even in safe mode I get dreadful performance on one of the tests hence my comment 1.
Comment 5•15 years ago
|
||
Filed Bug 504271 for my issue in comment 1. javascript.options.strict is the cause
Updated•15 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 6•15 years ago
|
||
Safe mode disables the JIT. Can you export that Excel file as CSV or text or even a screenshot? Many of us (including myself on this computer) don't have a way to view Excel files usefully.
Comment 8•15 years ago
|
||
Great, thanks. Would be excellent if you could use ftp://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2009-06-30-03-tracemonkey/ and friends to narrow down the regression range on tracemonkey, which will point to a much smaller set of changes. Up for it?
Comment 9•15 years ago
|
||
There were three worksheets, merged to one csv.
Reporter | ||
Comment 10•15 years ago
|
||
I try to friend a narrow regression range, unless one of you is doing so already, give a yell please :)
Reporter | ||
Comment 11•15 years ago
|
||
I got it down to:
2009-06-26-03-tracemonkey works
2009-06-27-03-tracemonkey slow
Comment 12•15 years ago
|
||
Dorus, thanks for hunting that regression range down. This looks like a regression from bug 500580. The test in this bug runs its code like so:
<a href="#" onclick="this.style.display='none';test();return false;">test</a>
That means that when we invoke the handler the scope chain starts at the <a> node, not the global object. And the fix for bug 500580 then disables the jit for the duration of the handler execution.
Here's a simple testcase that can be used to test this:
data:text/html,<script>function f() { var s = new Date; for (var i = 0; i < 1e7; ++i); alert(new Date-s);} f()</script><button onclick="f()">click</button>
Load that URI, get the first alert, click the button, get the second alert, compare the two numbers. In 1.9.1, they're about equal. On m-c and t-m they're off by an order of magnitude, as expected for jit off....
Blocks: 500580
Keywords: regressionwindow-wanted
Summary: TM: JIT no longer speed up any javascript loop → TM: Code run off an event handler is never traced
Comment 13•15 years ago
|
||
Argh, the fix for bug 500580, and the fix for bug 497060 before it, is too pessimistic. Static scope rules in JS mean that even though onclick="f()" creates a function with a deep scope chain, the call to f is not deep.
Note also that if there were some way to make the <script> in which f is defined have a deep scope chain, but f called function g defined in a script with a shallow (global object only) scope chain, then the fix for bug 497060 would bite in the same fashion.
We really want JIT disabling to be statically scoped, not dynamically scoped as in the fixes for those bugs. Graydon, if you take this I will do a better job advising.
/be
Assignee | ||
Comment 14•15 years ago
|
||
Sure. I figured this was on my plate sooner or later. I think I already might have one about it open still. Plus, the existing one is still making bc's test rig cry. It was a hack to get it to "safe", need to fix right.
Assignee: general → graydon
Comment 15•15 years ago
|
||
This seems like a P1 for the mozilla-1.9.2 branch; out of curiousity, are we not tracking a sunspider score on our nightly trunk builds that should have alerted us to this sooner?
Comment 16•15 years ago
|
||
Sunspider doesn't run off events, this is another test that isn't in our suite (and is a little rough around the edges to incorporate, I think).
Comment 17•15 years ago
|
||
Dromaeo does, though, right?
Comment 18•15 years ago
|
||
No, I believe Dromaeo uses setTimeout.
Comment 19•15 years ago
|
||
> (and is a little rough around the edges to incorporate, I think).
I we had a performance suite we could just drop tests into, writing a test for this would be super-easy....
Comment 20•15 years ago
|
||
(In reply to comment #19)
> > (and is a little rough around the edges to incorporate, I think).
>
> I we had a performance suite we could just drop tests into, writing a test for
> this would be super-easy....
http://hg.mozilla.org/users/rsayre_mozilla.com/benchmarker/
Assignee | ||
Comment 21•15 years ago
|
||
I talked to brendan a bit today and worked out, I think, an approach that should cost no more than the current code but free us from the blunt instrument of disabling the JIT altogether when activated on an event handler.
Haven't done performance comparisons yet though. Just posting here for initial feedback. It certainly *works*, and I've checked that it bails on loop headers that are embedded in event handlers; I'll toss it at the try server tonight as well to see how it fares.
One question though: should we blacklist if we keep trying to enter (and bailing) this way? It seems like it'd be rare for there to be a loop header literally *in* an event handler body (rather than reachable-through it) but that case will repeatedly try-to-enter and fail here. Very cheaply, but still.
Attachment #392832 -
Flags: review?
Updated•15 years ago
|
Attachment #392832 -
Flags: review? → review+
Comment 22•15 years ago
|
||
Comment on attachment 392832 [details] [diff] [review]
Rough cut at fixing this the "more correct" way.
>+
>+/*
>+ * We cache name lookup results only for the global object or for native
>+ * non-global objects without prototype or with prototype that never mutates,
>+ * see bug 462734 and bug 487039.
>+ */
>+
Nit: no blank line here, move it down...
>+extern JS_FRIEND_DATA(JSClass) js_CallClass;
>+extern JS_FRIEND_DATA(JSClass) js_DeclEnvClass;
... to here. Or could you move the externs into the static inline for narrowest scope?
>+ /*
>+ * The JIT records and exepects to execute with two scope-chain
tpyo
>+ * assumptions baked-in:
>+ *
>+ * 1. That the bottom of the scope chain is global, in the sense of
>+ * JSCLASS_IS_GLOBAL.
>+ *
>+ * 2. That the scope chain between fp and the global is free of
>+ * "unusual" native objects such as HTML forms or other funny
>+ * things.
>+ *
>+ * #2 is checked here while following the scope-chain links, via
>+ * js_IsCacheableNonGlobalScope, which consults a whitelist of known
>+ * class types; once a global is found, it's checked for #1. Failing
>+ * either check causes an early return from execution.
>+ */
>+
Nit: no blank line needed here.
>+ JSObject* globalObj;
>+ JSObject *child = cx->fp->scopeChain;
Nit: T* p vs T *p conflict -- jstracer.cpp style favors T* p.
>+ while ((globalObj = OBJ_GET_PARENT(cx, child)) != NULL) {
>+ if (!js_IsCacheableNonGlobalScope(child))
>+ return NULL;
>+ child = globalObj;
>+ }
>+ globalObj = child;
Might be cleaner and use fewer lines to s/globalObj/parent/g and then s/child/globalObj/g, although this has the odd-looking effect of calling non-globals along the scope chain "globalObj" temporarily.
To avoid that, how about using JSObject* parent instead of globalObj until the last line cited above, at which point introduce JSObject* globalObj = child; ? Cleanest looking and the compiler can figure out minimal register allocation :-).
>+ if (!(OBJ_GET_CLASS(cx, globalObj)->flags & JSCLASS_IS_GLOBAL))
>+ return NULL;
Otherwise looks great! r=me with nits picked.
/be
Assignee | ||
Comment 23•15 years ago
|
||
http://hg.mozilla.org/tracemonkey/rev/f5fd44e7cfdb
(With blacklisting, as suggested on IRC. Appears to satisfy the try servers and improves the URL case listed in this bug. Not sure if it entirely fixes the world, but i
Whiteboard: fixed-in-tracemonkey
Assignee | ||
Comment 24•15 years ago
|
||
Oh, weird. Cut off. "but it doesn't seem to make anything I can find any worse."
Comment 25•15 years ago
|
||
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Updated•15 years ago
|
Priority: -- → P1
Comment 26•15 years ago
|
||
status1.9.2:
--- → beta1-fixed
You need to log in
before you can comment on or make changes to this bug.
Description
•