diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/src/jit-test/tests/ion/bug1493900-1.js | 17 | ||||
-rw-r--r-- | js/src/jit-test/tests/ion/bug1493900-2.js | 7 | ||||
-rw-r--r-- | js/src/jit/BacktrackingAllocator.cpp | 38 | ||||
-rw-r--r-- | js/src/jit/BacktrackingAllocator.h | 30 |
4 files changed, 66 insertions, 26 deletions
diff --git a/js/src/jit-test/tests/ion/bug1493900-1.js b/js/src/jit-test/tests/ion/bug1493900-1.js new file mode 100644 index 000000000..643c1943d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1493900-1.js @@ -0,0 +1,17 @@ +function f() { + var objs = []; + for (var i = 0; i < 100; i++) { + objs[i] = {}; + } + var o = objs[0]; + var a = new Float64Array(1024); + function g(a, b) { + let p = b; + for (; p.x < 0; p = p.x) { + while (p === p) {} + } + for (var i = 0; i < 10000; ++i) {} + } + g(a, o); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1493900-2.js b/js/src/jit-test/tests/ion/bug1493900-2.js new file mode 100644 index 000000000..7e7f5fdec --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1493900-2.js @@ -0,0 +1,7 @@ +function f(a, b) { + for (; b.x < 0; b = b.x) { + while (b === b) {}; + } + for (var i = 0; i < 99999; ++i) {} +} +f(0, 0); diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 741ed1592..645aefc4f 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -1736,6 +1736,18 @@ BacktrackingAllocator::deadRange(LiveRange* range) } bool +BacktrackingAllocator::moveAtEdge(LBlock* predecessor, LBlock* successor, LiveRange* from, + LiveRange* to, LDefinition::Type type) +{ + if (successor->mir()->numPredecessors() > 1) { + MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); + return moveAtExit(predecessor, from, to, type); + } + + return moveAtEntry(successor, from, to, type); +} + +bool BacktrackingAllocator::resolveControlFlow() { // Add moves to handle changing assignments for vregs over their lifetime. @@ -1846,15 +1858,11 @@ BacktrackingAllocator::resolveControlFlow() if (!alloc().ensureBallast()) { return false; } - if (mSuccessor->numPredecessors() > 1) { - MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); - if (!moveAtExit(predecessor, from, to, def->type())) { - return false; - } - } else { - if (!moveAtEntry(successor, from, to, def->type())) { - return false; - } + + // Note: we have to use moveAtEdge both here and below (for edge + // resolution) to avoid conflicting moves. See bug 1493900. + if (!moveAtEdge(predecessor, successor, from, to, def->type())) { + return false; } } } @@ -1884,16 +1892,12 @@ BacktrackingAllocator::resolveControlFlow() if (targetRange->covers(exitOf(predecessor))) continue; - if (!alloc().ensureBallast()) + if (!alloc().ensureBallast()) { return false; + } LiveRange* from = reg.rangeFor(exitOf(predecessor), true); - if (successor->mir()->numPredecessors() > 1) { - MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); - if (!moveAtExit(predecessor, from, targetRange, reg.type())) - return false; - } else { - if (!moveAtEntry(successor, from, targetRange, reg.type())) - return false; + if (!moveAtEdge(predecessor, successor, from, targetRange, reg.type())) { + return false; } } } diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index 9910498fb..c6cf26695 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -108,8 +108,9 @@ class Requirement } MOZ_ASSERT(newRequirement.kind() == Requirement::REGISTER); - if (kind() == Requirement::FIXED) + if (kind() == Requirement::FIXED) { return allocation().isRegister(); + } *this = newRequirement; return true; @@ -353,10 +354,12 @@ class LiveRange : public TempObject // Comparator for use in range splay trees. static int compare(LiveRange* v0, LiveRange* v1) { // LiveRange includes 'from' but excludes 'to'. - if (v0->to() <= v1->from()) + if (v0->to() <= v1->from()) { return -1; - if (v0->from() >= v1->to()) + } + if (v0->from() >= v1->to()) { return 1; + } return 0; } }; @@ -642,10 +645,12 @@ class BacktrackingAllocator : protected RegisterAllocator // Comparator for use in splay tree. static int compare(CallRange* v0, CallRange* v1) { - if (v0->range.to <= v1->range.from) + if (v0->range.to <= v1->range.from) { return -1; - if (v0->range.from >= v1->range.to) + } + if (v0->range.from >= v1->range.to) { return 1; + } return 0; } }; @@ -744,36 +749,43 @@ class BacktrackingAllocator : protected RegisterAllocator MOZ_MUST_USE bool moveInput(LInstruction* ins, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = getInputMoveGroup(ins); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAfter(LInstruction* ins, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = getMoveGroupAfter(ins); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAtExit(LBlock* block, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = block->getExitMoveGroup(alloc()); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAtEntry(LBlock* block, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = block->getEntryMoveGroup(alloc()); return addMove(moves, from, to, type); } + MOZ_MUST_USE bool moveAtEdge(LBlock* predecessor, LBlock* successor, LiveRange* from, + LiveRange* to, LDefinition::Type type); + // Debugging methods. void dumpAllocations(); |