Esempio n. 1
0
void CallLinkStatus::computeDFGStatuses(
    CodeBlock* dfgCodeBlock, CallLinkStatus::ContextMap& map)
{
#if ENABLE(DFG_JIT)
    RELEASE_ASSERT(dfgCodeBlock->jitType() == JITCode::DFGJIT);
    CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
    for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
        CallLinkInfo& info = **iter;
        CodeOrigin codeOrigin = info.codeOrigin;

        bool takeSlowPath;
        bool badFunction;

        // Check if we had already previously made a terrible mistake in the FTL for this
        // code origin. Note that this is approximate because we could have a monovariant
        // inline in the FTL that ended up failing. We should fix that at some point by
        // having data structures to track the context of frequent exits. This is currently
        // challenging because it would require creating a CodeOrigin-based database in
        // baseline CodeBlocks, but those CodeBlocks don't really have a place to put the
        // InlineCallFrames.
        CodeBlock* currentBaseline =
            baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
        {
            ConcurrentJITLocker locker(currentBaseline->m_lock);
            takeSlowPath =
                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCache, ExitFromFTL))
                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCacheWatchpoint, ExitFromFTL))
                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadExecutable, ExitFromFTL));
            badFunction =
                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadFunction, ExitFromFTL));
        }

        {
            ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
            if (takeSlowPath)
                map.add(info.codeOrigin, takesSlowPath());
            else {
                CallLinkStatus status = computeFor(locker, info);
                if (status.isSet()) {
                    if (badFunction)
                        status.makeClosureCall();
                    map.add(info.codeOrigin, status);
                }
            }
        }
    }
#else
    UNUSED_PARAM(dfgCodeBlock);
#endif // ENABLE(DFG_JIT)

    if (verbose) {
        dataLog("Context map:\n");
        ContextMap::iterator iter = map.begin();
        ContextMap::iterator end = map.end();
        for (; iter != end; ++iter) {
            dataLog("    ", iter->key, ":\n");
            dataLog("        ", iter->value, "\n");
        }
    }
}
Esempio n. 2
0
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
{
    if (static_cast<double>(m_count) / dfgCodeBlock->speculativeFailCounter() <= Options::osrExitProminenceForFrequentExitSite)
        return false;
    
    return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOrigin, profiledCodeBlock)->addFrequentExitSite(FrequentExitSite(m_codeOrigin.bytecodeIndex, m_kind));
}
Esempio n. 3
0
void OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
{
    CodeBlock* sourceProfiledCodeBlock =
        baselineCodeBlockForOriginAndBaselineCodeBlock(
            m_codeOriginForExitProfile, profiledCodeBlock);
    if (sourceProfiledCodeBlock)
        sourceProfiledCodeBlock->addFrequentExitSite(FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind, jitType));
}
bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
{
    CodeBlock* sourceProfiledCodeBlock =
        baselineCodeBlockForOriginAndBaselineCodeBlock(
            m_codeOriginForExitProfile, profiledCodeBlock);
    if (!sourceProfiledCodeBlock)
        return false;
    return sourceProfiledCodeBlock->addFrequentExitSite(
            FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind));
}
Esempio n. 5
0
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
{
    FrequentExitSite exitSite;
    
    if (m_kind == ArgumentsEscaped) {
        // Count this one globally. It doesn't matter where in the code block the arguments excaped;
        // the fact that they did is not associated with any particular instruction.
        exitSite = FrequentExitSite(m_kind);
    } else
        exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind);
    
    return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite);
}
void OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
{
    CodeBlock* sourceProfiledCodeBlock =
        baselineCodeBlockForOriginAndBaselineCodeBlock(
            m_codeOriginForExitProfile, profiledCodeBlock);
    if (sourceProfiledCodeBlock) {
        FrequentExitSite site;
        if (m_wasHoisted)
            site = FrequentExitSite(HoistingFailed, jitType);
        else
            site = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind, jitType);
        sourceProfiledCodeBlock->addFrequentExitSite(site);
    }
}
Esempio n. 7
0
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
{
    if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
        return false;
    
    FrequentExitSite exitSite;
    
    if (m_kind == ArgumentsEscaped) {
        // Count this one globally. It doesn't matter where in the code block the arguments excaped;
        // the fact that they did is not associated with any particular instruction.
        exitSite = FrequentExitSite(m_kind);
    } else
        exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind);
    
    return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOrigin, profiledCodeBlock)->addFrequentExitSite(exitSite);
}
Esempio n. 8
0
void CallLinkStatus::computeDFGStatuses(
    CodeBlock* dfgCodeBlock, CallLinkStatus::ContextMap& map)
{
#if ENABLE(DFG_JIT)
    RELEASE_ASSERT(dfgCodeBlock->jitType() == JITCode::DFGJIT);
    CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
    for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
        CallLinkInfo& info = **iter;
        CodeOrigin codeOrigin = info.codeOrigin();
        
        // Check if we had already previously made a terrible mistake in the FTL for this
        // code origin. Note that this is approximate because we could have a monovariant
        // inline in the FTL that ended up failing. We should fix that at some point by
        // having data structures to track the context of frequent exits. This is currently
        // challenging because it would require creating a CodeOrigin-based database in
        // baseline CodeBlocks, but those CodeBlocks don't really have a place to put the
        // InlineCallFrames.
        CodeBlock* currentBaseline =
            baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
        ExitSiteData exitSiteData;
        {
            ConcurrentJITLocker locker(currentBaseline->m_lock);
            exitSiteData = computeExitSiteData(
                locker, currentBaseline, codeOrigin.bytecodeIndex);
        }
        
        {
            ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
            map.add(info.codeOrigin(), computeFor(locker, dfgCodeBlock, info, exitSiteData));
        }
    }
#else
    UNUSED_PARAM(dfgCodeBlock);
#endif // ENABLE(DFG_JIT)
    
    if (verbose) {
        dataLog("Context map:\n");
        ContextMap::iterator iter = map.begin();
        ContextMap::iterator end = map.end();
        for (; iter != end; ++iter) {
            dataLog("    ", iter->key, ":\n");
            dataLog("        ", iter->value, "\n");
        }
    }
}
void ProfiledCodeBlockJettisoningWatchpoint::fireInternal()
{
    if (DFG::shouldShowDisassembly()) {
        dataLog(
            "Firing profiled watchpoint ", RawPointer(this), " on ", *m_codeBlock, " due to ",
            m_exitKind, " at ", m_codeOrigin, "\n");
    }
    
    baselineCodeBlockForOriginAndBaselineCodeBlock(
        m_codeOrigin, m_codeBlock->baselineVersion())->addFrequentExitSite(
            DFG::FrequentExitSite(m_codeOrigin.bytecodeIndex, m_exitKind));
    
#if ENABLE(JIT)
    m_codeBlock->jettison(CountReoptimization);
#endif

    if (isOnList())
        remove();
}