summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Buzbee <buzbee@google.com>2010-01-31 18:53:15 -0800
committerBill Buzbee <buzbee@google.com>2010-02-01 14:54:40 -0800
commit06bb83906737fec543c86ab36f450cc62066b58a (patch)
treea16d6aa6eaff6f8dce79b0ea76826920cc3ea6d1
parent4ec8405ab284c5f076589684d533f67815b3b9aa (diff)
downloadandroid_dalvik-06bb83906737fec543c86ab36f450cc62066b58a.tar.gz
android_dalvik-06bb83906737fec543c86ab36f450cc62066b58a.tar.bz2
android_dalvik-06bb83906737fec543c86ab36f450cc62066b58a.zip
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.
-rw-r--r--vm/Debugger.c7
-rw-r--r--vm/Globals.h3
-rw-r--r--vm/Profile.c3
-rw-r--r--vm/compiler/Compiler.c21
-rw-r--r--vm/compiler/Compiler.h1
-rw-r--r--vm/compiler/codegen/arm/Assemble.c2
-rw-r--r--vm/interp/Jit.c5
-rw-r--r--vm/mterp/out/InterpC-portdbg.c26
-rw-r--r--vm/mterp/out/InterpC-portstd.c26
-rw-r--r--vm/mterp/portable/entry.c26
10 files changed, 71 insertions, 49 deletions
diff --git a/vm/Debugger.c b/vm/Debugger.c
index be6fa6621..2f57046b7 100644
--- a/vm/Debugger.c
+++ b/vm/Debugger.c
@@ -418,6 +418,9 @@ void dvmDbgActive(void)
LOGI("Debugger is active\n");
dvmInitBreakpoints();
gDvm.debuggerActive = true;
+#if defined(WITH_JIT)
+ dvmCompilerStateRefresh();
+#endif
}
/*
@@ -445,6 +448,9 @@ void dvmDbgDisconnected(void)
dvmHashTableClear(gDvm.dbgRegistry);
dvmHashTableUnlock(gDvm.dbgRegistry);
+#if defined(WITH_JIT)
+ dvmCompilerStateRefresh();
+#endif
}
/*
@@ -3045,4 +3051,3 @@ void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt)
dvmJdwpDdmSendChunkV(gDvm.jdwpState, type, iov, iovcnt);
}
-
diff --git a/vm/Globals.h b/vm/Globals.h
index bac28f69b..6d9455e98 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -685,6 +685,9 @@ struct DvmJitGlobals {
/* 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 dcfad71fe..b079988a0 100644
--- a/vm/Profile.c
+++ b/vm/Profile.c
@@ -230,6 +230,9 @@ static void updateActiveProfilers(int count)
} 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 39b42cd82..dfcd88f34 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -344,6 +344,7 @@ bool compilerThreadStartup(void)
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 @@ void dvmCompilerShutdown(void)
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 71eed5da1..6b4d41424 100644
--- a/vm/compiler/Compiler.h
+++ b/vm/compiler/Compiler.h
@@ -165,6 +165,7 @@ char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
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 6a59c7ea1..998c95585 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -1328,7 +1328,7 @@ void* dvmJitChain(void* tgtAddr, u4* branchAddr)
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 34a7736d6..6adbf3d97 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -776,6 +776,7 @@ int dvmCheckJit(const u2* pc, Thread* self, InterpState* interpState)
interpState->entryPoint = kInterpEntryResume;
switchInterp = !debugOrProfile;
break;
+ case kJitTSelectRequest:
case kJitTSelectAbort:
#if defined(SHOW_TRACE)
LOGD("TraceGen: trace abort");
@@ -833,7 +834,8 @@ JitEntry *dvmFindJitEntry(const u2* pc)
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 @@ s8 dvmJitf2l(float f)
return (s8)f;
}
-
#endif /* WITH_JIT */
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 5b984e32e..5abdff577 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -1477,25 +1477,21 @@ bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
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)) {
- interpState->nextMode = INTERP_STD;
- //LOGD("** something wrong, exiting\n");
- return true;
- }
-#else
- if (interpState->jitState != kJitSelfVerification &&
- 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;
}
-#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 bfda6713d..8b30bd6fc 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1217,25 +1217,21 @@ bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
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)) {
- interpState->nextMode = INTERP_STD;
- //LOGD("** something wrong, exiting\n");
- return true;
- }
-#else
- if (interpState->jitState != kJitSelfVerification &&
- 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;
}
-#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 4a6ed4ee3..8ea4bdc75 100644
--- a/vm/mterp/portable/entry.c
+++ b/vm/mterp/portable/entry.c
@@ -42,25 +42,21 @@ bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
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)) {
- interpState->nextMode = INTERP_STD;
- //LOGD("** something wrong, exiting\n");
- return true;
- }
-#else
- if (interpState->jitState != kJitSelfVerification &&
- 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;
}
-#endif /* WITH_SELF_VERIFICATION */
#endif /* INTERP_TYPE == INTERP_DBG */
#endif /* WITH_JIT */