diff options
author | Bill Buzbee <buzbee@google.com> | 2010-01-31 18:53:15 -0800 |
---|---|---|
committer | Bill Buzbee <buzbee@google.com> | 2010-02-01 14:54:40 -0800 |
commit | 06bb83906737fec543c86ab36f450cc62066b58a (patch) | |
tree | a16d6aa6eaff6f8dce79b0ea76826920cc3ea6d1 | |
parent | 4ec8405ab284c5f076589684d533f67815b3b9aa (diff) | |
download | android_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.c | 7 | ||||
-rw-r--r-- | vm/Globals.h | 3 | ||||
-rw-r--r-- | vm/Profile.c | 3 | ||||
-rw-r--r-- | vm/compiler/Compiler.c | 21 | ||||
-rw-r--r-- | vm/compiler/Compiler.h | 1 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Assemble.c | 2 | ||||
-rw-r--r-- | vm/interp/Jit.c | 5 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-portdbg.c | 26 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-portstd.c | 26 | ||||
-rw-r--r-- | vm/mterp/portable/entry.c | 26 |
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 */ |