Bug 882111 part 1 - Some js::Interpret cleanup. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 14 Jun 2013 09:46:28 +0200
changeset 135030 1646619b5221f80bdeae0b365d0805e6b39de06f
parent 135029 9ec58d112f8841d0f14e39244285ea2436eed6be
child 135049 52c875b9c520f19cbe9ed33f7cc11be689bc8d61
push id29500
push userjandemooij@gmail.com
push dateFri, 14 Jun 2013 07:46:31 +0000
treeherdermozilla-inbound@1646619b5221 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs882111
milestone24.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 882111 part 1 - Some js::Interpret cleanup. r=luke
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -275,16 +275,19 @@ js::ValueToCallable(JSContext *cx, const
         if (callable->isCallable())
             return callable;
     }
 
     ReportIsNotFunction(cx, v, numToSkip, construct);
     return NULL;
 }
 
+static JS_NEVER_INLINE bool
+Interpret(JSContext *cx, StackFrame *entryFrame);
+
 bool
 js::RunScript(JSContext *cx, StackFrame *fp)
 {
     JS_ASSERT(fp == cx->fp());
     RootedScript script(cx, fp->script());
 
     JS_ASSERT_IF(!fp->isGeneratorFrame(), cx->regs().pc == script->code);
     JS_ASSERT_IF(fp->isEvalFrame(), script->isActiveEval);
@@ -337,17 +340,17 @@ js::RunScript(JSContext *cx, StackFrame 
             return false;
         if (status == ion::Method_Compiled) {
             ion::IonExecStatus status = ion::EnterBaselineMethod(cx, fp);
             return !IsErrorStatus(status);
         }
     }
 #endif
 
-    return Interpret(cx, fp) != Interpret_Error;
+    return Interpret(cx, fp);
 }
 
 /*
  * Find a function reference and its 'this' value implicit first parameter
  * under argc arguments on cx's stack, and call the function.  Push missing
  * required arguments, allocate declared local variables, and pop everything
  * when done.  Then push the return value.
  */
@@ -980,23 +983,22 @@ js::IteratorNext(JSContext *cx, HandleOb
             rval.setString(*ni->current());
             ni->incCursor();
             return true;
         }
     }
     return js_IteratorNext(cx, iterobj, rval);
 }
 
-JS_NEVER_INLINE InterpretStatus
-js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode, bool useNewType)
+static JS_NEVER_INLINE bool
+Interpret(JSContext *cx, StackFrame *entryFrame)
 {
     JSAutoResolveFlags rf(cx, RESOLVE_INFER);
 
-    if (interpMode == JSINTERP_NORMAL)
-        gc::MaybeVerifyBarriers(cx, true);
+    gc::MaybeVerifyBarriers(cx, true);
 
     JS_ASSERT(!cx->compartment()->activeAnalysis);
 
 #define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->hasScriptCounts, switchMask == -1)
 
     register int switchMask = 0;
     int switchOp;
     typedef GenericInterruptEnabler<int> InterruptEnabler;
@@ -1055,18 +1057,16 @@ js::Interpret(JSContext *cx, StackFrame 
         DO_OP();                                                              \
     JS_END_MACRO
 
 #define SET_SCRIPT(s)                                                         \
     JS_BEGIN_MACRO                                                            \
         script = (s);                                                         \
         if (script->hasAnyBreakpointsOrStepMode() || script->hasScriptCounts) \
             interrupts.enable();                                              \
-        JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP,                        \
-                     script->hasAnyBreakpointsOrStepMode());                  \
     JS_END_MACRO
 
     /* Repoint cx->regs to a local variable for faster access. */
     FrameRegs regs = cx->regs();
     PreserveRegsGuard interpGuard(cx, regs);
 
     /*
      * Help Debugger find frames running scripts that it has put in
@@ -1123,53 +1123,38 @@ js::Interpret(JSContext *cx, StackFrame 
             goto error;
         }
     }
 #endif
 
     /* State communicated between non-local jumps: */
     bool interpReturnOK;
 
-    /* Don't call the script prologue if executing between Method and Trace JIT. */
-    if (interpMode == JSINTERP_NORMAL) {
-        StackFrame *fp = regs.fp();
-        if (!fp->isGeneratorFrame()) {
-            if (!fp->prologue(cx))
-                goto error;
-        } else {
-            Probes::enterScript(cx, script, script->function(), fp);
-        }
-        if (cx->compartment()->debugMode()) {
-            JSTrapStatus status = ScriptDebugPrologue(cx, fp);
-            switch (status) {
-              case JSTRAP_CONTINUE:
-                break;
-              case JSTRAP_RETURN:
-                interpReturnOK = true;
-                goto forced_return;
-              case JSTRAP_THROW:
-              case JSTRAP_ERROR:
-                goto error;
-              default:
-                JS_NOT_REACHED("bad ScriptDebugPrologue status");
-            }
+    if (!entryFrame->isGeneratorFrame()) {
+        if (!entryFrame->prologue(cx))
+            goto error;
+    } else {
+        Probes::enterScript(cx, script, script->function(), entryFrame);
+    }
+    if (cx->compartment()->debugMode()) {
+        JSTrapStatus status = ScriptDebugPrologue(cx, entryFrame);
+        switch (status) {
+          case JSTRAP_CONTINUE:
+            break;
+          case JSTRAP_RETURN:
+            interpReturnOK = true;
+            goto forced_return;
+          case JSTRAP_THROW:
+          case JSTRAP_ERROR:
+            goto error;
+          default:
+            JS_NOT_REACHED("bad ScriptDebugPrologue status");
         }
     }
 
-    /* The REJOIN mode acts like the normal mode, except the prologue is skipped. */
-    if (interpMode == JSINTERP_REJOIN)
-        interpMode = JSINTERP_NORMAL;
-
-    /*
-     * The RETHROW mode acts like a bailout mode, except that it resume an
-     * exception instead of resuming the script.
-     */
-    if (interpMode == JSINTERP_RETHROW)
-        goto error;
-
     /*
      * It is important that "op" be initialized before calling DO_OP because
      * it is possible for "op" to be specially assigned during the normal
      * processing of an opcode while looping. We rely on DO_NEXT_OP to manage
      * "op" correctly in all other cases.
      */
     JSOp op;
     int32_t len;
@@ -1235,17 +1220,17 @@ js::Interpret(JSContext *cx, StackFrame 
               default:;
             }
             moreInterrupts = true;
         }
 
         if (script->hasAnyBreakpointsOrStepMode())
             moreInterrupts = true;
 
-        if (script->hasBreakpointsAt(regs.pc) && interpMode != JSINTERP_SKIP_TRAP) {
+        if (script->hasBreakpointsAt(regs.pc)) {
             RootedValue rval(cx);
             JSTrapStatus status = Debugger::onTrap(cx, &rval);
             switch (status) {
               case JSTRAP_ERROR:
                 goto error;
               case JSTRAP_RETURN:
                 regs.fp()->setReturnValue(rval);
                 interpReturnOK = true;
@@ -1255,18 +1240,16 @@ js::Interpret(JSContext *cx, StackFrame 
                 goto error;
               default:
                 break;
             }
             JS_ASSERT(status == JSTRAP_CONTINUE);
             JS_ASSERT(rval.isInt32() && rval.toInt32() == op);
         }
 
-        interpMode = JSINTERP_NORMAL;
-
         switchMask = moreInterrupts ? -1 : 0;
         switchOp = int(op);
         goto do_switch;
     }
 
 /* No-ops for ease of decompilation. */
 ADD_EMPTY_CASE(JSOP_NOP)
 ADD_EMPTY_CASE(JSOP_UNUSED125)
@@ -3017,19 +3000,16 @@ END_CASE(JSOP_ARRAYPUSH)
 
         } /* switch (op) */
     } /* for (;;) */
 
   error:
     JS_ASSERT(&cx->regs() == &regs);
     JS_ASSERT(uint32_t(regs.pc - script->code) < script->length);
 
-    /* When rejoining, we must not err before finishing Interpret's prologue. */
-    JS_ASSERT(interpMode != JSINTERP_REJOIN);
-
     if (cx->isExceptionPending()) {
         /* Call debugger throw hooks. */
         if (cx->compartment()->debugMode()) {
             JSTrapStatus status = DebugExceptionUnwind(cx, regs.fp(), regs.pc);
             switch (status) {
               case JSTRAP_ERROR:
                 goto error;
 
@@ -3144,17 +3124,17 @@ END_CASE(JSOP_ARRAYPUSH)
 #ifdef JS_ION
     /*
      * This path is used when it's guaranteed the method can be finished
      * inside the JIT.
      */
   leave_on_safe_point:
 #endif
 
-    return interpReturnOK ? Interpret_Ok : Interpret_Error;
+    return interpReturnOK;
 }
 
 bool
 js::Throw(JSContext *cx, HandleValue v)
 {
     JS_ASSERT(!cx->isExceptionPending());
     cx->setPendingException(v);
     return false;
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -159,41 +159,16 @@ InvokeConstructor(JSContext *cx, const V
 extern bool
 ExecuteKernel(JSContext *cx, HandleScript script, JSObject &scopeChain, const Value &thisv,
               ExecuteType type, AbstractFramePtr evalInFrame, Value *result);
 
 /* Execute a script with the given scopeChain as global code. */
 extern bool
 Execute(JSContext *cx, HandleScript script, JSObject &scopeChain, Value *rval);
 
-/* Flags to toggle js::Interpret() execution. */
-enum InterpMode
-{
-    JSINTERP_NORMAL    = 0, /* interpreter is running normally */
-    JSINTERP_REJOIN    = 1, /* as normal, but the frame has already started */
-    JSINTERP_SKIP_TRAP = 2, /* as REJOIN, but skip trap at first opcode */
-    JSINTERP_BAILOUT   = 3, /* interpreter is running from an Ion bailout */
-    JSINTERP_RETHROW   = 4  /* as BAILOUT, but unwind all frames */
-};
-
-enum InterpretStatus
-{
-    Interpret_Error    = 0, /* interpreter had an error */
-    Interpret_Ok       = 1, /* interpreter executed successfully */
-    Interpret_OSR      = 2  /* when mode=BAILOUT and we should OSR into Ion */
-};
-
-/*
- * Execute the caller-initialized frame for a user-defined script or function
- * pointed to by cx->fp until completion or error.
- */
-extern JS_NEVER_INLINE InterpretStatus
-Interpret(JSContext *cx, StackFrame *stopFp, InterpMode mode = JSINTERP_NORMAL,
-          bool useNewType = false);
-
 extern bool
 RunScript(JSContext *cx, StackFrame *fp);
 
 extern bool
 StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *equal);
 
 extern bool
 LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *equal);