summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--js/src/jit-test/tests/ion/bug1493900-1.js17
-rw-r--r--js/src/jit-test/tests/ion/bug1493900-2.js7
-rw-r--r--js/src/jit/BacktrackingAllocator.cpp38
-rw-r--r--js/src/jit/BacktrackingAllocator.h3
4 files changed, 48 insertions, 17 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..ef3c2a572 100644
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -774,6 +774,9 @@ class BacktrackingAllocator : protected RegisterAllocator
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();