Bug 1282741 - Fix assertion involving debug mode toggle cycles in debug mode OSR. r=jandem, a=ritu
authorShu-yu Guo <shu@rfrn.org>
Mon, 08 Aug 2016 14:46:00 -0400
changeset 350572 f79842c6d1557dfd9550baed0a1d664c978b4c36
parent 350571 02929136e12c119b544db6d8f7de1a88985423eb
child 350573 ea1cd458ad5e45ac6c74e16a7919a5814ba89fb2
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, ritu
bugs1282741
milestone50.0
Bug 1282741 - Fix assertion involving debug mode toggle cycles in debug mode OSR. r=jandem, a=ritu
js/src/jit-test/tests/debug/bug1282741.js
js/src/jit/BaselineDebugModeOSR.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug1282741.js
@@ -0,0 +1,28 @@
+
+function removeAdd(dbg, g) {
+    dbg.removeDebuggee(g);
+    dbg.addDebuggee(g);
+    switch (dbg.removeDebuggee(g)) {}
+}
+function newGlobalDebuggerPair(toggleSeq) {
+    var g = newGlobal();
+    var dbg = new Debugger;
+    dbg.addDebuggee(g);
+    g.eval("" + function f() {
+        for (var i = 0; i < 100; i++) interruptIf(i == 95);
+    });
+    setInterruptCallback(function() {
+        return true;
+    });
+    return [g, dbg];
+}
+function testEpilogue(toggleSeq) {
+    var [g, dbg] = newGlobalDebuggerPair(toggleSeq);
+    dbg.onEnterFrame = function(f) {
+        f.onPop = function() {
+            toggleSeq(dbg, g);
+        }
+    };
+    g.f()
+}
+testEpilogue(removeAdd);
--- a/js/src/jit/BaselineDebugModeOSR.cpp
+++ b/js/src/jit/BaselineDebugModeOSR.cpp
@@ -365,26 +365,23 @@ PatchBaselineFramesForDebugMode(JSContex
     //  J. From the warmup counter in the prologue.
     //
     // On to Off:
     //  - All the ways above.
     //  C. From the debug trap handler.
     //  D. From the debug prologue.
     //  E. From the debug epilogue.
     //
-    // Off to On to Off:
-    //  F. Undo case B, I or J above on previously patched yet unpopped frames.
-    //
-    // On to Off to On:
-    //  G. Undo cases B, C, D, E, I or J above on previously patched yet unpopped
+    // Cycles (On to Off to On)+ or (Off to On to Off)+:
+    //  F. Undo cases B, C, D, E, I or J above on previously patched yet unpopped
     //     frames.
     //
     // In general, we patch the return address from the VM call to return to a
     // "continuation fixer" to fix up machine state (registers and stack
-    // state). Specifics on what need to be done are documented below.
+    // state). Specifics on what needs to be done are documented below.
     //
 
     CommonFrameLayout* prev = nullptr;
     size_t entryIndex = *start;
 
     for (JitFrameIterator iter(activation); !iter.done(); ++iter) {
         switch (iter.type()) {
           case JitFrame_BaselineJS: {
@@ -453,41 +450,32 @@ PatchBaselineFramesForDebugMode(JSContex
                                                            script, pc);
                 DebugModeOSRVolatileJitFrameIterator::forwardLiveIterators(
                     cx, prev->returnAddress(), retAddr);
                 prev->setReturnAddress(retAddr);
                 entryIndex++;
                 break;
             }
 
-            // Cases F and G above.
+            // Case F above.
             //
             // We undo a previous recompile by handling cases B, C, D, E, I or J
             // like normal, except that we retrieve the pc information via
             // the previous OSR debug info stashed on the frame.
             BaselineDebugModeOSRInfo* info = iter.baselineFrame()->getDebugModeOSRInfo();
             if (info) {
                 MOZ_ASSERT(info->pc == pc);
                 MOZ_ASSERT(info->frameKind == kind);
-
-                // Case G, might need to undo B, C, D, E, I or J.
-                MOZ_ASSERT_IF(script->baselineScript()->hasDebugInstrumentation(),
-                              kind == ICEntry::Kind_CallVM ||
-                              kind == ICEntry::Kind_WarmupCounter ||
-                              kind == ICEntry::Kind_StackCheck ||
-                              kind == ICEntry::Kind_EarlyStackCheck ||
-                              kind == ICEntry::Kind_DebugTrap ||
-                              kind == ICEntry::Kind_DebugPrologue ||
-                              kind == ICEntry::Kind_DebugEpilogue);
-                // Case F, should only need to undo case B, I or J.
-                MOZ_ASSERT_IF(!script->baselineScript()->hasDebugInstrumentation(),
-                              kind == ICEntry::Kind_CallVM ||
-                              kind == ICEntry::Kind_WarmupCounter||
-                              kind == ICEntry::Kind_StackCheck ||
-                              kind == ICEntry::Kind_EarlyStackCheck);
+                MOZ_ASSERT(kind == ICEntry::Kind_CallVM ||
+                           kind == ICEntry::Kind_WarmupCounter ||
+                           kind == ICEntry::Kind_StackCheck ||
+                           kind == ICEntry::Kind_EarlyStackCheck ||
+                           kind == ICEntry::Kind_DebugTrap ||
+                           kind == ICEntry::Kind_DebugPrologue ||
+                           kind == ICEntry::Kind_DebugEpilogue);
 
                 // We will have allocated a new recompile info, so delete the
                 // existing one.
                 iter.baselineFrame()->deleteDebugModeOSRInfo();
             }
 
             // The RecompileInfo must already be allocated so that this
             // function may be infallible.