Bug 910782 - SpiderMonkey: Wrap several gotos in macros. r=luke
authorDan Gohman <sunfish@google.com>
Mon, 28 Oct 2013 10:32:49 -0700
changeset 152509 0f80724faca52d1e45ff58ea5e7c9f018301c999
parent 152508 0af6a04d58315640a10157bf1ff57313188c6a31
child 152510 88e167fa6f4b14fbf5e079a7b19b3658b302b669
push id35550
push usersunfish@google.com
push dateMon, 28 Oct 2013 17:37:09 +0000
treeherdermozilla-inbound@9540960e67a2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs910782
milestone27.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 910782 - SpiderMonkey: Wrap several gotos in macros. r=luke
js/src/vm/Interpreter.cpp
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1233,26 +1233,28 @@ Interpret(JSContext *cx, RunState &state
      */
     static_assert(EnableInterruptsPseudoOpcode >= JSOP_LIMIT,
                   "EnableInterruptsPseudoOpcode must be greater than any opcode");
     static_assert(EnableInterruptsPseudoOpcode == jsbytecode(-1),
                   "EnableInterruptsPseudoOpcode must be the maximum jsbytecode value");
     jsbytecode switchMask = 0;
     jsbytecode switchOp;
 
+#define ADVANCE_AND_DO_OP() goto advanceAndDoOp
 #define DO_OP()            goto do_op
+#define DO_SWITCH()        goto do_switch
 
 #define BEGIN_CASE(OP)     case OP:
 #define END_CASE(OP)                                                          \
     JS_BEGIN_MACRO                                                            \
         len = OP##_LENGTH;                                                    \
-        goto advanceAndDoOp;                                                  \
+        ADVANCE_AND_DO_OP();                                                  \
     JS_END_MACRO;
 
-#define END_VARLEN_CASE    goto advanceAndDoOp;
+#define END_VARLEN_CASE    ADVANCE_AND_DO_OP();
 
 #define LOAD_DOUBLE(PCOFF, dbl)                                               \
     ((dbl) = script->getConst(GET_UINT32_INDEX(regs.pc + (PCOFF))).toDouble())
 
     /*
      * Prepare to call a user-supplied branch handler, and abort the script
      * if it returns false.
      */
@@ -1362,18 +1364,18 @@ Interpret(JSContext *cx, RunState &state
           default:
             MOZ_ASSUME_UNREACHABLE("bad ScriptDebugPrologue status");
         }
     }
 
     /*
      * 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 |advanceAndDoOp:| to
-     * manage "op" correctly in all other cases.
+     * processing of an opcode while looping. We rely on |ADVANCE_AND_DO_OP()|
+     * to manage "op" correctly in all other cases.
      */
     JSOp op;
     int32_t len;
     len = 0;
 
     if (rt->profilingScripts || cx->runtime()->debugHooks.interruptHook)
         switchMask = EnableInterruptsPseudoOpcode; /* Enable interrupts. */
 
@@ -1451,17 +1453,17 @@ BEGIN_CASE(EnableInterruptsPseudoOpcode)
         JS_ASSERT(status == JSTRAP_CONTINUE);
         JS_ASSERT(rval.isInt32() && rval.toInt32() == op);
     }
 
     JS_ASSERT(switchMask == EnableInterruptsPseudoOpcode);
     switchMask = moreInterrupts ? EnableInterruptsPseudoOpcode : 0;
 
     switchOp = jsbytecode(op);
-    goto do_switch;
+    DO_SWITCH();
 }
 
 /* Various 1-byte no-ops. */
 BEGIN_CASE(JSOP_NOP)
 BEGIN_CASE(JSOP_UNUSED125)
 BEGIN_CASE(JSOP_UNUSED126)
 BEGIN_CASE(JSOP_UNUSED132)
 BEGIN_CASE(JSOP_UNUSED148)
@@ -1500,17 +1502,17 @@ BEGIN_CASE(JSOP_UNUSED220)
 BEGIN_CASE(JSOP_UNUSED221)
 BEGIN_CASE(JSOP_UNUSED222)
 BEGIN_CASE(JSOP_UNUSED223)
 BEGIN_CASE(JSOP_CONDSWITCH)
 BEGIN_CASE(JSOP_TRY)
 {
     JS_ASSERT(js_CodeSpec[op].length == 1);
     len = 1;
-    goto advanceAndDoOp;
+    ADVANCE_AND_DO_OP();
 }
 
 BEGIN_CASE(JSOP_LOOPHEAD)
 END_CASE(JSOP_LOOPHEAD)
 
 BEGIN_CASE(JSOP_LABEL)
 END_CASE(JSOP_LABEL)
 
@@ -1637,17 +1639,17 @@ BEGIN_CASE(JSOP_STOP)
 
         JS_ASSERT(js_CodeSpec[*regs.pc].format & JOF_INVOKE);
 
         /* Resume execution in the calling frame. */
         if (JS_LIKELY(interpReturnOK)) {
             TypeScript::Monitor(cx, script, regs.pc, regs.sp[-1]);
 
             len = JSOP_CALL_LENGTH;
-            goto advanceAndDoOp;
+            ADVANCE_AND_DO_OP();
         }
 
         /* Increment pc so that |sp - fp->slots == ReconstructStackDepth(pc)|. */
         regs.pc += JSOP_CALL_LENGTH;
         goto error;
     } else {
         JS_ASSERT(regs.stackDepth() == 0);
     }
@@ -1681,27 +1683,27 @@ BEGIN_CASE(JSOP_IFNE)
 }
 END_CASE(JSOP_IFNE)
 
 BEGIN_CASE(JSOP_OR)
 {
     bool cond = ToBooleanOp(regs);
     if (cond) {
         len = GET_JUMP_OFFSET(regs.pc);
-        goto advanceAndDoOp;
+        ADVANCE_AND_DO_OP();
     }
 }
 END_CASE(JSOP_OR)
 
 BEGIN_CASE(JSOP_AND)
 {
     bool cond = ToBooleanOp(regs);
     if (!cond) {
         len = GET_JUMP_OFFSET(regs.pc);
-        goto advanceAndDoOp;
+        ADVANCE_AND_DO_OP();
     }
 }
 END_CASE(JSOP_AND)
 
 #define FETCH_ELEMENT_ID(n, id)                                               \
     JS_BEGIN_MACRO                                                            \
         if (!ValueToId<CanGC>(cx, regs.stackHandleAt(n), &(id)))              \
             goto error;                                                       \
@@ -1713,17 +1715,17 @@ END_CASE(JSOP_AND)
         unsigned diff_ = (unsigned) GET_UINT8(regs.pc) - (unsigned) JSOP_IFEQ;\
         if (diff_ <= 1) {                                                     \
             regs.sp -= (spdec);                                               \
             if ((cond) == (diff_ != 0)) {                                     \
                 ++regs.pc;                                                    \
                 BRANCH(GET_JUMP_OFFSET(regs.pc));                             \
             }                                                                 \
             len = 1 + JSOP_IFEQ_LENGTH;                                       \
-            goto advanceAndDoOp;                                              \
+            ADVANCE_AND_DO_OP();                                              \
         }                                                                     \
     JS_END_MACRO
 
 BEGIN_CASE(JSOP_IN)
 {
     HandleValue rref = regs.stackHandleAt(-1);
     if (!rref.isObject()) {
         js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NullPtr());
@@ -2464,17 +2466,17 @@ BEGIN_CASE(JSOP_FUNCALL)
         } else {
             if (!Invoke(cx, args))
                 goto error;
         }
         Value *newsp = args.spAfterCall();
         TypeScript::Monitor(cx, script, regs.pc, newsp[-1]);
         regs.sp = newsp;
         len = JSOP_CALL_LENGTH;
-        goto advanceAndDoOp;
+        ADVANCE_AND_DO_OP();
     }
 
     InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
     bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
 
     TypeMonitorCall(cx, args, construct);
 
 #ifdef JS_ION
@@ -2684,17 +2686,17 @@ BEGIN_CASE(JSOP_TABLESWITCH)
     const Value &rref = *--regs.sp;
     int32_t i;
     if (rref.isInt32()) {
         i = rref.toInt32();
     } else {
         double d;
         /* Don't use mozilla::DoubleIsInt32; treat -0 (double) as 0. */
         if (!rref.isDouble() || (d = rref.toDouble()) != (i = int32_t(rref.toDouble())))
-            goto advanceAndDoOp;
+            ADVANCE_AND_DO_OP();
     }
 
     pc2 += JUMP_OFFSET_LEN;
     int32_t low = GET_JUMP_OFFSET(pc2);
     pc2 += JUMP_OFFSET_LEN;
     int32_t high = GET_JUMP_OFFSET(pc2);
 
     i -= low;
@@ -3223,17 +3225,17 @@ BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
         /* Pop the block's slots maintaining the topmost expr. */
         Value *vp = &regs.sp[-1];
         regs.sp -= GET_UINT16(regs.pc);
         JS_ASSERT(regs.stackDepth() == blockDepth + 1);
         regs.sp[-1] = *vp;
     } else {
         /* Another op will pop; nothing to do here. */
         len = JSOP_LEAVEFORLETIN_LENGTH;
-        goto advanceAndDoOp;
+        ADVANCE_AND_DO_OP();
     }
 }
 END_CASE(JSOP_LEAVEBLOCK)
 
 BEGIN_CASE(JSOP_GENERATOR)
 {
     JS_ASSERT(!cx->isExceptionPending());
     regs.fp()->initGeneratorFrame();
@@ -3336,28 +3338,28 @@ default:
                     break;
 
                 /*
                  * Don't clear exceptions to save cx->exception from GC
                  * until it is pushed to the stack via [exception] in the
                  * catch block.
                  */
                 len = 0;
-                goto advanceAndDoOp;
+                ADVANCE_AND_DO_OP();
 
               case JSTRY_FINALLY:
                 /*
                  * Push (true, exception) pair for finally to indicate that
                  * [retsub] should rethrow the exception.
                  */
                 PUSH_BOOLEAN(true);
                 PUSH_COPY(cx->getPendingException());
                 cx->clearPendingException();
                 len = 0;
-                goto advanceAndDoOp;
+                ADVANCE_AND_DO_OP();
 
               case JSTRY_ITER: {
                 /* This is similar to JSOP_ENDITER in the interpreter loop. */
                 JS_ASSERT(JSOp(*regs.pc) == JSOP_ENDITER);
                 RootedObject &obj = rootObject0;
                 obj = &regs.sp[-1].toObject();
                 bool ok = UnwindIteratorForException(cx, obj);
                 regs.sp -= 1;