Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
 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;
     }
 }
Esempio n. 4
0
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");
    }
}