Jit: MethodTrace + Jit fix

Add checks for debug & trace mode to avoid re-entering Jit'd code.
This is the conversative solution - we'll eventually want the Jit
to integrate support for tracing and debug into Jit'd code.
diff --git a/vm/Debugger.c b/vm/Debugger.c
index be6fa66..2f57046 100644
--- a/vm/Debugger.c
+++ b/vm/Debugger.c
@@ -418,6 +418,9 @@
     LOGI("Debugger is active\n");
     dvmInitBreakpoints();
     gDvm.debuggerActive = true;
+#if defined(WITH_JIT)
+    dvmCompilerStateRefresh();
+#endif
 }
 
 /*
@@ -445,6 +448,9 @@
 
     dvmHashTableClear(gDvm.dbgRegistry);
     dvmHashTableUnlock(gDvm.dbgRegistry);
+#if defined(WITH_JIT)
+    dvmCompilerStateRefresh();
+#endif
 }
 
 /*
@@ -3045,4 +3051,3 @@
 
     dvmJdwpDdmSendChunkV(gDvm.jdwpState, type, iov, iovcnt);
 }
-
diff --git a/vm/Globals.h b/vm/Globals.h
index bac28f6..6d9455e 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -685,6 +685,9 @@
     /* Array of profile threshold counters */
     unsigned char *pProfTable;
 
+    /* Copy of pProfTable used for temporarily disabling the Jit */
+    unsigned char *pProfTableCopy;
+
     /* Size of JIT hash table in entries.  Must be a power of 2 */
     unsigned int jitTableSize;
 
diff --git a/vm/Profile.c b/vm/Profile.c
index dcfad71..b079988 100644
--- a/vm/Profile.c
+++ b/vm/Profile.c
@@ -230,6 +230,9 @@
     } while (!ATOMIC_CMP_SWAP(&gDvm.activeProfilers, oldValue, newValue));
 
     LOGD("+++ active profiler count now %d\n", newValue);
+#if defined(WITH_JIT)
+    dvmCompilerStateRefresh();
+#endif
 }
 
 
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index 39b42cd..dfcd88f 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -344,6 +344,7 @@
     gDvmJit.compilerHighWater =
         COMPILER_WORK_QUEUE_SIZE - (COMPILER_WORK_QUEUE_SIZE/4);
     gDvmJit.pProfTable = pJitProfTable;
+    gDvmJit.pProfTableCopy = pJitProfTable;
     dvmUnlockMutex(&gDvmJit.tableLock);
 
     /* Signal running threads to refresh their cached pJitTable pointers */
@@ -511,3 +512,23 @@
             LOGD("Compiler thread has shut down\n");
     }
 }
+
+
+void dvmCompilerStateRefresh()
+{
+    bool jitActive;
+    bool jitActivate;
+
+    dvmLockMutex(&gDvmJit.tableLock);
+    jitActive = gDvmJit.pProfTable != NULL;
+    jitActivate = !(gDvm.debuggerActive || (gDvm.activeProfilers > 0));
+
+    if (jitActivate && !jitActive) {
+        gDvmJit.pProfTable = gDvmJit.pProfTableCopy;
+        dvmUnlockMutex(&gDvmJit.tableLock);
+    } else if (!jitActivate && jitActive) {
+        gDvmJit.pProfTable = NULL;
+        dvmUnlockMutex(&gDvmJit.tableLock);
+        dvmJitUnchainAll();
+    }
+}
diff --git a/vm/compiler/Compiler.h b/vm/compiler/Compiler.h
index 71eed5d..6b4d414 100644
--- a/vm/compiler/Compiler.h
+++ b/vm/compiler/Compiler.h
@@ -165,6 +165,7 @@
                               struct SSARepresentation *ssaRep);
 void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
                 void (*func)(struct CompilationUnit *, struct BasicBlock *));
+void dvmCompilerStateRefresh(void);
 JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc);
 
 #endif /* _DALVIK_VM_COMPILER */
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 6a59c7e..998c955 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -1328,7 +1328,7 @@
     u4 newInst;
     bool thumbTarget;
 
-    if (gDvm.sumThreadSuspendCount == 0) {
+    if ((gDvmJit.pProfTable != NULL) && gDvm.sumThreadSuspendCount == 0) {
         assert((branchOffset >= -(1<<22)) && (branchOffset <= ((1<<22)-2)));
 
         gDvmJit.translationChains++;
diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c
index 34a7736..6adbf3d 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -776,6 +776,7 @@
             interpState->entryPoint = kInterpEntryResume;
             switchInterp = !debugOrProfile;
             break;
+        case kJitTSelectRequest:
         case kJitTSelectAbort:
 #if defined(SHOW_TRACE)
             LOGD("TraceGen:  trace abort");
@@ -833,7 +834,8 @@
 void* dvmJitGetCodeAddr(const u2* dPC)
 {
     int idx = dvmJitHash(dPC);
-    const u2* npc = gDvmJit.pJitEntryTable[idx].dPC;
+    const u2* npc = (gDvmJit.pProfTable == NULL) ? NULL :
+                     gDvmJit.pJitEntryTable[idx].dPC;
 
     if (npc != NULL) {
         if (npc == dPC) {
@@ -1130,5 +1132,4 @@
         return (s8)f;
 }
 
-
 #endif /* WITH_JIT */
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 5b984e3..5abdff5 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -1477,25 +1477,21 @@
          interpState->pc,
          interpState->method->name);
 #endif
-
 #if INTERP_TYPE == INTERP_DBG
-    /* Check to see if we've got a trace selection request.  If we do,
-     * but something is amiss, revert to the fast interpreter.
-     */
-#if !defined(WITH_SELF_VERIFICATION)
-    if (dvmJitCheckTraceRequest(self,interpState)) {
+    /* Check to see if we've got a trace selection request. */
+    if (
+#if defined(WITH_SELF_VERIFICATION)
+         (interpState->jitState != kJitSelfVerification) &&
+#endif
+         !gDvm.debuggerActive &&
+#if defined(WITH_PROFILER)
+         (gDvm.activeProfilers == 0) &&
+#endif
+         dvmJitCheckTraceRequest(self, interpState)) {
         interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
+        //LOGD("Invalid trace request, exiting\n");
         return true;
     }
-#else
-    if (interpState->jitState != kJitSelfVerification &&
-        dvmJitCheckTraceRequest(self,interpState)) {
-        interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
-        return true;
-    }
-#endif /* WITH_SELF_VERIFICATION */
 #endif /* INTERP_TYPE == INTERP_DBG */
 #endif /* WITH_JIT */
 
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index bfda671..8b30bd6 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1217,25 +1217,21 @@
          interpState->pc,
          interpState->method->name);
 #endif
-
 #if INTERP_TYPE == INTERP_DBG
-    /* Check to see if we've got a trace selection request.  If we do,
-     * but something is amiss, revert to the fast interpreter.
-     */
-#if !defined(WITH_SELF_VERIFICATION)
-    if (dvmJitCheckTraceRequest(self,interpState)) {
+    /* Check to see if we've got a trace selection request. */
+    if (
+#if defined(WITH_SELF_VERIFICATION)
+         (interpState->jitState != kJitSelfVerification) &&
+#endif
+         !gDvm.debuggerActive &&
+#if defined(WITH_PROFILER)
+         (gDvm.activeProfilers == 0) &&
+#endif
+         dvmJitCheckTraceRequest(self, interpState)) {
         interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
+        //LOGD("Invalid trace request, exiting\n");
         return true;
     }
-#else
-    if (interpState->jitState != kJitSelfVerification &&
-        dvmJitCheckTraceRequest(self,interpState)) {
-        interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
-        return true;
-    }
-#endif /* WITH_SELF_VERIFICATION */
 #endif /* INTERP_TYPE == INTERP_DBG */
 #endif /* WITH_JIT */
 
diff --git a/vm/mterp/portable/entry.c b/vm/mterp/portable/entry.c
index 4a6ed4e..8ea4bdc 100644
--- a/vm/mterp/portable/entry.c
+++ b/vm/mterp/portable/entry.c
@@ -42,25 +42,21 @@
          interpState->pc,
          interpState->method->name);
 #endif
-
 #if INTERP_TYPE == INTERP_DBG
-    /* Check to see if we've got a trace selection request.  If we do,
-     * but something is amiss, revert to the fast interpreter.
-     */
-#if !defined(WITH_SELF_VERIFICATION)
-    if (dvmJitCheckTraceRequest(self,interpState)) {
+    /* Check to see if we've got a trace selection request. */
+    if (
+#if defined(WITH_SELF_VERIFICATION)
+         (interpState->jitState != kJitSelfVerification) &&
+#endif
+         !gDvm.debuggerActive &&
+#if defined(WITH_PROFILER)
+         (gDvm.activeProfilers == 0) &&
+#endif
+         dvmJitCheckTraceRequest(self, interpState)) {
         interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
+        //LOGD("Invalid trace request, exiting\n");
         return true;
     }
-#else
-    if (interpState->jitState != kJitSelfVerification &&
-        dvmJitCheckTraceRequest(self,interpState)) {
-        interpState->nextMode = INTERP_STD;
-        //LOGD("** something wrong, exiting\n");
-        return true;
-    }
-#endif /* WITH_SELF_VERIFICATION */
 #endif /* INTERP_TYPE == INTERP_DBG */
 #endif /* WITH_JIT */