Closed
Bug 470409
Opened 17 years ago
Closed 17 years ago
TM: Crash [@ js_EqualStrings]
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
VERIFIED
FIXED
People
(Reporter: gkw, Assigned: Waldo)
References
Details
(4 keywords, Whiteboard: fixed-in-tracemonkey)
Crash Data
Attachments
(1 file, 1 obsolete file)
|
2.52 KB,
patch
|
brendan
:
review+
|
Details | Diff | Splinter Review |
for (var z = 0; z < 3; ++z) { {switch( '' ) { default: ; case 9: break; case "" : case <x/>: break; } } }
crashes opt at null at js_EqualStrings and asserts dbg at Assertion failure: str1, at ../jsstr.cpp
Flags: blocking1.9.1?
| Assignee | ||
Updated•17 years ago
|
Assignee: general → jwalden+bmo
Status: NEW → ASSIGNED
| Assignee | ||
Comment 1•17 years ago
|
||
(gdb) disas $pc-50 $pc
Dump of assembler code from 0x8e2f8a to 0x8e2fbc:
0x008e2f8a: add %al,(%eax)
0x008e2f8c: add %al,(%eax)
0x008e2f8e: add %al,(%eax)
0x008e2f90: push %edi
0x008e2f91: push %esi
0x008e2f92: push %ebx
0x008e2f93: push %ebp
0x008e2f94: mov %esp,%ebp
0x008e2f96: sub $0xc,%esp
0x008e2f99: mov %ecx,%ebx
0x008e2f9b: mov (%ebx),%edi
0x008e2f9d: mov 8(%ebx),%esi
0x008e2fa0: movl $0x0,(%edi)
0x008e2fa6: movl $0x86a000,8(%edi)
0x008e2fad: mov $0x86a000,%edx
0x008e2fb2: mov $0x0,%ecx
0x008e2fb7: call 0x11366a <js_EqualStrings>
Looks like somehow we think this is supposed to be called with three (!) arguments, not two, and somehow there's a constant 0 as the first argument to make the obvious crash. Still investigating...
| Assignee | ||
Comment 2•17 years ago
|
||
Attachment #353941 -
Flags: review?(brendan)
Comment 3•17 years ago
|
||
Comment on attachment 353941 [details] [diff] [review]
Don't forget the guard in the type-mismatch case
>+ LIns* x;
>+ bool cond;
>
> uint8 ltag = getPromotedType(l);
> if (ltag != getPromotedType(r)) {
>- set(&l, lir->insImm(!equal));
>- return;
>- }
>-
>- LIns* x;
>- bool cond;
>- if (ltag == JSVAL_STRING) {
>+ x = lir->insImm(!equal);
>+ cond = !equal;
Nit: transpose these two statements, common !equal into cond.
>+ } else if (ltag == JSVAL_STRING) {
> LIns* args[] = { r_ins, l_ins };
> x = lir->ins2i(LIR_eq, lir->insCall(&js_EqualStrings_ci, args), equal);
> cond = js_EqualStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r));
Rest of code is:
} else {
LOpcode op = (ltag != JSVAL_DOUBLE) ? LIR_eq : LIR_feq;
x = lir->ins2(op, l_ins, r_ins);
if (!equal)
x = lir->ins_eq0(x);
cond = (l == r);
}
cond = (cond == equal);
if (cmpCase) {
/* Only guard if the same path may not always be taken. */
if (!x->isconst())
guard(cond, x, BRANCH_EXIT);
return;
}
set(&l, x);
But x = lir->insImm(!equal) makes x a constant, so the guard won't be emitted. What am I missing?
/be
| Assignee | ||
Comment 4•17 years ago
|
||
Hmm, point. I wonder if maybe the logic of determining operands for calls is off by one somehow in rare circumstances. Implausible, I know, but verbose is verifying that we're setting up a call with the first argument as 0. Will stare some at the assembly-generation step and see if I can figure out where the problem lies...
Comment 5•17 years ago
|
||
Thinking about this more, the code is better as patched in one regard, because it uses the common tail that covers cmpCase == true.
We must not set(&l, x) in a switch case, of course -- that must be the bug with the unpatched code, eh?
The patched code emits nothing that's actually used, and simply leaves control flow staying on trace, as is done elsewhere (ifop, record_JSOP_IFPRIMTOP), since differently typed operands are not strictly equal (!==) by definition.
While we don't need to emit a constant guard, I'm not sure it's worth optimizing here to avoid the x = lir->insImm(!equal). I would common !equal into cond and use that as the insImm arg, though.
/be
| Assignee | ||
Comment 6•17 years ago
|
||
(In reply to comment #5)
> We must not set(&l, x) in a switch case, of course -- that must be the bug with
> the unpatched code, eh?
Ah, yes, that makes sense -- we're just tracing linearly from switch through whatever case finally gets hit, so we just add guards for the previous conditions we might hit differently (plus any evaluation of expressions in the case clauses) and do nothing else.
> While we don't need to emit a constant guard, I'm not sure it's worth
> optimizing here to avoid the x = lir->insImm(!equal). I would common !equal
> into cond and use that as the insImm arg, though.
Makes sense. We're already doing the x = ... stuff in the non-type-mismatch cases anyway even when it's possible x might be constant then (e.g. boolean comparisons, or string-equality if we were clever enough to do that in insCall).
Attachment #353941 -
Attachment is obsolete: true
Attachment #354109 -
Flags: review?(brendan)
Attachment #353941 -
Flags: review?(brendan)
Updated•17 years ago
|
Attachment #354109 -
Flags: review?(brendan) → review+
Comment 7•17 years ago
|
||
Comment on attachment 354109 [details] [diff] [review]
Better patch
Looks good. Great to see a bit of the banner comment in the trace-test.js diff ;-).
/be
| Assignee | ||
Comment 8•17 years ago
|
||
Fixed in TM:
http://hg.mozilla.org/tracemonkey/rev/debe29698839
Whiteboard: fixed-in-tracemonkey
Comment 10•17 years ago
|
||
merged to mc
Status: ASSIGNED → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
| Reporter | ||
Updated•17 years ago
|
Flags: blocking1.9.1?
Comment 11•17 years ago
|
||
Keywords: fixed1.9.1
Comment 12•17 years ago
|
||
test included in js1_8_1/trace/trace-test.js
http://hg.mozilla.org/mozilla-central/rev/8f967a7729e2
Flags: in-testsuite+
Flags: in-litmus-
Comment 13•16 years ago
|
||
v 1.9.1, 1.9.2
Status: RESOLVED → VERIFIED
Keywords: fixed1.9.1 → verified1.9.1
Updated•14 years ago
|
Crash Signature: [@ js_EqualStrings]
You need to log in
before you can comment on or make changes to this bug.
Description
•