Fixed recursion in thin loops accidentally trying to close the parent loop (bug 464089, r=gal).

This commit is contained in:
David Anderson 2008-11-12 19:00:15 -08:00
parent e23679569a
commit 30101c6443
2 changed files with 35 additions and 1 deletions

View File

@ -2191,6 +2191,16 @@ TraceRecorder::closeLoop(Fragmento* fragmento, bool& demote, unsigned *demotes)
exitIns = snapshot(UNSTABLE_LOOP_EXIT);
exit = (VMSideExit*)((GuardRecord*)exitIns->payload())->exit;
if (callDepth != 0) {
debug_only_v(printf("Stack depth mismatch, possible recursion\n");)
js_BlacklistPC(fragmento, fragment);
trashTree = true;
return false;
}
JS_ASSERT(exit->numStackSlots == treeInfo->stackTypeMap.length());
peer_root = fragmento->getLoop(fragment->root->ip);
JS_ASSERT(peer_root != NULL);
stable = deduceTypeStability(peer_root, &peer, demotes);
@ -2326,7 +2336,16 @@ TraceRecorder::joinEdgesToEntry(nanojit::Fragmento* fragmento, nanojit::Fragment
void
TraceRecorder::endLoop(Fragmento* fragmento)
{
fragment->lastIns = lir->insGuard(LIR_x, lir->insImm(1), snapshot(LOOP_EXIT));
LIns* exitIns = snapshot(LOOP_EXIT);
if (callDepth != 0) {
debug_only_v(printf("Stack depth mismatch, possible recursion\n");)
js_BlacklistPC(fragmento, fragment);
trashTree = true;
return;
}
fragment->lastIns = lir->insGuard(LIR_x, lir->insImm(1), exitIns);
compile(fragmento);
if (fragmento->assm()->error() != nanojit::None)

View File

@ -1851,6 +1851,21 @@ function testBug463490() {
testBug463490.expected = true;
test(testBug463490);
// Test no assert (bug 464089)
function shortRecursiveLoop(b, c) {
for (var i = 0; i < c; i++) {
if (b)
shortRecursiveLoop(c - 1);
}
}
function testClosingRecursion() {
shortRecursiveLoop(false, 1);
shortRecursiveLoop(true, 3);
return true;
}
testClosingRecursion.expected = true;
test(testClosingRecursion);
// BEGIN MANDELBROT STUFF
// XXXbz I would dearly like to wrap it up into a function to avoid polluting
// the global scope, but the function ends up heavyweight, and then we lose on