Fixed breaks in switch statements causing premature end-of-traces (bug 456345, r=gal,brendan).

This commit is contained in:
David Anderson 2008-09-24 13:12:25 -07:00
parent c184542b3b
commit a53ee95a20
3 changed files with 34 additions and 3 deletions

View File

@ -4622,7 +4622,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
ale = NULL;
while (!STMT_IS_LOOP(stmt) && stmt->type != STMT_SWITCH)
stmt = stmt->down;
noteType = SRC_BREAK;
noteType = (stmt->type == STMT_SWITCH) ? SRC_NULL : SRC_BREAK;
}
if (EmitGoto(cx, cg, stmt, &stmt->breaks, ale, noteType) < 0)

View File

@ -1832,7 +1832,7 @@ TraceRecorder::closeLoop(Fragmento* fragmento)
}
compile(fragmento);
debug_only_v(printf("recording completed at %s:%u@%u\n", cx->fp->script->filename,
debug_only_v(printf("recording completed at %s:%u@%u via closeLoop\n", cx->fp->script->filename,
js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
cx->fp->regs->pc - cx->fp->script->code););
}
@ -1844,6 +1844,10 @@ TraceRecorder::endLoop(Fragmento* fragmento)
SideExit *exit = snapshot(LOOP_EXIT);
fragment->lastIns = lir->insGuard(LIR_x, lir->insImm(1), exit);
compile(fragmento);
debug_only_v(printf("recording completed at %s:%u@%u via endLoop\n", cx->fp->script->filename,
js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
cx->fp->regs->pc - cx->fp->script->code););
}
/* Emit code to adjust the stack to match the inner tree's stack expectations. */
@ -1890,7 +1894,6 @@ TraceRecorder::prepareTreeCall(Fragment* inner)
void
TraceRecorder::emitTreeCall(Fragment* inner, GuardRecord* lr)
{
JS_ASSERT(lr->exit->exitType == LOOP_EXIT && !lr->calldepth);
TreeInfo* ti = (TreeInfo*)inner->vmprivate;
/* Invoke the inner tree. */
LIns* args[] = { INS_CONSTPTR(inner), lirbuf->state }; /* reverse order */
@ -2446,6 +2449,8 @@ js_ExecuteTree(JSContext* cx, Fragment** treep, uintN& inlineCallCount,
lr = u.func(&state, NULL);
#endif
JS_ASSERT(lr->exit->exitType != LOOP_EXIT || !lr->calldepth);
if (!onTrace)
tm->onTrace = false;

View File

@ -1583,6 +1583,32 @@ function testMatchStringObject() {
testMatchStringObject.expected = null;
test(testMatchStringObject);
function innerSwitch(k)
{
var m = 0;
switch (k)
{
case 0:
m = 1;
break;
}
return m;
}
function testInnerSwitchBreak()
{
var r = new Array(5);
for (var i = 0; i < 5; i++)
{
r[i] = innerSwitch(0);
}
return r.join(",");
}
testInnerSwitchBreak.expected = "1,1,1,1,1";
test(testInnerSwitchBreak);
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
print("\npassed:", passes.length && passes.join(","));
print("\nFAILED:", fails.length && fails.join(","));