diff options
author | buzbee <buzbee@google.com> | 2011-01-19 15:31:15 -0800 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2011-01-19 16:39:41 -0800 |
commit | 18fba346582c08d81aa96d9508c0e935bad5f36f (patch) | |
tree | f69072fa267c06e5a3036c76fc37ba1df9c88f67 /vm/compiler/Compiler.c | |
parent | 9238eb89ea5f0564047a2a2f040a2229d42f6f63 (diff) | |
download | android_dalvik-18fba346582c08d81aa96d9508c0e935bad5f36f.tar.gz android_dalvik-18fba346582c08d81aa96d9508c0e935bad5f36f.tar.bz2 android_dalvik-18fba346582c08d81aa96d9508c0e935bad5f36f.zip |
Support traceview-style profiling in all builds
This change builds on an earlier bccheng change that allowed JIT'd code
to avoid reverting to the debug portable interpeter when doing traceview-style
method profiling. That CL introduced a new traceview build (libdvm_traceview)
because the performance delta was too great to enable the capability for
all builds.
In this CL, we remove the libdvm_traceview build and provide full-speed
method tracing in all builds. This is done by introducing "_PROF"
versions of invoke and return templates used by the JIT. Normally, these
templates are not used, and performace in unaffected. However, when method
profiling is enabled, all existing translation are purged and new translations
are created using the _PROF templates. These templates introduce a
smallish performance penalty above and beyond the actual tracing cost, but
again are only used when tracing has been enabled.
Strictly speaking, there is a slight burden that is placed on invokes and
returns in the non-tracing case - on the order of an additional 3 or 4
cycles per invoke/return. Those operations are already heavyweight enough
that I was unable to measure the added cost in benchmarks.
Change-Id: Ic09baf4249f1e716e136a65458f4e06cea35fc18
Diffstat (limited to 'vm/compiler/Compiler.c')
-rw-r--r-- | vm/compiler/Compiler.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c index 886b1f11a..a1e3d0e8d 100644 --- a/vm/compiler/Compiler.c +++ b/vm/compiler/Compiler.c @@ -99,6 +99,7 @@ bool dvmCompilerWorkEnqueue(const u2 *pc, WorkOrderKind kind, void* info) newOrder->result.codeAddress = NULL; newOrder->result.discardResult = (kind == kWorkOrderTraceDebug) ? true : false; + newOrder->result.cacheVersion = gDvmJit.cacheVersion; newOrder->result.requestingThread = dvmThreadSelf(); gDvmJit.compilerWorkEnqueueIndex++; @@ -264,6 +265,9 @@ static void resetCodeCache(void) /* Lock the mutex to clean up the work queue */ dvmLockMutex(&gDvmJit.compilerLock); + /* Update the translation cache version */ + gDvmJit.cacheVersion++; + /* Drain the work queue to free the work orders */ while (workQueueLength()) { CompilerWorkOrder work = workDequeue(); @@ -749,6 +753,33 @@ void dvmCompilerStateRefresh() return; } + /* + * On the first enabling of method tracing, switch the compiler + * into a mode that includes trace support for invokes and returns. + * If there are any existing translations, flush them. NOTE: we + * can't blindly flush the translation cache because this code + * may be executed before the compiler thread has finished + * initialization. + */ + if ((gDvm.interpBreak & kSubModeMethodTrace) && + !gDvmJit.methodTraceSupport) { + bool resetRequired; + /* + * compilerLock will prevent new compilations from being + * installed while we are working. + */ + dvmLockMutex(&gDvmJit.compilerLock); + gDvmJit.cacheVersion++; // invalidate compilations in flight + gDvmJit.methodTraceSupport = true; + resetRequired = (gDvmJit.numCompilations != 0); + dvmUnlockMutex(&gDvmJit.compilerLock); + if (resetRequired) { + dvmSuspendAllThreads(SUSPEND_FOR_CC_RESET); + resetCodeCache(); + dvmResumeAllThreads(SUSPEND_FOR_CC_RESET); + } + } + dvmLockMutex(&gDvmJit.tableLock); jitActive = gDvmJit.pProfTable != NULL; jitActivate = !dvmDebuggerOrProfilerActive(); |