mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Fixed recursion not tracing when hitting JSOP_STOP instead of JSOP_RETURN (bug 530900, r=gal).
This commit is contained in:
parent
d12dfe06f1
commit
648e699428
@ -156,9 +156,19 @@ TraceRecorder::downSnapshot(FrameInfo* downFrame)
|
||||
unsigned exitTypeMapLen = downPostSlots + 1 + ngslots;
|
||||
JSTraceType* exitTypeMap = (JSTraceType*)alloca(sizeof(JSTraceType) * exitTypeMapLen);
|
||||
JSTraceType* typeMap = downFrame->get_typemap();
|
||||
|
||||
/* Add stack slots. */
|
||||
for (unsigned i = 0; i < downPostSlots; i++)
|
||||
exitTypeMap[i] = typeMap[i];
|
||||
exitTypeMap[downPostSlots] = determineSlotType(&stackval(-1));
|
||||
|
||||
/* Add the return type. */
|
||||
JS_ASSERT_IF(*cx->fp->regs->pc != JSOP_RETURN, *cx->fp->regs->pc == JSOP_STOP);
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN)
|
||||
exitTypeMap[downPostSlots] = determineSlotType(&stackval(-1));
|
||||
else
|
||||
exitTypeMap[downPostSlots] = TT_PSEUDOBOOLEAN;
|
||||
|
||||
/* Add global types. */
|
||||
determineGlobalTypes(&exitTypeMap[downPostSlots + 1]);
|
||||
|
||||
VMSideExit* exit = (VMSideExit*)
|
||||
@ -246,9 +256,9 @@ TraceRecorder::upRecursion()
|
||||
* This is always safe because this point is only reached on simple "call myself"
|
||||
* recursive functions.
|
||||
*/
|
||||
#if defined DEBUG
|
||||
#if defined DEBUG
|
||||
AssertDownFrameIsConsistent(cx, anchor, fi);
|
||||
#endif
|
||||
#endif
|
||||
fi = anchor->recursive_down;
|
||||
} else if (recursive_pc != fragment->root->ip) {
|
||||
/*
|
||||
@ -296,12 +306,19 @@ TraceRecorder::upRecursion()
|
||||
*/
|
||||
exit = downSnapshot(fi);
|
||||
|
||||
LIns* rval_ins = (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT) ?
|
||||
get(&stackval(-1)) :
|
||||
NULL;
|
||||
JS_ASSERT(rval_ins != NULL);
|
||||
LIns* rval_ins;
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN) {
|
||||
rval_ins = (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT) ?
|
||||
get(&stackval(-1)) :
|
||||
NULL;
|
||||
JS_ASSERT(rval_ins);
|
||||
} else {
|
||||
rval_ins = INS_CONST(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
||||
}
|
||||
|
||||
JSTraceType returnType = exit->stackTypeMap()[downPostSlots];
|
||||
if (returnType == TT_INT32) {
|
||||
JS_ASSERT(*cx->fp->regs->pc == JSOP_RETURN);
|
||||
JS_ASSERT(determineSlotType(&stackval(-1)) == TT_INT32);
|
||||
JS_ASSERT(isPromoteInt(rval_ins));
|
||||
rval_ins = ::demote(lir, rval_ins);
|
||||
@ -310,7 +327,10 @@ TraceRecorder::upRecursion()
|
||||
UpRecursiveSlotMap slotMap(*this, downPostSlots, rval_ins);
|
||||
for (unsigned i = 0; i < downPostSlots; i++)
|
||||
slotMap.addSlot(exit->stackType(i));
|
||||
slotMap.addSlot(&stackval(-1));
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN)
|
||||
slotMap.addSlot(&stackval(-1));
|
||||
else
|
||||
slotMap.addSlot(TT_PSEUDOBOOLEAN);
|
||||
VisitGlobalSlots(slotMap, cx, *tree->globalSlots);
|
||||
if (recursive_pc == (jsbytecode*)fragment->root->ip) {
|
||||
debug_only_print0(LC_TMTracer, "Compiling up-recursive loop...\n");
|
||||
@ -447,10 +467,15 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
||||
cx->fp->regs->pc = exit->pc;
|
||||
js_CaptureStackTypes(cx, frameDepth, typeMap);
|
||||
cx->fp->regs->pc = oldpc;
|
||||
if (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT)
|
||||
typeMap[downPostSlots] = determineSlotType(&stackval(-1));
|
||||
else
|
||||
if (!anchor || anchor->exitType != RECURSIVE_SLURP_FAIL_EXIT) {
|
||||
JS_ASSERT_IF(*cx->fp->regs->pc != JSOP_RETURN, *cx->fp->regs->pc == JSOP_STOP);
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN)
|
||||
typeMap[downPostSlots] = determineSlotType(&stackval(-1));
|
||||
else
|
||||
typeMap[downPostSlots] = TT_PSEUDOBOOLEAN;
|
||||
} else {
|
||||
typeMap[downPostSlots] = anchor->stackTypeMap()[anchor->numStackSlots - 1];
|
||||
}
|
||||
determineGlobalTypes(&typeMap[exit->numStackSlots]);
|
||||
#if defined JS_JIT_SPEW
|
||||
TreevisLogExit(cx, exit);
|
||||
@ -466,39 +491,43 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
||||
* grabbed safely.
|
||||
*/
|
||||
LIns* rval_ins;
|
||||
JSTraceType 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);
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN) {
|
||||
JSTraceType 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_ldq, 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");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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_ldq, 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");
|
||||
}
|
||||
rval_ins = INS_CONST(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
||||
}
|
||||
|
||||
/* Slurp */
|
||||
@ -556,7 +585,10 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
||||
RecursiveSlotMap slotMap(*this, downPostSlots, rval_ins);
|
||||
for (unsigned i = 0; i < downPostSlots; i++)
|
||||
slotMap.addSlot(typeMap[i]);
|
||||
slotMap.addSlot(&stackval(-1), typeMap[downPostSlots]);
|
||||
if (*cx->fp->regs->pc == JSOP_RETURN)
|
||||
slotMap.addSlot(&stackval(-1), typeMap[downPostSlots]);
|
||||
else
|
||||
slotMap.addSlot(TT_PSEUDOBOOLEAN);
|
||||
VisitGlobalSlots(slotMap, cx, *tree->globalSlots);
|
||||
debug_only_print0(LC_TMTracer, "Compiling up-recursive slurp...\n");
|
||||
exit = copy(exit);
|
||||
|
@ -4682,7 +4682,8 @@ TraceRecorder::closeLoop(SlotMap& slotMap, VMSideExit* exit)
|
||||
* case this loop was blacklisted in the meantime, JSOP_NOP.
|
||||
*/
|
||||
JS_ASSERT((*cx->fp->regs->pc == JSOP_TRACE || *cx->fp->regs->pc == JSOP_NOP ||
|
||||
*cx->fp->regs->pc == JSOP_RETURN) && !cx->fp->imacpc);
|
||||
*cx->fp->regs->pc == JSOP_RETURN || *cx->fp->regs->pc == JSOP_STOP) &&
|
||||
!cx->fp->imacpc);
|
||||
|
||||
if (callDepth != 0) {
|
||||
debug_only_print0(LC_TMTracer,
|
||||
@ -14204,6 +14205,11 @@ TraceRecorder::record_JSOP_CALLELEM()
|
||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::record_JSOP_STOP()
|
||||
{
|
||||
if (callDepth == 0 && IsTraceableRecursion(cx) &&
|
||||
tree->recursion != Recursion_Disallowed &&
|
||||
tree->script == cx->fp->script) {
|
||||
return InjectStatus(upRecursion());
|
||||
}
|
||||
JSStackFrame *fp = cx->fp;
|
||||
|
||||
if (fp->imacpc) {
|
||||
|
Loading…
Reference in New Issue
Block a user