Bug 1016523 - Part 2: Handle propagated forced returns in Baseline. (r=jandem)
authorShu-yu Guo <shu@rfrn.org>
Thu, 05 Jun 2014 15:10:33 -0700
changeset 207282 f54319e70aa95b966d407978b175532fe583c2c4
parent 207281 6f0ea3b13b103303c527d499511b29b3f9b5dd72
child 207283 4c794b0e6e9cba4324152562377df20d2d0d5931
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1016523
milestone32.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
Bug 1016523 - Part 2: Handle propagated forced returns in Baseline. (r=jandem)
js/src/jit/IonFrames.cpp
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -21,16 +21,17 @@
 #include "jit/JitCompartment.h"
 #include "jit/ParallelFunctions.h"
 #include "jit/PcScriptCache.h"
 #include "jit/Recover.h"
 #include "jit/Safepoints.h"
 #include "jit/Snapshots.h"
 #include "jit/VMFunctions.h"
 #include "vm/ArgumentsObject.h"
+#include "vm/Debugger.h"
 #include "vm/ForkJoin.h"
 #include "vm/Interpreter.h"
 
 #include "jsscriptinlines.h"
 #include "jit/JitFrameIterator-inl.h"
 #include "vm/Probes-inl.h"
 
 namespace js {
@@ -426,51 +427,68 @@ HandleExceptionIon(JSContext *cx, const 
 
           default:
             MOZ_ASSUME_UNREACHABLE("Unexpected try note");
         }
     }
 }
 
 static void
+ForcedReturn(JSContext *cx, const JitFrameIterator &frame, jsbytecode *pc,
+             ResumeFromException *rfe, bool *calledDebugEpilogue)
+{
+    BaselineFrame *baselineFrame = frame.baselineFrame();
+    MOZ_ASSERT(baselineFrame->hasReturnValue());
+
+    if (jit::DebugEpilogue(cx, baselineFrame, pc, true)) {
+        rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
+        rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
+        rfe->stackPointer = reinterpret_cast<uint8_t *>(baselineFrame);
+        return;
+    }
+
+    // DebugEpilogue threw an exception. Propagate to the caller frame.
+    *calledDebugEpilogue = true;
+}
+
+static void
 HandleExceptionBaseline(JSContext *cx, const JitFrameIterator &frame, ResumeFromException *rfe,
                         jsbytecode **unwoundScopeToPc, bool *calledDebugEpilogue)
 {
     JS_ASSERT(frame.isBaselineJS());
     JS_ASSERT(!*calledDebugEpilogue);
 
     RootedScript script(cx);
     jsbytecode *pc;
     frame.baselineScriptAndPc(script.address(), &pc);
 
+    // We may be propagating a forced return from the interrupt
+    // callback, which cannot easily force a return.
+    if (cx->isPropagatingForcedReturn()) {
+        cx->clearPropagatingForcedReturn();
+        ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue);
+        return;
+    }
+
     if (cx->isExceptionPending() && cx->compartment()->debugMode()) {
         BaselineFrame *baselineFrame = frame.baselineFrame();
         JSTrapStatus status = DebugExceptionUnwind(cx, baselineFrame, pc);
         switch (status) {
           case JSTRAP_ERROR:
             // Uncatchable exception.
             JS_ASSERT(!cx->isExceptionPending());
             break;
 
           case JSTRAP_CONTINUE:
           case JSTRAP_THROW:
             JS_ASSERT(cx->isExceptionPending());
             break;
 
           case JSTRAP_RETURN:
-            JS_ASSERT(baselineFrame->hasReturnValue());
-            if (jit::DebugEpilogue(cx, baselineFrame, pc, true)) {
-                rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
-                rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
-                rfe->stackPointer = reinterpret_cast<uint8_t *>(baselineFrame);
-                return;
-            }
-
-            // DebugEpilogue threw an exception. Propagate to the caller frame.
-            *calledDebugEpilogue = true;
+            ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue);
             return;
 
           default:
             MOZ_ASSUME_UNREACHABLE("Invalid trap status");
         }
     }
 
     if (!script->hasTrynotes())