/*
 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "DFGPlan.h"

#if ENABLE(DFG_JIT)

#include "DFGArgumentsEliminationPhase.h"
#include "DFGBackwardsPropagationPhase.h"
#include "DFGByteCodeParser.h"
#include "DFGCFAPhase.h"
#include "DFGCFGSimplificationPhase.h"
#include "DFGCPSRethreadingPhase.h"
#include "DFGCSEPhase.h"
#include "DFGCleanUpPhase.h"
#include "DFGConstantFoldingPhase.h"
#include "DFGConstantHoistingPhase.h"
#include "DFGCriticalEdgeBreakingPhase.h"
#include "DFGDCEPhase.h"
#include "DFGFailedFinalizer.h"
#include "DFGFixupPhase.h"
#include "DFGGraphSafepoint.h"
#include "DFGIntegerCheckCombiningPhase.h"
#include "DFGIntegerRangeOptimizationPhase.h"
#include "DFGInvalidationPointInjectionPhase.h"
#include "DFGJITCompiler.h"
#include "DFGLICMPhase.h"
#include "DFGLiveCatchVariablePreservationPhase.h"
#include "DFGLivenessAnalysisPhase.h"
#include "DFGLoopPreHeaderCreationPhase.h"
#include "DFGMovHintRemovalPhase.h"
#include "DFGOSRAvailabilityAnalysisPhase.h"
#include "DFGOSREntrypointCreationPhase.h"
#include "DFGObjectAllocationSinkingPhase.h"
#include "DFGPhantomInsertionPhase.h"
#include "DFGPredictionInjectionPhase.h"
#include "DFGPredictionPropagationPhase.h"
#include "DFGPutStackSinkingPhase.h"
#include "DFGSSAConversionPhase.h"
#include "DFGSSALoweringPhase.h"
#include "DFGStackLayoutPhase.h"
#include "DFGStaticExecutionCountEstimationPhase.h"
#include "DFGStoreBarrierClusteringPhase.h"
#include "DFGStoreBarrierInsertionPhase.h"
#include "DFGStrengthReductionPhase.h"
#include "DFGTierUpCheckInjectionPhase.h"
#include "DFGTypeCheckHoistingPhase.h"
#include "DFGUnificationPhase.h"
#include "DFGValidate.h"
#include "DFGValueRepReductionPhase.h"
#include "DFGVarargsForwardingPhase.h"
#include "DFGVirtualRegisterAllocationPhase.h"
#include "DFGWatchpointCollectionPhase.h"
#include "JSCInlines.h"
#include "OperandsInlines.h"
#include "ProfilerDatabase.h"
#include "TrackedReferences.h"
#include "VMInlines.h"

#if ENABLE(FTL_JIT)
#include "FTLCapabilities.h"
#include "FTLCompile.h"
#include "FTLFail.h"
#include "FTLLink.h"
#include "FTLLowerDFGToB3.h"
#include "FTLState.h"
#endif

namespace JSC {

extern Seconds totalDFGCompileTime;
extern Seconds totalFTLCompileTime;
extern Seconds totalFTLDFGCompileTime;
extern Seconds totalFTLB3CompileTime;

}

namespace JSC { namespace DFG {

namespace {

void dumpAndVerifyGraph(Graph& graph, const char* text, bool forceDump = false)
{
    GraphDumpMode modeForFinalValidate = DumpGraph;
    if (verboseCompilationEnabled(graph.m_plan.mode()) || forceDump) {
        dataLog(text, "\n");
        graph.dump();
        modeForFinalValidate = DontDumpGraph;
    }
    if (validationEnabled())
        validate(graph, modeForFinalValidate);
}

Profiler::CompilationKind profilerCompilationKindForMode(CompilationMode mode)
{
    switch (mode) {
    case InvalidCompilationMode:
        RELEASE_ASSERT_NOT_REACHED();
        return Profiler::DFG;
    case DFGMode:
        return Profiler::DFG;
    case FTLMode:
        return Profiler::FTL;
    case FTLForOSREntryMode:
        return Profiler::FTLForOSREntry;
    }
    RELEASE_ASSERT_NOT_REACHED();
    return Profiler::DFG;
}

} // anonymous namespace

Plan::Plan(CodeBlock* passedCodeBlock, CodeBlock* profiledDFGCodeBlock,
    CompilationMode mode, BytecodeIndex osrEntryBytecodeIndex,
    const Operands<Optional<JSValue>>& mustHandleValues)
    : m_mode(mode)
    , m_vm(&passedCodeBlock->vm())
    , m_codeBlock(passedCodeBlock)
    , m_profiledDFGCodeBlock(profiledDFGCodeBlock)
    , m_mustHandleValues(mustHandleValues)
    , m_osrEntryBytecodeIndex(osrEntryBytecodeIndex)
    , m_compilation(UNLIKELY(m_vm->m_perBytecodeProfiler) ? adoptRef(new Profiler::Compilation(m_vm->m_perBytecodeProfiler->ensureBytecodesFor(m_codeBlock), profilerCompilationKindForMode(mode))) : nullptr)
    , m_inlineCallFrames(adoptRef(new InlineCallFrameSet()))
    , m_identifiers(m_codeBlock)
    , m_weakReferences(m_codeBlock)
    , m_stage(Preparing)
{
    RELEASE_ASSERT(m_codeBlock->alternative()->jitCode());
    m_inlineCallFrames->disableThreadingChecks();
}

Plan::~Plan()
{
}

bool Plan::computeCompileTimes() const
{
    return reportCompileTimes()
        || Options::reportTotalCompileTimes()
        || (m_vm && m_vm->m_perBytecodeProfiler);
}

bool Plan::reportCompileTimes() const
{
    return Options::reportCompileTimes()
        || Options::reportDFGCompileTimes()
        || (Options::reportFTLCompileTimes() && isFTL());
}

void Plan::compileInThread(ThreadData* threadData)
{
    m_threadData = threadData;

    MonotonicTime before { };
    CString codeBlockName;
    if (UNLIKELY(computeCompileTimes()))
        before = MonotonicTime::now();
    if (UNLIKELY(reportCompileTimes()))
        codeBlockName = toCString(*m_codeBlock);

    CompilationScope compilationScope;

    if (logCompilationChanges(m_mode) || Options::logPhaseTimes())
        dataLog("DFG(Plan) compiling ", *m_codeBlock, " with ", m_mode, ", instructions size = ", m_codeBlock->instructionsSize(), "\n");

    CompilationPath path = compileInThreadImpl();

    RELEASE_ASSERT(path == CancelPath || m_finalizer);
    RELEASE_ASSERT((path == CancelPath) == (m_stage == Cancelled));

    MonotonicTime after { };
    if (UNLIKELY(computeCompileTimes())) {
        after = MonotonicTime::now();
    
        if (Options::reportTotalCompileTimes()) {
            if (isFTL()) {
                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 (m_codeBlock) { // m_codeBlock will be null if the compilation was cancelled.
        if (path == FTLPath)
            CODEBLOCK_LOG_EVENT(m_codeBlock, "ftlCompile", ("took ", (after - before).milliseconds(), " ms (DFG: ", (m_timeBeforeFTL - before).milliseconds(), ", B3: ", (after - m_timeBeforeFTL).milliseconds(), ") with ", pathName));
        else
            CODEBLOCK_LOG_EVENT(m_codeBlock, "dfgCompile", ("took ", (after - before).milliseconds(), " ms with ", pathName));
    }
    if (UNLIKELY(reportCompileTimes())) {
        dataLog("Optimized ", codeBlockName, " using ", m_mode, " with ", pathName, " into ", m_finalizer ? m_finalizer->codeSize() : 0, " bytes in ", (after - before).milliseconds(), " ms");
        if (path == FTLPath)
            dataLog(" (DFG: ", (m_timeBeforeFTL - before).milliseconds(), ", B3: ", (after - m_timeBeforeFTL).milliseconds(), ")");
        dataLog(".\n");
    }
}

Plan::CompilationPath Plan::compileInThreadImpl()
{
    {
        CompilerTimingScope timingScope("DFG", "clean must handle values");
        cleanMustHandleValuesIfNecessary();
    }

    if (verboseCompilationEnabled(m_mode) && m_osrEntryBytecodeIndex) {
        dataLog("\n");
        dataLog("Compiler must handle OSR entry from ", m_osrEntryBytecodeIndex, " with values: ", m_mustHandleValues, "\n");
        dataLog("\n");
    }

    Graph dfg(*m_vm, *this);

    {
        CompilerTimingScope timingScope("DFG", "bytecode parser");
        parse(dfg);
    }

    m_codeBlock->setCalleeSaveRegisters(RegisterSet::dfgCalleeSaveRegisters());

    bool changed = false;

#define RUN_PHASE(phase)                                         \
    do {                                                         \
        if (Options::safepointBeforeEachPhase()) {               \
            Safepoint::Result safepointResult;                   \
            {                                                    \
                GraphSafepoint safepoint(dfg, safepointResult);  \
            }                                                    \
            if (safepointResult.didGetCancelled())               \
                return CancelPath;                               \
        }                                                        \
        dfg.nextPhase();                                         \
        changed |= phase(dfg);                                   \
    } while (false);                                             \

    
    // By this point the DFG bytecode parser will have potentially mutated various tables
    // in the CodeBlock. This is a good time to perform an early shrink, which is more
    // powerful than a late one. It's safe to do so because we haven't generated any code
    // that references any of the tables directly, yet.
    {
        ConcurrentJSLocker locker(m_codeBlock->m_lock);
        m_codeBlock->shrinkToFit(locker, CodeBlock::ShrinkMode::EarlyShrink);
    }

    if (validationEnabled())
        validate(dfg);
    
    if (Options::dumpGraphAfterParsing()) {
        dataLog("Graph after parsing:\n");
        dfg.dump();
    }

    RUN_PHASE(performLiveCatchVariablePreservationPhase);

    RUN_PHASE(performCPSRethreading);
    RUN_PHASE(performUnification);
    RUN_PHASE(performPredictionInjection);
    
    RUN_PHASE(performStaticExecutionCountEstimation);

    if (m_mode == FTLForOSREntryMode) {
        bool result = performOSREntrypointCreation(dfg);
        if (!result) {
            m_finalizer = makeUnique<FailedFinalizer>(*this);
            return FailPath;
        }
        RUN_PHASE(performCPSRethreading);
    }
    
    if (validationEnabled())
        validate(dfg);
    
    RUN_PHASE(performBackwardsPropagation);
    RUN_PHASE(performPredictionPropagation);
    RUN_PHASE(performFixup);
    RUN_PHASE(performInvalidationPointInjection);
    RUN_PHASE(performTypeCheckHoisting);

    dfg.m_fixpointState = FixpointNotConverged;

    // For now we're back to avoiding a fixpoint. Note that we've ping-ponged on this decision
    // many times. For maximum throughput, it's best to fixpoint. But the throughput benefit is
    // small and not likely to show up in FTL anyway. On the other hand, not fixpointing means
    // that the compiler compiles more quickly. We want the third tier to compile quickly, which
    // not fixpointing accomplishes; and the fourth tier shouldn't need a fixpoint.
    if (validationEnabled())
        validate(dfg);
        
    RUN_PHASE(performStrengthReduction);
    RUN_PHASE(performCPSRethreading);
    RUN_PHASE(performCFA);
    RUN_PHASE(performConstantFolding);
    changed = false;
    RUN_PHASE(performCFGSimplification);
    RUN_PHASE(performLocalCSE);
    
    if (validationEnabled())
        validate(dfg);
    
    RUN_PHASE(performCPSRethreading);
    if (!isFTL()) {
        // Only run this if we're not FTLing, because currently for a LoadVarargs that is forwardable and
        // in a non-varargs inlined call frame, this will generate ForwardVarargs while the FTL
        // ArgumentsEliminationPhase will create a sequence of GetStack+PutStacks. The GetStack+PutStack
        // sequence then gets sunk, eliminating anything that looks like an escape for subsequent phases,
        // while the ForwardVarargs doesn't get simplified until later (or not at all) and looks like an
        // escape for all of the arguments. This then disables object allocation sinking.
        //
        // So, for now, we just disable this phase for the FTL.
        //
        // If we wanted to enable it, we'd have to do any of the following:
        // - Enable ForwardVarargs->GetStack+PutStack strength reduction, and have that run before
        //   PutStack sinking and object allocation sinking.
        // - Make VarargsForwarding emit a GetLocal+SetLocal sequence, that we can later turn into
        //   GetStack+PutStack.
        //
        // But, it's not super valuable to enable those optimizations, since the FTL
        // ArgumentsEliminationPhase does everything that this phase does, and it doesn't introduce this
        // pathology.
        
        RUN_PHASE(performVarargsForwarding); // Do this after CFG simplification and CPS rethreading.
    }
    if (changed) {
        RUN_PHASE(performCFA);
        RUN_PHASE(performConstantFolding);
    }
    
    // If we're doing validation, then run some analyses, to give them an opportunity
    // to self-validate. Now is as good a time as any to do this.
    if (validationEnabled()) {
        dfg.ensureCPSDominators();
        dfg.ensureCPSNaturalLoops();
    }

    switch (m_mode) {
    case DFGMode: {
        dfg.m_fixpointState = FixpointConverged;

        RUN_PHASE(performTierUpCheckInjection);

        RUN_PHASE(performFastStoreBarrierInsertion);
        RUN_PHASE(performStoreBarrierClustering);
        RUN_PHASE(performCleanUp);
        RUN_PHASE(performCPSRethreading);
        RUN_PHASE(performDCE);
        RUN_PHASE(performPhantomInsertion);
        RUN_PHASE(performStackLayout);
        RUN_PHASE(performVirtualRegisterAllocation);
        RUN_PHASE(performWatchpointCollection);
        dumpAndVerifyGraph(dfg, "Graph after optimization:");
        
        {
            CompilerTimingScope timingScope("DFG", "machine code generation");

            JITCompiler dataFlowJIT(dfg);
            if (m_codeBlock->codeType() == FunctionCode)
                dataFlowJIT.compileFunction();
            else
                dataFlowJIT.compile();
        }
        
        return DFGPath;
    }
    
    case FTLMode:
    case FTLForOSREntryMode: {
#if ENABLE(FTL_JIT)
        if (FTL::canCompile(dfg) == FTL::CannotCompile) {
            m_finalizer = makeUnique<FailedFinalizer>(*this);
            return FailPath;
        }
        
        RUN_PHASE(performCleanUp); // Reduce the graph size a bit.
        RUN_PHASE(performCriticalEdgeBreaking);
        if (Options::createPreHeaders())
            RUN_PHASE(performLoopPreHeaderCreation);
        RUN_PHASE(performCPSRethreading);
        RUN_PHASE(performSSAConversion);
        RUN_PHASE(performSSALowering);
        
        // Ideally, these would be run to fixpoint with the object allocation sinking phase.
        RUN_PHASE(performArgumentsElimination);
        if (Options::usePutStackSinking())
            RUN_PHASE(performPutStackSinking);
        
        RUN_PHASE(performConstantHoisting);
        RUN_PHASE(performGlobalCSE);
        RUN_PHASE(performLivenessAnalysis);
        RUN_PHASE(performCFA);
        RUN_PHASE(performConstantFolding);
        RUN_PHASE(performCleanUp); // Reduce the graph size a lot.
        changed = false;
        RUN_PHASE(performStrengthReduction);
        if (Options::useObjectAllocationSinking()) {
            RUN_PHASE(performCriticalEdgeBreaking);
            RUN_PHASE(performObjectAllocationSinking);
        }
        if (Options::useValueRepElimination())
            RUN_PHASE(performValueRepReduction);
        if (changed) {
            // State-at-tail and state-at-head will be invalid if we did strength reduction since
            // it might increase live ranges.
            RUN_PHASE(performLivenessAnalysis);
            RUN_PHASE(performCFA);
            RUN_PHASE(performConstantFolding);
        }
        
        // Currently, this relies on pre-headers still being valid. That precludes running CFG
        // simplification before it, unless we re-created the pre-headers. There wouldn't be anything
        // wrong with running LICM earlier, if we wanted to put other CFG transforms above this point.
        // Alternatively, we could run loop pre-header creation after SSA conversion - but if we did that
        // then we'd need to do some simple SSA fix-up.
        RUN_PHASE(performLivenessAnalysis);
        RUN_PHASE(performCFA);
        RUN_PHASE(performLICM);

        // FIXME: Currently: IntegerRangeOptimization *must* be run after LICM.
        //
        // IntegerRangeOptimization makes changes on nodes based on preceding blocks
        // and nodes. LICM moves nodes which can invalidates assumptions used
        // by IntegerRangeOptimization.
        //
        // Ideally, the dependencies should be explicit. See https://bugs.webkit.org/show_bug.cgi?id=157534.
        RUN_PHASE(performLivenessAnalysis);
        RUN_PHASE(performIntegerRangeOptimization);
        
        RUN_PHASE(performCleanUp);
        RUN_PHASE(performIntegerCheckCombining);
        RUN_PHASE(performGlobalCSE);

        // At this point we're not allowed to do any further code motion because our reasoning
        // about code motion assumes that it's OK to insert GC points in random places.
        dfg.m_fixpointState = FixpointConverged;

        RUN_PHASE(performLivenessAnalysis);
        RUN_PHASE(performCFA);
        RUN_PHASE(performGlobalStoreBarrierInsertion);
        RUN_PHASE(performStoreBarrierClustering);
        if (Options::useMovHintRemoval())
            RUN_PHASE(performMovHintRemoval);
        RUN_PHASE(performCleanUp);
        RUN_PHASE(performDCE); // We rely on this to kill dead code that won't be recognized as dead by B3.
        RUN_PHASE(performStackLayout);
        RUN_PHASE(performLivenessAnalysis);
        RUN_PHASE(performOSRAvailabilityAnalysis);
        RUN_PHASE(performWatchpointCollection);
        
        if (FTL::canCompile(dfg) == FTL::CannotCompile) {
            m_finalizer = makeUnique<FailedFinalizer>(*this);
            return FailPath;
        }

        dfg.nextPhase();
        dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:", shouldDumpDisassembly(m_mode));

        // Flash a safepoint in case the GC wants some action.
        Safepoint::Result safepointResult;
        {
            GraphSafepoint safepoint(dfg, safepointResult);
        }
        if (safepointResult.didGetCancelled())
            return CancelPath;

        dfg.nextPhase();
        FTL::State state(dfg);
        FTL::lowerDFGToB3(state);

        if (UNLIKELY(computeCompileTimes()))
            m_timeBeforeFTL = MonotonicTime::now();
        
        if (UNLIKELY(Options::b3AlwaysFailsBeforeCompile())) {
            FTL::fail(state);
            return FTLPath;
        }
        
        FTL::compile(state, safepointResult);
        if (safepointResult.didGetCancelled())
            return CancelPath;
        
        if (UNLIKELY(Options::b3AlwaysFailsBeforeLink())) {
            FTL::fail(state);
            return FTLPath;
        }
        
        if (state.allocationFailed) {
            FTL::fail(state);
            return FTLPath;
        }

        FTL::link(state);
        
        if (state.allocationFailed) {
            FTL::fail(state);
            return FTLPath;
        }
        
        return FTLPath;
#else
        RELEASE_ASSERT_NOT_REACHED();
        return FailPath;
#endif // ENABLE(FTL_JIT)
    }
        
    default:
        RELEASE_ASSERT_NOT_REACHED();
        return FailPath;
    }

#undef RUN_PHASE
}

bool Plan::isStillValid()
{
    CodeBlock* replacement = m_codeBlock->replacement();
    if (!replacement)
        return false;
    // FIXME: This is almost certainly not necessary. There's no way for the baseline
    // code to be replaced during a compilation, except if we delete the plan, in which
    // case we wouldn't be here.
    // https://bugs.webkit.org/show_bug.cgi?id=132707
    if (m_codeBlock->alternative() != replacement->baselineVersion())
        return false;
    if (!m_watchpoints.areStillValid())
        return false;
    return true;
}

void Plan::reallyAdd(CommonData* commonData)
{
    m_watchpoints.reallyAdd(m_codeBlock, *commonData);
    m_identifiers.reallyAdd(*m_vm, commonData);
    m_weakReferences.reallyAdd(*m_vm, commonData);
    m_transitions.reallyAdd(*m_vm, commonData);
    m_globalProperties.reallyAdd(m_codeBlock, m_identifiers, *commonData);
    commonData->recordedStatuses = WTFMove(m_recordedStatuses);
}

void Plan::notifyCompiling()
{
    m_stage = Compiling;
}

void Plan::notifyReady()
{
    m_callback->compilationDidBecomeReadyAsynchronously(m_codeBlock, m_profiledDFGCodeBlock);
    m_stage = Ready;
}

bool Plan::isStillValidOnMainThread()
{
    return m_globalProperties.isStillValidOnMainThread(*m_vm, m_identifiers);
}

CompilationResult Plan::finalizeWithoutNotifyingCallback()
{
    // We perform multiple stores before emitting a write-barrier. To ensure that no GC happens between store and write-barrier, we should ensure that
    // GC is deferred when this function is called.
    ASSERT(m_vm->heap.isDeferred());

    CompilationResult result = [&] {
        if (!isStillValidOnMainThread() || !isStillValid()) {
            CODEBLOCK_LOG_EVENT(m_codeBlock, "dfgFinalize", ("invalidated"));
            return CompilationInvalidated;
        }

        bool result;
        if (m_codeBlock->codeType() == FunctionCode)
            result = m_finalizer->finalizeFunction();
        else
            result = m_finalizer->finalize();

        if (!result) {
            CODEBLOCK_LOG_EVENT(m_codeBlock, "dfgFinalize", ("failed"));
            return CompilationFailed;
        }

        reallyAdd(m_codeBlock->jitCode()->dfgCommon());
        {
            ConcurrentJSLocker locker(m_codeBlock->m_lock);
            m_codeBlock->jitCode()->shrinkToFit(locker);
            m_codeBlock->shrinkToFit(locker, CodeBlock::ShrinkMode::LateShrink);
        }

        if (validationEnabled()) {
            TrackedReferences trackedReferences;

            for (WriteBarrier<JSCell>& reference : m_codeBlock->jitCode()->dfgCommon()->weakReferences)
                trackedReferences.add(reference.get());
            for (StructureID structureID : m_codeBlock->jitCode()->dfgCommon()->weakStructureReferences)
                trackedReferences.add(m_vm->getStructure(structureID));
            for (WriteBarrier<Unknown>& constant : m_codeBlock->constants())
                trackedReferences.add(constant.get());

            for (auto* inlineCallFrame : *m_inlineCallFrames) {
                ASSERT(inlineCallFrame->baselineCodeBlock.get());
                trackedReferences.add(inlineCallFrame->baselineCodeBlock.get());
            }

            // Check that any other references that we have anywhere in the JITCode are also
            // tracked either strongly or weakly.
            m_codeBlock->jitCode()->validateReferences(trackedReferences);
        }

        CODEBLOCK_LOG_EVENT(m_codeBlock, "dfgFinalize", ("succeeded"));
        return CompilationSuccessful;
    }();

    // We will establish new references from the code block to things. So, we need a barrier.
    m_vm->heap.writeBarrier(m_codeBlock);
    return result;
}

void Plan::finalizeAndNotifyCallback()
{
    m_callback->compilationDidComplete(m_codeBlock, m_profiledDFGCodeBlock, finalizeWithoutNotifyingCallback());
}

CompilationKey Plan::key()
{
    return CompilationKey(m_codeBlock->alternative(), m_mode);
}

void Plan::checkLivenessAndVisitChildren(SlotVisitor& visitor)
{
    if (!isKnownToBeLiveDuringGC())
        return;

    cleanMustHandleValuesIfNecessary();
    for (unsigned i = m_mustHandleValues.size(); i--;) {
        Optional<JSValue> value = m_mustHandleValues[i];
        if (value)
            visitor.appendUnbarriered(value.value());
    }

    m_recordedStatuses.visitAggregate(visitor);
    m_recordedStatuses.markIfCheap(visitor);

    visitor.appendUnbarriered(m_codeBlock);
    visitor.appendUnbarriered(m_codeBlock->alternative());
    visitor.appendUnbarriered(m_profiledDFGCodeBlock);

    if (m_inlineCallFrames) {
        for (auto* inlineCallFrame : *m_inlineCallFrames) {
            ASSERT(inlineCallFrame->baselineCodeBlock.get());
            visitor.appendUnbarriered(inlineCallFrame->baselineCodeBlock.get());
        }
    }

    m_weakReferences.visitChildren(visitor);
    m_transitions.visitChildren(visitor);
}

void Plan::finalizeInGC()
{
    ASSERT(m_vm);
    m_recordedStatuses.finalizeWithoutDeleting(*m_vm);
}

bool Plan::isKnownToBeLiveDuringGC()
{
    if (m_stage == Cancelled)
        return false;
    if (!m_vm->heap.isMarked(m_codeBlock->ownerExecutable()))
        return false;
    if (!m_vm->heap.isMarked(m_codeBlock->alternative()))
        return false;
    if (!!m_profiledDFGCodeBlock && !m_vm->heap.isMarked(m_profiledDFGCodeBlock))
        return false;
    return true;
}

void Plan::cancel()
{
    RELEASE_ASSERT(m_stage != Cancelled);
    ASSERT(m_vm);
    m_vm = nullptr;

    m_codeBlock = nullptr;
    m_profiledDFGCodeBlock = nullptr;
    m_mustHandleValues.clear();
    m_compilation = nullptr;
    m_finalizer = nullptr;
    m_inlineCallFrames = nullptr;
    m_watchpoints = DesiredWatchpoints();
    m_identifiers = DesiredIdentifiers();
    m_globalProperties = DesiredGlobalProperties();
    m_weakReferences = DesiredWeakReferences();
    m_transitions = DesiredTransitions();
    m_callback = nullptr;
    m_stage = Cancelled;
}

void Plan::cleanMustHandleValuesIfNecessary()
{
    LockHolder locker(m_mustHandleValueCleaningLock);

    if (!m_mustHandleValuesMayIncludeGarbage)
        return;

    m_mustHandleValuesMayIncludeGarbage = false;

    if (!m_codeBlock)
        return;

    if (!m_mustHandleValues.numberOfLocals())
        return;

    CodeBlock* alternative = m_codeBlock->alternative();
    FastBitVector liveness = alternative->livenessAnalysis().getLivenessInfoAtBytecodeIndex(alternative, m_osrEntryBytecodeIndex);

    for (unsigned local = m_mustHandleValues.numberOfLocals(); local--;) {
        if (!liveness[local])
            m_mustHandleValues.local(local) = WTF::nullopt;
    }
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

