diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGPlan.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPlan.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPlan.cpp | 475 |
1 files changed, 92 insertions, 383 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPlan.cpp b/Source/JavaScriptCore/dfg/DFGPlan.cpp index a4a269808..735f5ffa2 100644 --- a/Source/JavaScriptCore/dfg/DFGPlan.cpp +++ b/Source/JavaScriptCore/dfg/DFGPlan.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,58 +28,43 @@ #if ENABLE(DFG_JIT) -#include "DFGArgumentsEliminationPhase.h" +#include "DFGArgumentsSimplificationPhase.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 "DFGCopyBarrierOptimizationPhase.h" #include "DFGCriticalEdgeBreakingPhase.h" #include "DFGDCEPhase.h" #include "DFGFailedFinalizer.h" +#include "DFGFlushLivenessAnalysisPhase.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 "DFGMaximalFlushInsertionPhase.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 "DFGResurrectionForValidationPhase.h" #include "DFGSSAConversionPhase.h" #include "DFGSSALoweringPhase.h" #include "DFGStackLayoutPhase.h" -#include "DFGStaticExecutionCountEstimationPhase.h" -#include "DFGStoreBarrierInsertionPhase.h" +#include "DFGStoreBarrierElisionPhase.h" #include "DFGStrengthReductionPhase.h" -#include "DFGStructureRegistrationPhase.h" #include "DFGTierUpCheckInjectionPhase.h" #include "DFGTypeCheckHoistingPhase.h" #include "DFGUnificationPhase.h" #include "DFGValidate.h" -#include "DFGVarargsForwardingPhase.h" #include "DFGVirtualRegisterAllocationPhase.h" #include "DFGWatchpointCollectionPhase.h" #include "Debugger.h" -#include "JSCInlines.h" #include "OperandsInlines.h" -#include "ProfilerDatabase.h" -#include "TrackedReferences.h" +#include "Operations.h" #include <wtf/CurrentTime.h> #if ENABLE(FTL_JIT) @@ -87,23 +72,17 @@ #include "FTLCompile.h" #include "FTLFail.h" #include "FTLLink.h" -#include "FTLLowerDFGToB3.h" +#include "FTLLowerDFGToLLVM.h" #include "FTLState.h" +#include "InitializeLLVM.h" #endif namespace JSC { namespace DFG { -namespace { - -double totalDFGCompileTime; -double totalFTLCompileTime; -double totalFTLDFGCompileTime; -double totalFTLB3CompileTime; - -void dumpAndVerifyGraph(Graph& graph, const char* text, bool forceDump = false) +static void dumpAndVerifyGraph(Graph& graph, const char* text) { GraphDumpMode modeForFinalValidate = DumpGraph; - if (verboseCompilationEnabled(graph.m_plan.mode) || forceDump) { + if (verboseCompilationEnabled()) { dataLog(text, "\n"); graph.dump(); modeForFinalValidate = DontDumpGraph; @@ -112,39 +91,18 @@ void dumpAndVerifyGraph(Graph& graph, const char* text, bool forceDump = false) 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, unsigned osrEntryBytecodeIndex, - const Operands<JSValue>& mustHandleValues) +Plan::Plan( + PassRefPtr<CodeBlock> passedCodeBlock, CompilationMode mode, + unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues) : vm(*passedCodeBlock->vm()) , codeBlock(passedCodeBlock) - , profiledDFGCodeBlock(profiledDFGCodeBlock) , mode(mode) , osrEntryBytecodeIndex(osrEntryBytecodeIndex) , mustHandleValues(mustHandleValues) - , compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock), profilerCompilationKindForMode(mode))) : 0) - , inlineCallFrames(adoptRef(new InlineCallFrameSet())) - , identifiers(codeBlock) - , weakReferences(codeBlock) - , stage(Preparing) + , compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock.get()), Profiler::DFG)) : 0) + , identifiers(codeBlock.get()) + , weakReferences(codeBlock.get()) + , isCompiled(false) { } @@ -152,54 +110,23 @@ Plan::~Plan() { } -bool Plan::computeCompileTimes() const +void Plan::compileInThread(LongLivedState& longLivedState) { - return reportCompileTimes() - || Options::reportTotalCompileTimes(); -} - -bool Plan::reportCompileTimes() const -{ - return Options::reportCompileTimes() - || (Options::reportFTLCompileTimes() && isFTL(mode)); -} - -void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadData) -{ - this->threadData = threadData; - double before = 0; - CString codeBlockName; - if (computeCompileTimes()) - before = monotonicallyIncreasingTimeMS(); - if (reportCompileTimes()) - codeBlockName = toCString(*codeBlock); + if (Options::reportCompileTimes()) + before = currentTimeMS(); SamplingRegion samplingRegion("DFG Compilation (Plan)"); CompilationScope compilationScope; - if (logCompilationChanges(mode)) + if (logCompilationChanges()) 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)); + RELEASE_ASSERT(finalizer); - double after = 0; - if (computeCompileTimes()) - after = monotonicallyIncreasingTimeMS(); - - if (Options::reportTotalCompileTimes()) { - if (isFTL(mode)) { - totalFTLCompileTime += after - before; - totalFTLDFGCompileTime += m_timeBeforeFTL - before; - totalFTLB3CompileTime += after - m_timeBeforeFTL; - } else - totalDFGCompileTime += after - before; - } - - if (reportCompileTimes()) { + if (Options::reportCompileTimes()) { const char* pathName; switch (path) { case FailPath: @@ -211,26 +138,22 @@ void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadDat case FTLPath: pathName = "FTL"; break; - case CancelPath: - pathName = "Cancelled"; - break; default: RELEASE_ASSERT_NOT_REACHED(); -#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE) pathName = ""; -#endif break; } - dataLog("Optimized ", codeBlockName, " using ", mode, " with ", pathName, " into ", finalizer ? finalizer->codeSize() : 0, " bytes in ", after - before, " ms"); + double now = currentTimeMS(); + dataLog("Optimized ", *codeBlock->alternative(), " using ", mode, " with ", pathName, " in ", now - before, " ms"); if (path == FTLPath) - dataLog(" (DFG: ", m_timeBeforeFTL - before, ", B3: ", after - m_timeBeforeFTL, ")"); + dataLog(" (DFG: ", beforeFTL - before, ", LLVM: ", now - beforeFTL, ")"); dataLog(".\n"); } } Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) { - if (verboseCompilationEnabled(mode) && osrEntryBytecodeIndex != UINT_MAX) { + if (verboseCompilationEnabled() && osrEntryBytecodeIndex != UINT_MAX) { dataLog("\n"); dataLog("Compiler must handle OSR entry from bc#", osrEntryBytecodeIndex, " with values: ", mustHandleValues, "\n"); dataLog("\n"); @@ -239,11 +162,9 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) Graph dfg(vm, *this, longLivedState); if (!parse(dfg)) { - finalizer = std::make_unique<FailedFinalizer>(*this); + finalizer = adoptPtr(new FailedFinalizer(*this)); return FailPath; } - - codeBlock->setCalleeSaveRegisters(RegisterSet::dfgCalleeSaveRegisters()); // 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 @@ -254,26 +175,14 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) if (validationEnabled()) validate(dfg); - if (Options::dumpGraphAfterParsing()) { - dataLog("Graph after parsing:\n"); - dfg.dump(); - } - - performLiveCatchVariablePreservationPhase(dfg); - - if (Options::useMaximalFlushInsertionPhase()) - performMaximalFlushInsertion(dfg); - performCPSRethreading(dfg); performUnification(dfg); performPredictionInjection(dfg); - performStaticExecutionCountEstimation(dfg); - if (mode == FTLForOSREntryMode) { bool result = performOSREntrypointCreation(dfg); if (!result) { - finalizer = std::make_unique<FailedFinalizer>(*this); + finalizer = adoptPtr(new FailedFinalizer(*this)); return FailPath; } performCPSRethreading(dfg); @@ -285,91 +194,66 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) performBackwardsPropagation(dfg); performPredictionPropagation(dfg); performFixup(dfg); - performStructureRegistration(dfg); performInvalidationPointInjection(dfg); performTypeCheckHoisting(dfg); + unsigned count = 1; 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); + for (;; ++count) { + if (logCompilationChanges()) + dataLogF("DFG beginning optimization fixpoint iteration #%u.\n", count); + bool changed = false; - performStrengthReduction(dfg); - performLocalCSE(dfg); - performCPSRethreading(dfg); - performCFA(dfg); - performConstantFolding(dfg); - bool changed = false; - changed |= performCFGSimplification(dfg); - changed |= performLocalCSE(dfg); - - if (validationEnabled()) - validate(dfg); - - performCPSRethreading(dfg); - if (!isFTL(mode)) { - // 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. + if (validationEnabled()) + validate(dfg); - changed |= performVarargsForwarding(dfg); // Do this after CFG simplification and CPS rethreading. - } - if (changed) { + changed |= performStrengthReduction(dfg); performCFA(dfg); - performConstantFolding(dfg); + changed |= performConstantFolding(dfg); + changed |= performArgumentsSimplification(dfg); + changed |= performCFGSimplification(dfg); + changed |= performCSE(dfg); + + if (!changed) + break; + + performCPSRethreading(dfg); } + if (logCompilationChanges()) + dataLogF("DFG optimization fixpoint converged in %u iterations.\n", count); + + dfg.m_fixpointState = FixpointConverged; + + performStoreBarrierElision(dfg); + performStoreElimination(dfg); + // 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.ensureDominators(); - dfg.ensureNaturalLoops(); - dfg.ensurePrePostNumbering(); + dfg.m_dominators.computeIfNecessary(dfg); + dfg.m_naturalLoops.computeIfNecessary(dfg); } switch (mode) { case DFGMode: { - dfg.m_fixpointState = FixpointConverged; - performTierUpCheckInjection(dfg); - performFastStoreBarrierInsertion(dfg); - performCleanUp(dfg); performCPSRethreading(dfg); performDCE(dfg); - if (Options::useCopyBarrierOptimization()) - performCopyBarrierOptimization(dfg); - performPhantomInsertion(dfg); performStackLayout(dfg); performVirtualRegisterAllocation(dfg); performWatchpointCollection(dfg); dumpAndVerifyGraph(dfg, "Graph after optimization:"); JITCompiler dataFlowJIT(dfg); - if (codeBlock->codeType() == FunctionCode) + if (codeBlock->codeType() == FunctionCode) { dataFlowJIT.compileFunction(); - else + dataFlowJIT.linkFunction(); + } else { dataFlowJIT.compile(); + dataFlowJIT.link(); + } return DFGPath; } @@ -378,121 +262,53 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) case FTLForOSREntryMode: { #if ENABLE(FTL_JIT) if (FTL::canCompile(dfg) == FTL::CannotCompile) { - finalizer = std::make_unique<FailedFinalizer>(*this); + finalizer = adoptPtr(new FailedFinalizer(*this)); return FailPath; } - performCleanUp(dfg); // Reduce the graph size a bit. performCriticalEdgeBreaking(dfg); - if (Options::createPreHeaders()) - performLoopPreHeaderCreation(dfg); + performLoopPreHeaderCreation(dfg); performCPSRethreading(dfg); performSSAConversion(dfg); performSSALowering(dfg); - - // Ideally, these would be run to fixpoint with the object allocation sinking phase. - performArgumentsElimination(dfg); - if (Options::usePutStackSinking()) - performPutStackSinking(dfg); - - performConstantHoisting(dfg); - performGlobalCSE(dfg); - performLivenessAnalysis(dfg); - performIntegerRangeOptimization(dfg); performLivenessAnalysis(dfg); performCFA(dfg); - performConstantFolding(dfg); - performCleanUp(dfg); // Reduce the graph size a lot. - changed = false; - changed |= performStrengthReduction(dfg); - if (Options::useObjectAllocationSinking()) { - changed |= performCriticalEdgeBreaking(dfg); - changed |= performObjectAllocationSinking(dfg); - } - if (changed) { - // State-at-tail and state-at-head will be invalid if we did strength reduction since - // it might increase live ranges. - performLivenessAnalysis(dfg); - performCFA(dfg); - performConstantFolding(dfg); - } - - // 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. performLICM(dfg); - - performCleanUp(dfg); - performIntegerCheckCombining(dfg); - performGlobalCSE(dfg); - - // 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; - + performCSE(dfg); performLivenessAnalysis(dfg); performCFA(dfg); - performGlobalStoreBarrierInsertion(dfg); - if (Options::useMovHintRemoval()) - performMovHintRemoval(dfg); - performCleanUp(dfg); - performDCE(dfg); // We rely on this to kill dead code that won't be recognized as dead by B3. - if (Options::useCopyBarrierOptimization()) - performCopyBarrierOptimization(dfg); + if (Options::validateFTLOSRExitLiveness()) + performResurrectionForValidation(dfg); + performDCE(dfg); // We rely on this to convert dead SetLocals into the appropriate hint, and to kill dead code that won't be recognized as dead by LLVM. performStackLayout(dfg); performLivenessAnalysis(dfg); + performFlushLivenessAnalysis(dfg); performOSRAvailabilityAnalysis(dfg); performWatchpointCollection(dfg); - if (FTL::canCompile(dfg) == FTL::CannotCompile) { - finalizer = std::make_unique<FailedFinalizer>(*this); - return FailPath; - } - - dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:", shouldDumpDisassembly(mode)); - - // Flash a safepoint in case the GC wants some action. - Safepoint::Result safepointResult; - { - GraphSafepoint safepoint(dfg, safepointResult); - } - if (safepointResult.didGetCancelled()) - return CancelPath; - - FTL::State state(dfg); - FTL::lowerDFGToB3(state); + dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:"); - if (computeCompileTimes()) - m_timeBeforeFTL = monotonicallyIncreasingTimeMS(); + initializeLLVM(); - if (Options::b3AlwaysFailsBeforeCompile()) { - FTL::fail(state); - return FTLPath; - } + FTL::State state(dfg); + FTL::lowerDFGToLLVM(state); - FTL::compile(state, safepointResult); - if (safepointResult.didGetCancelled()) - return CancelPath; + if (Options::reportCompileTimes()) + beforeFTL = currentTimeMS(); - if (Options::b3AlwaysFailsBeforeLink()) { + if (Options::llvmAlwaysFailsBeforeCompile()) { FTL::fail(state); return FTLPath; } - if (state.allocationFailed) { - FTL::fail(state); - return FTLPath; - } + FTL::compile(state); - FTL::link(state); - - if (state.allocationFailed) { + if (Options::llvmAlwaysFailsBeforeLink()) { FTL::fail(state); return FTLPath; } + FTL::link(state); return FTLPath; #else RELEASE_ASSERT_NOT_REACHED(); @@ -508,52 +324,37 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState) bool Plan::isStillValid() { - CodeBlock* replacement = 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 (codeBlock->alternative() != replacement->baselineVersion()) - return false; - if (!watchpoints.areStillValid()) - return false; - return true; + return watchpoints.areStillValid() + && chains.areStillValid(); } void Plan::reallyAdd(CommonData* commonData) { - watchpoints.reallyAdd(codeBlock, *commonData); + watchpoints.reallyAdd(codeBlock.get(), *commonData); identifiers.reallyAdd(vm, commonData); weakReferences.reallyAdd(vm, commonData); transitions.reallyAdd(vm, commonData); -} - -void Plan::notifyCompiling() -{ - stage = Compiling; -} - -void Plan::notifyCompiled() -{ - stage = Compiled; + writeBarriers.trigger(vm); } void Plan::notifyReady() { - callback->compilationDidBecomeReadyAsynchronously(codeBlock, profiledDFGCodeBlock); - stage = Ready; + callback->compilationDidBecomeReadyAsynchronously(codeBlock.get()); + isCompiled = 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()) return CompilationInvalidated; + if (vm.enabledProfiler()) + return CompilationInvalidated; + + Debugger* debugger = codeBlock->globalObject()->debugger(); + if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests())) + return CompilationInvalidated; + bool result; if (codeBlock->codeType() == FunctionCode) result = finalizer->finalizeFunction(); @@ -565,27 +366,12 @@ CompilationResult Plan::finalizeWithoutNotifyingCallback() 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); - } - return CompilationSuccessful; } void Plan::finalizeAndNotifyCallback() { - callback->compilationDidComplete(codeBlock, profiledDFGCodeBlock, finalizeWithoutNotifyingCallback()); + callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback()); } CompilationKey Plan::key() @@ -593,83 +379,6 @@ CompilationKey Plan::key() return CompilationKey(codeBlock->alternative(), mode); } -void Plan::rememberCodeBlocks() -{ - // Compilation writes lots of values to a CodeBlock without performing - // an explicit barrier. So, we need to be pessimistic and assume that - // all our CodeBlocks must be visited during GC. - - Heap::heap(codeBlock)->writeBarrier(codeBlock); - Heap::heap(codeBlock)->writeBarrier(codeBlock->alternative()); - if (profiledDFGCodeBlock) - Heap::heap(profiledDFGCodeBlock)->writeBarrier(profiledDFGCodeBlock); -} - -void Plan::checkLivenessAndVisitChildren(SlotVisitor& visitor) -{ - if (!isKnownToBeLiveDuringGC()) - return; - - for (unsigned i = mustHandleValues.size(); i--;) - visitor.appendUnbarrieredValue(&mustHandleValues[i]); - - visitor.appendUnbarrieredReadOnlyPointer(codeBlock); - visitor.appendUnbarrieredReadOnlyPointer(codeBlock->alternative()); - visitor.appendUnbarrieredReadOnlyPointer(profiledDFGCodeBlock); - - if (inlineCallFrames) { - for (auto* inlineCallFrame : *inlineCallFrames) { - ASSERT(inlineCallFrame->baselineCodeBlock.get()); - visitor.appendUnbarrieredReadOnlyPointer(inlineCallFrame->baselineCodeBlock.get()); - } - } - - weakReferences.visitChildren(visitor); - transitions.visitChildren(visitor); -} - -bool Plan::isKnownToBeLiveDuringGC() -{ - if (stage == Cancelled) - return false; - if (!Heap::isMarked(codeBlock->ownerExecutable())) - return false; - if (!Heap::isMarked(codeBlock->alternative())) - return false; - if (!!profiledDFGCodeBlock && !Heap::isMarked(profiledDFGCodeBlock)) - return false; - return true; -} - -void Plan::cancel() -{ - codeBlock = nullptr; - profiledDFGCodeBlock = nullptr; - mustHandleValues.clear(); - compilation = nullptr; - finalizer = nullptr; - inlineCallFrames = nullptr; - watchpoints = DesiredWatchpoints(); - identifiers = DesiredIdentifiers(); - weakReferences = DesiredWeakReferences(); - transitions = DesiredTransitions(); - callback = nullptr; - stage = Cancelled; -} - -HashMap<CString, double> Plan::compileTimeStats() -{ - HashMap<CString, double> result; - if (Options::reportTotalCompileTimes()) { - result.add("Compile Time", totalDFGCompileTime + totalFTLCompileTime); - result.add("DFG Compile Time", totalDFGCompileTime); - result.add("FTL Compile Time", totalFTLCompileTime); - result.add("FTL (DFG) Compile Time", totalFTLDFGCompileTime); - result.add("FTL (B3) Compile Time", totalFTLB3CompileTime); - } - return result; -} - } } // namespace JSC::DFG #endif // ENABLE(DFG_JIT) |