mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 12:45:27 +00:00
Fixed regression with recursion and type unstable frame slurping (bug 551705, r=gal).
This commit is contained in:
parent
64a20b3120
commit
dc2f935dc2
@ -492,43 +492,41 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
||||
* grabbed safely.
|
||||
*/
|
||||
LIns* rval_ins;
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN) {
|
||||
TraceType returnType = exit->stackTypeMap()[downPostSlots];
|
||||
if (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT) {
|
||||
rval_ins = get(&stackval(-1));
|
||||
if (returnType == TT_INT32) {
|
||||
JS_ASSERT(determineSlotType(&stackval(-1)) == TT_INT32);
|
||||
JS_ASSERT(isPromoteInt(rval_ins));
|
||||
rval_ins = demote(lir, rval_ins);
|
||||
}
|
||||
/*
|
||||
* The return value must be written out early, before slurping can fail,
|
||||
* otherwise it will not be available when there's a type mismatch.
|
||||
*/
|
||||
lir->insStorei(rval_ins, lirbuf->sp, exit->sp_adj - sizeof(double));
|
||||
} else {
|
||||
switch (returnType)
|
||||
{
|
||||
case TT_PSEUDOBOOLEAN:
|
||||
case TT_INT32:
|
||||
rval_ins = lir->insLoad(LIR_ld, lirbuf->sp, exit->sp_adj - sizeof(double));
|
||||
break;
|
||||
case TT_DOUBLE:
|
||||
rval_ins = lir->insLoad(LIR_ldf, lirbuf->sp, exit->sp_adj - sizeof(double));
|
||||
break;
|
||||
case TT_FUNCTION:
|
||||
case TT_OBJECT:
|
||||
case TT_STRING:
|
||||
case TT_NULL:
|
||||
rval_ins = lir->insLoad(LIR_ldp, lirbuf->sp, exit->sp_adj - sizeof(double));
|
||||
break;
|
||||
default:
|
||||
JS_NOT_REACHED("unknown type");
|
||||
RETURN_STOP_A("unknown type");
|
||||
}
|
||||
intptr_t offset = exit->sp_adj - sizeof(double);
|
||||
TraceType returnType = exit->stackTypeMap()[downPostSlots];
|
||||
|
||||
if (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT) {
|
||||
rval_ins = get(&stackval(-1));
|
||||
if (returnType == TT_INT32) {
|
||||
JS_ASSERT(determineSlotType(&stackval(-1)) == TT_INT32);
|
||||
JS_ASSERT(isPromoteInt(rval_ins));
|
||||
rval_ins = demote(lir, rval_ins);
|
||||
}
|
||||
/*
|
||||
* The return value must be written out early, before slurping can fail,
|
||||
* otherwise it will not be available when there's a type mismatch.
|
||||
*/
|
||||
lir->insStorei(rval_ins, lirbuf->sp, offset);
|
||||
} else {
|
||||
rval_ins = INS_CONST(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
||||
switch (returnType)
|
||||
{
|
||||
case TT_PSEUDOBOOLEAN:
|
||||
case TT_INT32:
|
||||
rval_ins = lir->insLoad(LIR_ld, lirbuf->sp, offset);
|
||||
break;
|
||||
case TT_DOUBLE:
|
||||
rval_ins = lir->insLoad(LIR_ldf, lirbuf->sp, offset);
|
||||
break;
|
||||
case TT_FUNCTION:
|
||||
case TT_OBJECT:
|
||||
case TT_STRING:
|
||||
case TT_NULL:
|
||||
rval_ins = lir->insLoad(LIR_ldp, lirbuf->sp, offset);
|
||||
break;
|
||||
default:
|
||||
JS_NOT_REACHED("unknown type");
|
||||
RETURN_STOP_A("unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
/* Slurp */
|
||||
|
39
js/src/trace-test/tests/basic/bug551705.js
Normal file
39
js/src/trace-test/tests/basic/bug551705.js
Normal file
@ -0,0 +1,39 @@
|
||||
(Function("\
|
||||
for each(let x in [\n\
|
||||
true,\n\
|
||||
(1),\n\
|
||||
(1),\n\
|
||||
(1),\n\
|
||||
(1),\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
(1),\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
(1),\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
(1),\n\
|
||||
(1),\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
true,\n\
|
||||
true\n\
|
||||
]) { \n\
|
||||
((function f(aaaaaa) {\n\
|
||||
return aaaaaa.length == 0 ? 0 : aaaaaa[0] + f(aaaaaa.slice(1))\n\
|
||||
})([\n\
|
||||
x,\n\
|
||||
Math.I,\n\
|
||||
'',\n\
|
||||
null,\n\
|
||||
Math.I,\n\
|
||||
null,\n\
|
||||
new String(),\n\
|
||||
new String()\n\
|
||||
]))\n\
|
||||
}"))()
|
||||
|
||||
/* Don't assert/crash. */
|
||||
|
Loading…
Reference in New Issue
Block a user