Beispiel #1
0
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();
}
Beispiel #2
0
/**
 * 关闭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();
}
Beispiel #4
0
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.
     */
}
Beispiel #5
0
/**
 * @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();
}