[INFER] Allow uncopies of loop temporaries after backedges, bug 684621.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 05 Sep 2011 07:33:06 -0700
changeset 77896 1c934fd8ac88f92f8db6df69d8415ed33d9f6d09
parent 77895 d4696bf0d286e56d9f1399a1cbcf485ed0a5eae4
child 77897 584386505971537c7ea479e51995a3c66abaf7ea
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs684621
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
[INFER] Allow uncopies of loop temporaries after backedges, bug 684621.
js/src/jit-test/tests/jaeger/loops/bug684621.js
js/src/methodjit/FrameState.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/loops/bug684621.js
@@ -0,0 +1,15 @@
+function runRichards() {
+    queue = new Packet;
+    Packet(queue, ID_DEVICE_A, KIND_DEVICE);
+    new Packet;
+}
+var ID_DEVICE_A = 4;
+var KIND_DEVICE = 0;
+Packet = function (queue) {
+    this.link = null
+    if (queue == null) return;
+    var peek, next = queue;
+    while ((peek = next.link) != null)
+    ID_HANDLER_B
+};
+runRichards()
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -1944,19 +1944,16 @@ FrameState::pushCopyOf(FrameEntry *backi
         if (fe->trackerIndex() < backing->trackerIndex())
             swapInTracker(fe, backing);
     }
 }
 
 FrameEntry *
 FrameState::walkTrackerForUncopy(FrameEntry *original)
 {
-    /* Temporary entries are immutable and should never be uncopied. */
-    JS_ASSERT(!isTemporary(original));
-
     uint32 firstCopy = InvalidIndex;
     FrameEntry *bestFe = NULL;
     uint32 ncopies = 0;
     for (uint32 i = original->trackerIndex() + 1; i < tracker.nentries; i++) {
         FrameEntry *fe = tracker[i];
         if (deadEntry(fe))
             continue;
         if (fe->isCopy() && fe->copyOf() == original) {
@@ -1973,17 +1970,17 @@ FrameState::walkTrackerForUncopy(FrameEn
     if (!ncopies) {
         JS_ASSERT(firstCopy == InvalidIndex);
         JS_ASSERT(!bestFe);
         return NULL;
     }
 
     JS_ASSERT(firstCopy != InvalidIndex);
     JS_ASSERT(bestFe);
-    JS_ASSERT(bestFe > original);
+    JS_ASSERT_IF(!isTemporary(original), bestFe > original);
 
     /* Mark all extra copies as copies of the new backing index. */
     bestFe->setCopyOf(NULL);
     if (ncopies > 1) {
         for (uint32 i = firstCopy; i < tracker.nentries; i++) {
             FrameEntry *other = tracker[i];
             if (deadEntry(other) || other == bestFe)
                 continue;
@@ -2868,16 +2865,18 @@ FrameState::allocTemporary()
 void
 FrameState::clearTemporaries()
 {
     JS_ASSERT(!a->parent);
 
     for (FrameEntry *fe = temporaries; fe < temporariesTop; fe++) {
         if (!fe->isTracked())
             continue;
+        if (fe->isCopied())
+            uncopy(fe);
         forgetAllRegs(fe);
         fe->resetSynced();
     }
 
     temporariesTop = temporaries;
 }
 
 Vector<TemporaryCopy> *