Bug 994444. (r=nbp)
authorShu-yu Guo <shu@rfrn.org>
Mon, 14 Apr 2014 22:00:07 -0700
changeset 196943 a71e790f9652157844c03f9c700ff1cdcfdc3f8b
parent 196942 0ff06ac4a4349a4ca72d709274b291c4498c4bd5
child 196944 5f65bfd35342939845d341d4ea5861a7c56feec6
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs994444
milestone31.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 994444. (r=nbp)
js/src/jit/BaselineBailouts.cpp
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -387,16 +387,27 @@ GetStubReturnAddress(JSContext *cx, jsby
         return cx->compartment()->jitCompartment()->baselineGetPropReturnAddr();
     if (IsSetPropPC(pc))
         return cx->compartment()->jitCompartment()->baselineSetPropReturnAddr();
     // This should be a call op of some kind, now.
     JS_ASSERT(IsCallPC(pc));
     return cx->compartment()->jitCompartment()->baselineCallReturnAddr();
 }
 
+static inline jsbytecode *
+GetNextNonLoopEntryPc(jsbytecode *pc)
+{
+    JSOp op = JSOp(*pc);
+    if (op == JSOP_GOTO)
+        return pc + GET_JUMP_OFFSET(pc);
+    if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD)
+        return GetNextPc(pc);
+    return pc;
+}
+
 // For every inline frame, we write out the following data:
 //
 //                      |      ...      |
 //                      +---------------+
 //                      |  Descr(???)   |  --- Descr size here is (PREV_FRAME_SIZE)
 //                      +---------------+
 //                      |  ReturnAddr   |
 //             --       +===============+  --- OVERWRITE STARTS HERE  (START_STACK_ADDR)
@@ -778,26 +789,28 @@ InitFromBailout(JSContext *cx, HandleScr
             return false;
     }
 
     size_t endOfBaselineJSFrameStack = builder.framePushed();
 
     // If we are resuming at a LOOPENTRY op, resume at the next op to avoid
     // a bailout -> enter Ion -> bailout loop with --ion-eager. See also
     // ThunkToInterpreter.
+    //
+    // The algorithm below is the "tortoise and the hare" algorithm. See bug
+    // 994444 for more explanation.
     if (!resumeAfter) {
+        jsbytecode *fasterPc = pc;
         while (true) {
-            op = JSOp(*pc);
-            if (op == JSOP_GOTO)
-                pc += GET_JUMP_OFFSET(pc);
-            else if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD)
-                pc = GetNextPc(pc);
-            else
+            pc = GetNextNonLoopEntryPc(pc);
+            fasterPc = GetNextNonLoopEntryPc(GetNextNonLoopEntryPc(fasterPc));
+            if (fasterPc == pc)
                 break;
         }
+        op = JSOp(*pc);
     }
 
     uint32_t pcOff = script->pcToOffset(pc);
     bool isCall = IsCallPC(pc);
     BaselineScript *baselineScript = script->baselineScript();
 
 #ifdef DEBUG
     uint32_t expectedDepth;