[INFER] Don't pointlessly generate extra copies of interpreter backedge logic, bug 682477.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 26 Aug 2011 19:58:22 -0700
changeset 76154 53e56c928eaddff935c672804606fb426a07acf6
parent 76153 907c553b698f26dbc36eafe25216e579e9f6e9d4
child 76155 36c307704c7853846ae073b6a49258fab2e01ae8
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
bugs682477
milestone9.0a1
[INFER] Don't pointlessly generate extra copies of interpreter backedge logic, bug 682477.
js/src/jsinterp.cpp
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1891,39 +1891,16 @@ Interpret(JSContext *cx, StackFrame *ent
     JS_BEGIN_MACRO                                                            \
         useMethodJIT = cx->methodJitEnabled &&                                \
             script->getJITStatus(regs.fp()->isConstructing()) != JITScript_Invalid && \
            (interpMode == JSINTERP_NORMAL ||                                  \
             interpMode == JSINTERP_REJOIN ||                                  \
             interpMode == JSINTERP_SKIP_TRAP);                                \
     JS_END_MACRO
 
-#define MONITOR_BRANCH_METHODJIT()                                            \
-    JS_BEGIN_MACRO                                                            \
-        mjit::CompileStatus status =                                          \
-            mjit::CanMethodJITAtBranch(cx, script, regs.fp(), regs.pc);       \
-        if (status == mjit::Compile_Error)                                    \
-            goto error;                                                       \
-        if (status == mjit::Compile_Okay) {                                   \
-            void *ncode =                                                     \
-                script->nativeCodeForPC(regs.fp()->isConstructing(), regs.pc);\
-            mjit::JaegerStatus status =                                       \
-                mjit::JaegerShotAtSafePoint(cx, ncode, true);                 \
-            CHECK_PARTIAL_METHODJIT(status);                                  \
-            interpReturnOK = (status == mjit::Jaeger_Returned);               \
-            if (entryFrame != regs.fp())                                      \
-                goto jit_return;                                              \
-            regs.fp()->setFinishedInInterpreter();                            \
-            goto leave_on_safe_point;                                         \
-        }                                                                     \
-        if (status == mjit::Compile_Abort) {                                  \
-            useMethodJIT = false;                                             \
-        }                                                                     \
-    JS_END_MACRO
-
 #define CHECK_PARTIAL_METHODJIT(status)                                       \
     JS_BEGIN_MACRO                                                            \
         if (status == mjit::Jaeger_Unfinished) {                              \
             op = (JSOp) *regs.pc;                                             \
             RESTORE_INTERP_VARS_CHECK_EXCEPTION();                            \
             DO_OP();                                                          \
         } else if (status == mjit::Jaeger_UnfinishedAtTrap) {                 \
             interpMode = JSINTERP_SKIP_TRAP;                                  \
@@ -1933,18 +1910,16 @@ Interpret(JSContext *cx, StackFrame *ent
             DO_OP();                                                          \
         }                                                                     \
     JS_END_MACRO
 
 #else
 
 #define RESET_USE_METHODJIT() ((void) 0)
 
-#define MONITOR_BRANCH_METHODJIT() ((void) 0)
-
 #endif
 
 #ifdef JS_TRACER
 
 #ifdef MOZ_TRACEVIS
 #if JS_THREADED_INTERP
 #define MONITOR_BRANCH_TRACEVIS                                               \
     JS_BEGIN_MACRO                                                            \
@@ -1974,45 +1949,16 @@ Interpret(JSContext *cx, StackFrame *ent
 #define RESTORE_INTERP_VARS_CHECK_EXCEPTION()                                 \
     JS_BEGIN_MACRO                                                            \
         RESTORE_INTERP_VARS();                                                \
         if (cx->isExceptionPending())                                         \
             goto error;                                                       \
         CHECK_INTERRUPT_HANDLER();                                            \
     JS_END_MACRO
 
-#define MONITOR_BRANCH()                                                      \
-    JS_BEGIN_MACRO                                                            \
-        if (TRACING_ENABLED(cx)) {                                            \
-            if (!TRACE_RECORDER(cx) && !TRACE_PROFILER(cx) && useMethodJIT) { \
-                MONITOR_BRANCH_METHODJIT();                                   \
-            } else {                                                          \
-                MonitorResult r = MonitorLoopEdge(cx, interpMode);            \
-                if (r == MONITOR_RECORDING) {                                 \
-                    JS_ASSERT(TRACE_RECORDER(cx));                            \
-                    JS_ASSERT(!TRACE_PROFILER(cx));                           \
-                    MONITOR_BRANCH_TRACEVIS;                                  \
-                    ENABLE_INTERRUPTS();                                      \
-                    CLEAR_LEAVE_ON_TRACE_POINT();                             \
-                }                                                             \
-                JS_ASSERT_IF(cx->isExceptionPending(), r == MONITOR_ERROR);   \
-                RESTORE_INTERP_VARS_CHECK_EXCEPTION();                        \
-            }                                                                 \
-        } else {                                                              \
-            MONITOR_BRANCH_METHODJIT();                                       \
-        }                                                                     \
-    JS_END_MACRO
-
-#else /* !JS_TRACER */
-
-#define MONITOR_BRANCH()                                                      \
-    JS_BEGIN_MACRO                                                            \
-        MONITOR_BRANCH_METHODJIT();                                           \
-    JS_END_MACRO
-
 #endif /* !JS_TRACER */
 
     /*
      * Prepare to call a user-supplied branch handler, and abort the script
      * if it returns false.
      */
 #define CHECK_BRANCH()                                                        \
     JS_BEGIN_MACRO                                                            \
@@ -2036,28 +1982,18 @@ Interpret(JSContext *cx, StackFrame *ent
 #else
 # define LEAVE_ON_SAFE_POINT() /* nop */
 #endif
 
 #define BRANCH(n)                                                             \
     JS_BEGIN_MACRO                                                            \
         regs.pc += (n);                                                       \
         op = (JSOp) *regs.pc;                                                 \
-        if ((n) <= 0) {                                                       \
-            CHECK_BRANCH();                                                   \
-            if (op == JSOP_NOTRACE) {                                         \
-                if (TRACE_RECORDER(cx) || TRACE_PROFILER(cx)) {               \
-                    MONITOR_BRANCH();                                         \
-                    op = (JSOp) *regs.pc;                                     \
-                }                                                             \
-            } else if (op == JSOP_TRACE) {                                    \
-                MONITOR_BRANCH();                                             \
-                op = (JSOp) *regs.pc;                                         \
-            }                                                                 \
-        }                                                                     \
+        if ((n) <= 0)                                                         \
+            goto check_backedge;                                              \
         LEAVE_ON_SAFE_POINT();                                                \
         DO_OP();                                                              \
     JS_END_MACRO
 
 #define SET_SCRIPT(s)                                                         \
     JS_BEGIN_MACRO                                                            \
         script = (s);                                                         \
         if (script->stepModeEnabled())                                        \
@@ -2366,16 +2302,63 @@ ADD_EMPTY_CASE(JSOP_STARTXMLEXPR)
 ADD_EMPTY_CASE(JSOP_NULLBLOCKCHAIN)
 END_EMPTY_CASES
 
 BEGIN_CASE(JSOP_TRACE)
 BEGIN_CASE(JSOP_NOTRACE)
     LEAVE_ON_SAFE_POINT();
 END_CASE(JSOP_TRACE)
 
+check_backedge:
+{
+    CHECK_BRANCH();
+    if (op != JSOP_NOTRACE && op != JSOP_TRACE)
+        DO_OP();
+
+#ifdef JS_TRACER
+    if (TRACING_ENABLED(cx) && (TRACE_RECORDER(cx) || TRACE_PROFILER(cx) || (op == JSOP_TRACE && !useMethodJIT))) {
+        MonitorResult r = MonitorLoopEdge(cx, interpMode);
+        if (r == MONITOR_RECORDING) {
+            JS_ASSERT(TRACE_RECORDER(cx));
+            JS_ASSERT(!TRACE_PROFILER(cx));
+            MONITOR_BRANCH_TRACEVIS;
+            ENABLE_INTERRUPTS();
+            CLEAR_LEAVE_ON_TRACE_POINT();
+        }
+        JS_ASSERT_IF(cx->isExceptionPending(), r == MONITOR_ERROR);
+        RESTORE_INTERP_VARS_CHECK_EXCEPTION();
+        op = (JSOp) *regs.pc;
+        DO_OP();
+    }
+#endif /* JS_TRACER */
+
+#ifdef JS_METHODJIT
+    mjit::CompileStatus status =
+        mjit::CanMethodJITAtBranch(cx, script, regs.fp(), regs.pc);
+    if (status == mjit::Compile_Error)
+        goto error;
+    if (status == mjit::Compile_Okay) {
+        void *ncode =
+            script->nativeCodeForPC(regs.fp()->isConstructing(), regs.pc);
+        mjit::JaegerStatus status =
+            mjit::JaegerShotAtSafePoint(cx, ncode, true);
+        CHECK_PARTIAL_METHODJIT(status);
+        interpReturnOK = (status == mjit::Jaeger_Returned);
+        if (entryFrame != regs.fp())
+            goto jit_return;
+        regs.fp()->setFinishedInInterpreter();
+        goto leave_on_safe_point;
+    }
+    if (status == mjit::Compile_Abort)
+        useMethodJIT = false;
+#endif /* JS_METHODJIT */
+
+    DO_OP();
+}
+
 /* ADD_EMPTY_CASE is not used here as JSOP_LINENO_LENGTH == 3. */
 BEGIN_CASE(JSOP_LINENO)
 END_CASE(JSOP_LINENO)
 
 BEGIN_CASE(JSOP_BLOCKCHAIN)
 END_CASE(JSOP_BLOCKCHAIN)
 
 BEGIN_CASE(JSOP_PUSH)