Bug 679251 - InlineReturn should advance the pc always (r=dvander)
authorLuke Wagner <luke@mozilla.com>
Tue, 16 Aug 2011 09:23:30 -0700
changeset 75389 9967f28c64e183bd85ae5f761c3ab2d8cb5adbc3
parent 75388 e765c8f565c63da5550aa59bf5d6358a4392fee0
child 75390 41b84b87c816403e1b74963d8094cff0406c989e
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersdvander
bugs679251
milestone8.0a1
Bug 679251 - InlineReturn should advance the pc always (r=dvander)
js/src/methodjit/InvokeHelpers.cpp
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -174,16 +174,23 @@ top:
  * Clean up a frame and return.
  */
 static void
 InlineReturn(VMFrame &f)
 {
     JS_ASSERT(f.fp() != f.entryfp);
     JS_ASSERT(!js_IsActiveWithOrBlock(f.cx, &f.fp()->scopeChain(), 0));
     f.cx->stack.popInlineFrame(f.regs);
+
+    JS_ASSERT(*f.regs.pc == JSOP_CALL ||
+              *f.regs.pc == JSOP_NEW ||
+              *f.regs.pc == JSOP_EVAL ||
+              *f.regs.pc == JSOP_FUNCALL ||
+              *f.regs.pc == JSOP_FUNAPPLY);
+    f.regs.pc += JSOP_CALL_LENGTH;
 }
 
 void JS_FASTCALL
 stubs::SlowCall(VMFrame &f, uint32 argc)
 {
     if (!Invoke(f.cx, CallArgsFromSp(argc, f.regs.sp)))
         THROW();
 }
@@ -704,30 +711,16 @@ FrameIsFinished(JSContext *cx)
     JSOp op = JSOp(*cx->regs().pc);
     return (op == JSOP_RETURN ||
             op == JSOP_RETRVAL ||
             op == JSOP_STOP)
         ? true
         : cx->fp()->finishedInInterpreter();
 }
 
-
-/* Simulate an inline_return by advancing the pc. */
-static inline void
-AdvanceReturnPC(JSContext *cx)
-{
-    JS_ASSERT(*cx->regs().pc == JSOP_CALL ||
-              *cx->regs().pc == JSOP_NEW ||
-              *cx->regs().pc == JSOP_EVAL ||
-              *cx->regs().pc == JSOP_FUNCALL ||
-              *cx->regs().pc == JSOP_FUNAPPLY);
-    cx->regs().pc += JSOP_CALL_LENGTH;
-}
-
-
 /*
  * Given a frame that is about to return, make sure its return value and
  * activation objects are fixed up. Then, pop the frame and advance the
  * current PC. Note that while we could enter the JIT at this point, the
  * logic would still be necessary for the interpreter, so it's easier
  * (and faster) to finish frames in C++ even if at a safe point here.
  */
 static bool
@@ -769,17 +762,16 @@ HandleFinishedFrame(VMFrame &f, StackFra
         if (JSOp(*cx->regs().pc) == JSOP_RETURN)
             cx->fp()->setReturnValue(f.regs.sp[-1]);
 
         returnOK = ScriptEpilogue(cx, cx->fp(), true);
     }
 
     if (cx->fp() != entryFrame) {
         InlineReturn(f);
-        AdvanceReturnPC(cx);
     }
 
     return returnOK;
 }
 
 /*
  * Given a frame newer than the entry frame, try to finish it. If it's at a
  * return position, pop the frame. If it's at a safe point, execute it in
@@ -809,17 +801,16 @@ EvaluateExcessFrame(VMFrame &f, StackFra
      */
     if (!fp->hasImacropc() && FrameIsFinished(cx))
         return HandleFinishedFrame(f, entryFrame);
 
     if (void *ncode = AtSafePoint(cx)) {
         if (!JaegerShotAtSafePoint(cx, ncode))
             return false;
         InlineReturn(f);
-        AdvanceReturnPC(cx);
         return true;
     }
 
     return PartialInterpret(f);
 }
 
 /*
  * Evaluate frames newer than the entry frame until all are gone. This will