[INFER] Preserve invariant entry ordering when removing existing redundant entries, bug 668643.
authorBrian Hackett <bhackett1024@gmail.com>
Sat, 02 Jul 2011 18:25:12 -0700
changeset 75174 90768623f7ec6ed660b4d196e6b90c1b85c12540
parent 75173 ff54e5c320bacbb1df5a4dc109a0ce70add0cbbd
child 75175 279a046a56cd4ef5fb087715ec140a28f52a3953
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs668643
milestone7.0a1
[INFER] Preserve invariant entry ordering when removing existing redundant entries, bug 668643.
js/src/jit-test/tests/jaeger/loops/bug668643.js
js/src/methodjit/LoopState.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/loops/bug668643.js
@@ -0,0 +1,12 @@
+
+function foo(a,n) {
+  var x = {a:[]};
+  for (var i = 0; i < n; ) {
+    a[i];
+    x.a[i];
+    a[++i];
+  }
+}
+var a = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0];
+var n = a.length;
+foo(a,n);
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -360,18 +360,26 @@ LoopState::checkRedundantEntry(const Inv
 
     for (unsigned i = 0; i < length; i++) {
         InvariantEntry &baseEntry = invariantEntries[i];
         if (!baseEntry.isCheck())
             continue;
         if (entryRedundant(entry, baseEntry))
             return true;
         if (entryRedundant(baseEntry, entry)) {
-            invariantEntries[i--] = invariantEntries.back();
+            /*
+             * Make sure to maintain the existing ordering on how invariant
+             * entries are generated, this is required for e.g. entries which
+             * use temporaries or slot computations which appear before any
+             * bounds checks on the arrays.
+             */
+            for (unsigned j = i; j < length - 1; j++)
+                invariantEntries[j] = invariantEntries[j + 1];
             invariantEntries.popBack();
+            i--;
             length--;
         }
     }
 
     return false;
 }
 
 bool