void dvmCompilerUpdateGlobalState() { bool jitActive; bool jitActivate; bool needUnchain = false; /* * The tableLock might not be initialized yet by the compiler thread if * debugger is attached from the very beginning of the VM launch. If * pProfTableCopy is NULL, the lock is not initialized yet and we don't * need to refresh anything either. */ if (gDvmJit.pProfTableCopy == NULL) { 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.activeProfilers != 0) && !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(); if (jitActivate && !jitActive) { gDvmJit.pProfTable = gDvmJit.pProfTableCopy; } else if (!jitActivate && jitActive) { gDvmJit.pProfTable = NULL; needUnchain = true; } dvmUnlockMutex(&gDvmJit.tableLock); if (needUnchain) dvmJitUnchainAll(); // Make sure all threads have current values dvmJitUpdateThreadStateAll(); }
/** * 关闭Jit编译器 */ void dvmCompilerShutdown(void) { void *threadReturn; /* Disable new translation requests */ /* 关闭新的编译请求 */ gDvmJit.pProfTable = NULL; gDvmJit.pProfTableCopy = NULL; dvmJitUpdateThreadStateAll(); /* 更新所有线程状态 */ /* * 以下代码应该是检测在虚拟机关闭之前等待所有编译工作队列完成 * dvmCompilerDumpStats()函数应该会更新所有工作队列的当前状态 * gDvmJit.compilerQueueLength会随着这个函数进行更新,这个常数 * 即是当前工作队列的数量。 */ if (gDvm.verboseShutdown || gDvmJit.profileMode == kTraceProfilingContinuous) { dvmCompilerDumpStats(); while (gDvmJit.compilerQueueLength) sleep(5); } /* 如果编译器工作线程存在 */ if (gDvmJit.compilerHandle) { gDvmJit.haltCompilerThread = true; /* 设置关闭标志为true */ /* 发送关闭信号 */ dvmLockMutex(&gDvmJit.compilerLock); pthread_cond_signal(&gDvmJit.compilerQueueActivity); dvmUnlockMutex(&gDvmJit.compilerLock); /* 关闭compilerThreadStart线程 */ if (pthread_join(gDvmJit.compilerHandle, &threadReturn) != 0) ALOGW("Compiler thread join failed"); else if (gDvm.verboseShutdown) ALOGD("Compiler thread has shut down"); } /* Break loops within the translation cache */ dvmJitUnchainAll(); /* * NOTE: our current implementatation doesn't allow for the compiler * thread to be restarted after it exits here. We aren't freeing * the JitTable or the ProfTable because threads which still may be * running or in the process of shutting down may hold references to * * them. */ }
/* * Respond to a SIGUSR2 by dumping some JIT stats and possibly resetting * the code cache. */ static void handleSigUsr2() { static int codeCacheResetCount = 0; gDvmJit.receivedSIGUSR2 ^= true; if ((--codeCacheResetCount & 7) == 0) { /* Dump all class pointers in the traces */ dvmJitScanAllClassPointers(printAllClass); gDvmJit.codeCacheFull = true; } else { dvmCompilerDumpStats(); /* Stress-test unchain all */ dvmJitUnchainAll(); ALOGD("Send %d more signals to reset the code cache", codeCacheResetCount & 7); } dvmCheckInterpStateConsistency(); }
void dvmCompilerShutdown(void) { void *threadReturn; /* Disable new translation requests */ gDvmJit.pProfTable = NULL; gDvmJit.pProfTableCopy = NULL; dvmJitUpdateThreadStateAll(); if (gDvm.verboseShutdown || gDvmJit.profileMode == kTraceProfilingContinuous) { dvmCompilerDumpStats(); while (gDvmJit.compilerQueueLength) sleep(5); } if (gDvmJit.compilerHandle) { gDvmJit.haltCompilerThread = true; dvmLockMutex(&gDvmJit.compilerLock); pthread_cond_signal(&gDvmJit.compilerQueueActivity); dvmUnlockMutex(&gDvmJit.compilerLock); if (pthread_join(gDvmJit.compilerHandle, &threadReturn) != 0) ALOGW("Compiler thread join failed"); else if (gDvm.verboseShutdown) ALOGD("Compiler thread has shut down"); } /* Break loops within the translation cache */ dvmJitUnchainAll(); /* * NOTE: our current implementatation doesn't allow for the compiler * thread to be restarted after it exits here. We aren't freeing * the JitTable or the ProfTable because threads which still may be * running or in the process of shutting down may hold references to * them. */ }
/** * @brief 更新编译器全局状态 * @note 在"vm/Profile.cpp"中的updateActiveProfilers中被调用 */ void dvmCompilerUpdateGlobalState() { bool jitActive; bool jitActivate; bool needUnchain = false; /* * The tableLock might not be initialized yet by the compiler thread if * debugger is attached from the very beginning of the VM launch. If * pProfTableCopy is NULL, the lock is not initialized yet and we don't * need to refresh anything either. */ /* * 如果在调试器附加到虚拟机启动器的非常早之前,编译器线程对tableLock * 并没有初始化完成。这是我们不能更新任何状态。 */ if (gDvmJit.pProfTableCopy == NULL) { 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. */ /* * 第一次启用函数tracing,转化编译器到保护支持invokes与returns * 指令的trace格式。如果已经存在了一些编译代码则直接刷入他们到缓存中。 * NOTE:我们不能在编译器线程未初始化完成之前刷入代码 */ /* activeProfilers 表明 开启profiler */ if ((gDvm.activeProfilers != 0) && !gDvmJit.methodTraceSupport) { /* 这里表明第一次启动tracing */ 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); /* 通过判断pProfTable表判断JIT是否被激活 */ jitActive = gDvmJit.pProfTable != NULL; jitActivate = !dvmDebuggerOrProfilerActive(); /* 处于调试阶段或者profile开启 */ /* jitActivate为TRUE表明处于调试阶段 */ if (jitActivate && !jitActive) { gDvmJit.pProfTable = gDvmJit.pProfTableCopy; /* 处于调试获取副本 */ } else if (!jitActivate && jitActive) { /* 处于正常运行 */ gDvmJit.pProfTable = NULL; needUnchain = true;/* 需要解链操作 */ } dvmUnlockMutex(&gDvmJit.tableLock); if (needUnchain) /* 不再调试模式下为TRUE */ dvmJitUnchainAll(); // Make sure all threads have current values /* 对所有线程设置JitTable表 */ dvmJitUpdateThreadStateAll(); }