From 395f00950412e0b390499b368d66239a10be3bc8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 24 Sep 2008 13:12:25 -0700 Subject: [PATCH] Fixed breaks in switch statements causing premature end-of-traces (bug 456345, r=gal,brendan). --- js/src/jsemit.cpp | 2 +- js/src/jstracer.cpp | 9 +++++++-- js/src/trace-test.js | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp index e281ecbf845a..214f11e50844 100644 --- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -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) diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 6e8299a43fd4..d17c82f54b45 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -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; diff --git a/js/src/trace-test.js b/js/src/trace-test.js index fc4dc0b362ad..8da3f0e35429 100644 --- a/js/src/trace-test.js +++ b/js/src/trace-test.js @@ -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(","));