summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/src/jit-test/tests/ion/bug1333946.js6
-rw-r--r--js/src/jit/IonBuilder.cpp45
2 files changed, 27 insertions, 24 deletions
diff --git a/js/src/jit-test/tests/ion/bug1333946.js b/js/src/jit-test/tests/ion/bug1333946.js
new file mode 100644
index 000000000..9cb3fb629
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1333946.js
@@ -0,0 +1,6 @@
+// |jit-test| exitstatus: 6;
+
+for (var x of [0]) {
+ timeout(0.001);
+ for (;;) {}
+}
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index 4318db2b6..534a48a90 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -958,35 +958,32 @@ IonBuilder::build()
bool
IonBuilder::processIterators()
{
- // Find phis that must directly hold an iterator live.
- Vector<MPhi*, 0, SystemAllocPolicy> worklist;
+ // Find and mark phis that must transitively hold an iterator live.
+
+ Vector<MDefinition*, 8, SystemAllocPolicy> worklist;
+
for (size_t i = 0; i < iterators_.length(); i++) {
- MDefinition* def = iterators_[i];
- if (def->isPhi()) {
- if (!worklist.append(def->toPhi()))
- return false;
- } else {
- for (MUseDefIterator iter(def); iter; iter++) {
- if (iter.def()->isPhi()) {
- if (!worklist.append(iter.def()->toPhi()))
- return false;
- }
- }
- }
+ if (!worklist.append(iterators_[i]))
+ return false;
+ iterators_[i]->setInWorklist();
}
- // Propagate the iterator and live status of phis to all other connected
- // phis.
while (!worklist.empty()) {
- MPhi* phi = worklist.popCopy();
- phi->setIterator();
- phi->setImplicitlyUsedUnchecked();
-
- for (MUseDefIterator iter(phi); iter; iter++) {
- if (iter.def()->isPhi()) {
- MPhi* other = iter.def()->toPhi();
- if (!other->isIterator() && !worklist.append(other))
+ MDefinition* def = worklist.popCopy();
+ def->setNotInWorklist();
+
+ if (def->isPhi()) {
+ MPhi* phi = def->toPhi();
+ phi->setIterator();
+ phi->setImplicitlyUsedUnchecked();
+ }
+
+ for (MUseDefIterator iter(def); iter; iter++) {
+ MDefinition* use = iter.def();
+ if (!use->isInWorklist() && (!use->isPhi() || !use->toPhi()->isIterator())) {
+ if (!worklist.append(use))
return false;
+ use->setInWorklist();
}
}
}