diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/src/jit-test/tests/ion/bug1333946.js | 6 | ||||
-rw-r--r-- | js/src/jit/IonBuilder.cpp | 45 |
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(); } } } |