Closed
Bug 478968
Opened 15 years ago
Closed 15 years ago
TM: equalityHelper can call toString or valueOf erroneously when tracing obj == undefined
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
VERIFIED
FIXED
People
(Reporter: jorendorff, Assigned: Waldo)
References
Details
(Keywords: verified1.9.1, Whiteboard: fixed-in-tracemonkey)
Attachments
(1 file, 1 obsolete file)
6.51 KB,
patch
|
brendan
:
review+
|
Details | Diff | Splinter Review |
obj = {toString: function() { throw 0; }}; for (i = 0; i < 5; i++) print(""+ (obj == undefined)); With the JIT, this throws. Without, obj.toString is never called. The latter is correct. Treehydra very cleverly detected this by defining a toString method that always throws. :-P
Assignee | ||
Updated•15 years ago
|
Assignee: general → jwalden+bmo
Status: NEW → ASSIGNED
Assignee | ||
Comment 1•15 years ago
|
||
Comments on wording of the side-exit documentation appreciated; I'm still not completely clear on their exact uses, and the wording probably could use some help in any case. Will file a followup bug to deal with the high side-exit count, but would rather get this fixed now and deal with revealed inefficiencies later -- wrong is worse than slow. I'm starting to wonder whether bug 471214 or something similar is biting all sorts of loopy code (particularly loopy code that has a style similar to the style of code I write), because I'm seeing quite a few loops lately that are exiting every go-around. Wouldn't surprise me, although given that I seem to see side exits on different ops each time they may be quite different.
Attachment #362841 -
Flags: review?(brendan)
Comment 2•15 years ago
|
||
Comment on attachment 362841 [details] [diff] [review] Patch and tests What are the jitstats with and without the patch? /be
Assignee | ||
Comment 3•15 years ago
|
||
Hm, actually I think the original comment had it right. If we have obj == undefined, we converted undefined=>NaN and Number(obj), but nothing == NaN, so it's only possible to detect error by side effects or abrupt termination. In this patch we detect that by incrementing a count as a side effect (and checking returns just to be sure), and here we fail pre-patch and pass after. The previous patch had a rather egregious typo of NaN for undefined, so its second test wasn't testing that the patch worked. The jitstats after are in the patch. Pre-patch, the side-exit count for testThrowingObjectEqUndefined is 0 as we hit the throw before we can execute a trace. The side-exit count for testConvertibleObjectEqUndefined is 1 before because we always convert the pseudo-boolean and always call valueOf on the object and always follow the same execution path, only executing when the loop ends. After, it's 2 because we have to side-exit to fill in the |undefined| case once, then it's smooth sailing until the loop ends.
Attachment #362841 -
Attachment is obsolete: true
Attachment #362995 -
Flags: review?(brendan)
Attachment #362841 -
Flags: review?(brendan)
Reporter | ||
Updated•15 years ago
|
Flags: blocking1.9.1?
Comment 4•15 years ago
|
||
Comment on attachment 362995 [details] [diff] [review] v2, with better tests >+ bool isBool = !JSVAL_IS_VOID(l); >+ guard(!isBool, >+ lir->ins2(LIR_eq, l_ins, INS_CONST(JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID))), >+ BRANCH_EXIT); >+ if (isBool) { Nit: would isVoid be clearer? Then you would avoid two negations via ! *and* the guard first arg and LIR-combo in second arg would use like terms (isVoid, LIR_eq(l_ins, ...VOID)). > enum ExitType { >+ /* >+ * An exit from a trace because a condition relied upon at recording time >+ * no longer holds; however, if that condition had been known to be >+ * otherwise at record time, further tracing of an alternate path of >+ * execution could have happened. >+ */ > BRANCH_EXIT, This doesn't motivate the b-word. How about "An exit at a possible branch-point in the trace at which to attach a future secondary trace. Therefore the recorder must generate different code to handle the other outcome of the branch condition from the primary trace's outcome." >@@ -4350,6 +4350,59 @@ function testRegexpGet() { > testRegexpGet.expected = "hi,hi,hi,hi,hi"; > test(testRegexpGet); > >+function testThrowingObjectEqUndefined() >+{ >+ try >+ { Is this trace-test.js style, or is it an eclectic place (or a sacked Rome)? I mean two-space basic offset and brace on its own line? r=me with nits. /be
Attachment #362995 -
Flags: review?(brendan) → review+
Comment 5•15 years ago
|
||
With baking I can make wanted case easily. Not sure about blocking but we are not at the 11th hour. /be
Flags: wanted1.9.1?
Assignee | ||
Comment 6•15 years ago
|
||
(In reply to comment #4) > Nit: would isVoid be clearer? Yeah, I think so, changed. > How about "An exit at a possible branch-point in the trace at which to > attach a future secondary trace. Therefore the recorder must generate > different code to handle the other outcome of the branch condition from > the primary trace's outcome." Works for me, changed. > Is this trace-test.js style, or is it an eclectic place (or a sacked Rome)? I > mean two-space basic offset and brace on its own line? It's the style I like most, common to nearly all JS tests I've ever written, trace-test or otherwise, and nobody's ever complained about tests having different style. Also, if anything, it's more an unmolested Parthenon than a destroyed Rome. :-P
Summary: TM: equalityHelper can call toString or valueOf erroneously → TM: equalityHelper can call toString or valueOf erroneously when tracing obj == undefined
Whiteboard: fixed-in-tracemonkey
Assignee | ||
Comment 7•15 years ago
|
||
http://hg.mozilla.org/tracemonkey/rev/a70e1f50ce17
Comment 8•15 years ago
|
||
I spotted some 4-space js-basic-offset invasion of your Parthenon. trace-test.js is really a mix, altogether. /be
Updated•15 years ago
|
Flags: wanted1.9.1?
Flags: wanted1.9.1+
Flags: blocking1.9.1?
Flags: blocking1.9.1-
The original author of trace-test.js (me) believes in 4-space, but my Emacs is a bit of an apostate at times.
Comment 10•15 years ago
|
||
http://hg.mozilla.org/mozilla-central/rev/a70e1f50ce17
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Comment 11•15 years ago
|
||
http://hg.mozilla.org/releases/mozilla-1.9.1/rev/74e0721ef1c4
Keywords: fixed1.9.1
Comment 12•15 years ago
|
||
http://hg.mozilla.org/tracemonkey/rev/1c16405d7d6c /cvsroot/mozilla/js/tests/js1_8_1/trace/trace-test.js,v <-- trace-test.js new revision: 1.12; previous revision: 1.11
Flags: in-testsuite+
Comment 13•15 years ago
|
||
verified 1.9.1, 1.9.2 based on testThrowingObjectEqUndefined and testConvertibleObjectEqUndefined
Status: RESOLVED → VERIFIED
Keywords: fixed1.9.1 → verified1.9.1
You need to log in
before you can comment on or make changes to this bug.
Description
•