bool ExitProfile::add(const ConcurrentJSLocker&, CodeBlock* owner, const FrequentExitSite& site) { ASSERT(site.jitType() != ExitFromAnything); CODEBLOCK_LOG_EVENT(owner, "frequentExit", (site)); if (Options::verboseExitProfile()) dataLog(pointerDump(owner), ": Adding exit site: ", site, "\n"); // If we've never seen any frequent exits then create the list and put this site // into it. if (!m_frequentExitSites) { m_frequentExitSites = std::make_unique<Vector<FrequentExitSite>>(); m_frequentExitSites->append(site); return true; } // Don't add it if it's already there. This is O(n), but that's OK, because we // know that the total number of places where code exits tends to not be large, // and this code is only used when recompilation is triggered. for (unsigned i = 0; i < m_frequentExitSites->size(); ++i) { if (m_frequentExitSites->at(i) == site) return false; } m_frequentExitSites->append(site); return true; }
CompilationResult Plan::finalizeWithoutNotifyingCallback() { // We will establish new references from the code block to things. So, we need a barrier. vm->heap.writeBarrier(codeBlock); if (!isStillValid()) { CODEBLOCK_LOG_EVENT(codeBlock, "dfgFinalize", ("invalidated")); return CompilationInvalidated; } bool result; if (codeBlock->codeType() == FunctionCode) result = finalizer->finalizeFunction(); else result = finalizer->finalize(); if (!result) { CODEBLOCK_LOG_EVENT(codeBlock, "dfgFinalize", ("failed")); return CompilationFailed; } reallyAdd(codeBlock->jitCode()->dfgCommon()); if (validationEnabled()) { TrackedReferences trackedReferences; for (WriteBarrier<JSCell>& reference : codeBlock->jitCode()->dfgCommon()->weakReferences) trackedReferences.add(reference.get()); for (WriteBarrier<Structure>& reference : codeBlock->jitCode()->dfgCommon()->weakStructureReferences) trackedReferences.add(reference.get()); for (WriteBarrier<Unknown>& constant : codeBlock->constants()) trackedReferences.add(constant.get()); // Check that any other references that we have anywhere in the JITCode are also // tracked either strongly or weakly. codeBlock->jitCode()->validateReferences(trackedReferences); } CODEBLOCK_LOG_EVENT(codeBlock, "dfgFinalize", ("succeeded")); return CompilationSuccessful; }
void finalize() { CompilationResult result = m_jit.link(); switch (result) { case CompilationFailed: CODEBLOCK_LOG_EVENT(m_codeBlock, "delayJITCompile", ("compilation failed")); if (Options::verboseOSR()) dataLogF(" JIT compilation failed.\n"); m_codeBlock->dontJITAnytimeSoon(); m_codeBlock->m_didFailJITCompilation = true; return; case CompilationSuccessful: if (Options::verboseOSR()) dataLogF(" JIT compilation successful.\n"); m_codeBlock->ownerScriptExecutable()->installCode(m_codeBlock); m_codeBlock->jitSoon(); return; default: RELEASE_ASSERT_NOT_REACHED(); return; } }
void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadData) { this->threadData = threadData; double before = 0; CString codeBlockName; if (UNLIKELY(computeCompileTimes())) before = monotonicallyIncreasingTimeMS(); if (UNLIKELY(reportCompileTimes())) codeBlockName = toCString(*codeBlock); CompilationScope compilationScope; if (logCompilationChanges(mode) || Options::reportDFGPhaseTimes()) dataLog("DFG(Plan) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n"); CompilationPath path = compileInThreadImpl(longLivedState); RELEASE_ASSERT(path == CancelPath || finalizer); RELEASE_ASSERT((path == CancelPath) == (stage == Cancelled)); double after = 0; if (UNLIKELY(computeCompileTimes())) { after = monotonicallyIncreasingTimeMS(); if (Options::reportTotalCompileTimes()) { if (isFTL(mode)) { totalFTLCompileTime += after - before; totalFTLDFGCompileTime += m_timeBeforeFTL - before; totalFTLB3CompileTime += after - m_timeBeforeFTL; } else totalDFGCompileTime += after - before; } } const char* pathName = nullptr; switch (path) { case FailPath: pathName = "N/A (fail)"; break; case DFGPath: pathName = "DFG"; break; case FTLPath: pathName = "FTL"; break; case CancelPath: pathName = "Cancelled"; break; default: RELEASE_ASSERT_NOT_REACHED(); break; } if (codeBlock) { // codeBlock will be null if the compilation was cancelled. if (path == FTLPath) CODEBLOCK_LOG_EVENT(codeBlock, "ftlCompile", ("took ", after - before, " ms (DFG: ", m_timeBeforeFTL - before, ", B3: ", after - m_timeBeforeFTL, ") with ", pathName)); else CODEBLOCK_LOG_EVENT(codeBlock, "dfgCompile", ("took ", after - before, " ms with ", pathName)); } if (UNLIKELY(reportCompileTimes())) { dataLog("Optimized ", codeBlockName, " using ", mode, " with ", pathName, " into ", finalizer ? finalizer->codeSize() : 0, " bytes in ", after - before, " ms"); if (path == FTLPath) dataLog(" (DFG: ", m_timeBeforeFTL - before, ", B3: ", after - m_timeBeforeFTL, ")"); dataLog(".\n"); } }