Ignore:
Timestamp:
Jul 24, 2013, 9:00:13 PM (12 years ago)
Author:
[email protected]
Message:

fourthTier: DFG should separate link phase into things that must be done concurrently and things that must be done synchronously, and have a way of passing data from one to the other
https://bugs.webkit.org/show_bug.cgi?id=116060

Reviewed by Gavin Barraclough.

This introduces the concept of a DFG::Plan, which corresponds to:

  • The data that the concurrent DFG or FTL need to start compiling a CodeBlock. This mostly includes basic things like CodeBlock*, but also a list of must-handle values for OSR entry.
  • The data that the synchronous linker need to link in code compiled by a concurrent compilation thread. This is further encapsulated by DFG::Finalizer, since the data, and the actions that need to be taken, are different in DFG versus FTL. This patch also institutes the policy that the concurrent compilation thread shall not use LinkBuffer::performFinalization(), since that code assumes that it's running on the same thread that will actually run the code.
  • The actions that need to be taken to compile code. In other words, most of the code that previously lived in DFGDriver.cpp now lives in DFG::Plan::compileInThread().
  • The actions that need to be taken when synchronously linking the code. This includes "really" adding watchpoints and identifiers, checking watchpoint and chain validity, and running the DFG::Finalizer.

Currently, DFGDriver just creates a Plan and runs it synchronously. But in the
future, we will be able to malloc some Plans and enqueue them, and have the
concurrent thread dequeue them and call Plan::compileInThread().

For now, this has no behavior or performance change.

(JSC::LinkBuffer::performFinalization):

  • assembler/LinkBuffer.h:

(LinkBuffer):
(JSC::LinkBuffer::LinkBuffer):
(JSC::LinkBuffer::~LinkBuffer):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::initialize):
(JSC::DFG::AbstractState::executeEffects):

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::setFuturePossibleStructure):
(JSC::DFG::AbstractValue::filterFuturePossibleStructure):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::addStructureTransitionCheck):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseResolveOperations):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):

  • dfg/DFGDriver.cpp:

(DFG):
(JSC::DFG::compile):

  • dfg/DFGFailedFinalizer.cpp: Added.

(DFG):
(JSC::DFG::FailedFinalizer::FailedFinalizer):
(JSC::DFG::FailedFinalizer::~FailedFinalizer):
(JSC::DFG::FailedFinalizer::finalize):
(JSC::DFG::FailedFinalizer::finalizeFunction):

  • dfg/DFGFailedFinalizer.h: Added.

(DFG):
(FailedFinalizer):

  • dfg/DFGFinalizer.cpp: Added.

(DFG):
(JSC::DFG::Finalizer::Finalizer):
(JSC::DFG::Finalizer::~Finalizer):

  • dfg/DFGFinalizer.h: Added.

(DFG):
(Finalizer):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(DFG):

  • dfg/DFGGraph.h:

(Graph):
(JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
(JSC::DFG::Graph::compilation):
(JSC::DFG::Graph::identifiers):
(JSC::DFG::Graph::watchpoints):
(JSC::DFG::Graph::chains):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
(JSC::DFG::JITCompiler::linkFunction):
(DFG):
(JSC::DFG::JITCompiler::disassemble):

  • dfg/DFGJITCompiler.h:

(JITCompiler):
(JSC::DFG::JITCompiler::addLazily):

  • dfg/DFGJITFinalizer.cpp: Added.

(DFG):
(JSC::DFG::JITFinalizer::JITFinalizer):
(JSC::DFG::JITFinalizer::~JITFinalizer):
(JSC::DFG::JITFinalizer::finalize):
(JSC::DFG::JITFinalizer::finalizeFunction):
(JSC::DFG::JITFinalizer::finalizeCommon):

  • dfg/DFGJITFinalizer.h: Added.

(DFG):
(JITFinalizer):

  • dfg/DFGPlan.cpp: Added.

(DFG):
(JSC::DFG::dumpAndVerifyGraph):
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::~Plan):
(JSC::DFG::Plan::compileInThread):
(JSC::DFG::Plan::isStillValid):
(JSC::DFG::Plan::reallyAdd):
(JSC::DFG::Plan::finalize):

  • dfg/DFGPlan.h: Added.

(DFG):
(Plan):
(JSC::DFG::Plan::vm):

  • dfg/DFGPredictionInjectionPhase.cpp:

(JSC::DFG::PredictionInjectionPhase::run):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::identifierUID):
(JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):

  • dfg/DFGTypeCheckHoistingPhase.cpp:

(JSC::DFG::TypeCheckHoistingPhase::run):

  • ftl/FTLGeneratedFunction.h: Added.

(FTL):

  • ftl/FTLJITFinalizer.cpp: Added.

(FTL):
(JSC::FTL::JITFinalizer::JITFinalizer):
(JSC::FTL::JITFinalizer::~JITFinalizer):
(JSC::FTL::JITFinalizer::finalize):
(JSC::FTL::JITFinalizer::finalizeFunction):

  • ftl/FTLJITFinalizer.h: Added.

(FTL):
(JITFinalizer):
(JSC::FTL::JITFinalizer::initializeExitThunksLinkBuffer):
(JSC::FTL::JITFinalizer::initializeEntrypointLinkBuffer):
(JSC::FTL::JITFinalizer::initializeCode):
(JSC::FTL::JITFinalizer::initializeFunction):
(JSC::FTL::JITFinalizer::initializeArityCheck):
(JSC::FTL::JITFinalizer::initializeJITCode):

  • ftl/FTLLink.cpp:

(JSC::FTL::link):

  • ftl/FTLLink.h:

(FTL):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):

  • ftl/FTLState.cpp:

(JSC::FTL::State::State):

  • ftl/FTLState.h:

(FTL):
(State):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp

    r153144 r153161  
    3030#include "JSString.h"
    3131
    32 
    3332#if ENABLE(DFG_JIT)
    3433
    35 #include "DFGArgumentsSimplificationPhase.h"
    36 #include "DFGBackwardsPropagationPhase.h"
    37 #include "DFGByteCodeParser.h"
    38 #include "DFGCFAPhase.h"
    39 #include "DFGCFGSimplificationPhase.h"
    40 #include "DFGCPSRethreadingPhase.h"
    41 #include "DFGCSEPhase.h"
    42 #include "DFGConstantFoldingPhase.h"
    43 #include "DFGDCEPhase.h"
    44 #include "DFGFixupPhase.h"
    45 #include "DFGJITCompiler.h"
    46 #include "DFGPredictionInjectionPhase.h"
    47 #include "DFGPredictionPropagationPhase.h"
    48 #include "DFGTypeCheckHoistingPhase.h"
    49 #include "DFGUnificationPhase.h"
    50 #include "DFGValidate.h"
    51 #include "DFGVirtualRegisterAllocationPhase.h"
    52 #include "FTLCapabilities.h"
    53 #include "FTLCompile.h"
    54 #include "FTLLink.h"
    55 #include "FTLLowerDFGToLLVM.h"
    56 #include "FTLState.h"
     34#include "DFGJITCode.h"
     35#include "DFGPlan.h"
     36#include "DFGThunks.h"
     37#include "FTLThunks.h"
     38#include "JITCode.h"
    5739#include "Operations.h"
    5840#include "Options.h"
    59 #include <wtf/CompilationThread.h>
    6041
    6142namespace JSC { namespace DFG {
     
    6849}
    6950
    70 static void dumpAndVerifyGraph(Graph& graph, const char* text)
    71 {
    72     GraphDumpMode modeForFinalValidate = DumpGraph;
    73     if (verboseCompilationEnabled()) {
    74         dataLog(text, "\n");
    75         graph.dump();
    76         modeForFinalValidate = DontDumpGraph;
    77     }
    78     if (validationEnabled())
    79         validate(graph, modeForFinalValidate);
    80 }
    81 
    82 enum CompileMode { CompileFunction, CompileOther };
    8351static bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
    8452{
    8553    SamplingRegion samplingRegion("DFG Compilation (Driver)");
    86     CompilationScope compilationScope;
    8754   
    8855    numCompilations++;
     
    10370        dataLog("DFG compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n");
    10471   
     72    // Make sure that any stubs that the DFG is going to use are initialized. We want to
     73    // make sure that al JIT code generation does finalization on the main thread.
     74    exec->vm().getCTIStub(osrExitGenerationThunkGenerator);
     75    exec->vm().getCTIStub(throwExceptionFromCallSlowPathGenerator);
     76    exec->vm().getCTIStub(linkCallThunkGenerator);
     77    exec->vm().getCTIStub(linkConstructThunkGenerator);
     78    exec->vm().getCTIStub(linkClosureCallThunkGenerator);
     79    exec->vm().getCTIStub(virtualCallThunkGenerator);
     80    exec->vm().getCTIStub(virtualConstructThunkGenerator);
     81#if ENABLE(FTL_JIT)
     82    exec->vm().getCTIStub(FTL::osrExitGenerationThunkGenerator);
     83#endif
     84   
    10585    // Derive our set of must-handle values. The compilation must be at least conservative
    10686    // enough to allow for OSR entry with these values.
     
    11090    else
    11191        numVarsWithValues = 0;
    112     Operands<JSValue> mustHandleValues(codeBlock->numParameters(), numVarsWithValues);
    113     for (size_t i = 0; i < mustHandleValues.size(); ++i) {
    114         int operand = mustHandleValues.operandForIndex(i);
     92    Plan plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues);
     93    for (size_t i = 0; i < plan.mustHandleValues.size(); ++i) {
     94        int operand = plan.mustHandleValues.operandForIndex(i);
    11595        if (operandIsArgument(operand)
    11696            && !operandToArgument(operand)
     
    121101            // but it has to be an actual value that can be grokked by subsequent DFG passes,
    122102            // so we sanitize it here by turning it into Undefined.
    123             mustHandleValues[i] = jsUndefined();
     103            plan.mustHandleValues[i] = jsUndefined();
    124104        } else
    125             mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
     105            plan.mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
    126106    }
    127107   
    128     Graph dfg(exec->vm(), codeBlock, osrEntryBytecodeIndex, mustHandleValues);
    129     if (!parse(dfg))
     108    plan.compileInThread();
     109    if (plan.finalize(jitCode, jitCodeWithArityCheck) != CompilationSuccessful)
    130110        return false;
    131    
    132     // By this point the DFG bytecode parser will have potentially mutated various tables
    133     // in the CodeBlock. This is a good time to perform an early shrink, which is more
    134     // powerful than a late one. It's safe to do so because we haven't generated any code
    135     // that references any of the tables directly, yet.
    136     codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
    137 
    138     if (validationEnabled())
    139         validate(dfg);
    140    
    141     performCPSRethreading(dfg);
    142     performUnification(dfg);
    143     performPredictionInjection(dfg);
    144    
    145     if (validationEnabled())
    146         validate(dfg);
    147    
    148     performBackwardsPropagation(dfg);
    149     performPredictionPropagation(dfg);
    150     performFixup(dfg);
    151     performTypeCheckHoisting(dfg);
    152    
    153     dfg.m_fixpointState = FixpointNotConverged;
    154 
    155     performCSE(dfg);
    156     performArgumentsSimplification(dfg);
    157     performCPSRethreading(dfg); // This should usually be a no-op since CSE rarely dethreads, and arguments simplification rarely does anything.
    158     performCFA(dfg);
    159     performConstantFolding(dfg);
    160     performCFGSimplification(dfg);
    161 
    162     dfg.m_fixpointState = FixpointConverged;
    163 
    164     performStoreElimination(dfg);
    165     performCPSRethreading(dfg);
    166     performDCE(dfg);
    167 
    168 #if ENABLE(FTL_JIT)
    169     if (Options::useExperimentalFTL()
    170         && compileMode == CompileFunction
    171         && FTL::canCompile(dfg)) {
    172        
    173         dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:");
    174        
    175         // FIXME: Support OSR entry.
    176         // https://bugs.webkit.org/show_bug.cgi?id=113625
    177        
    178         FTL::State state(dfg);
    179         FTL::lowerDFGToLLVM(state);
    180         FTL::compile(state);
    181         compilationScope.leaveEarly();
    182         return FTL::link(state, jitCode, *jitCodeWithArityCheck);
    183     }
    184 #endif // ENABLE(FTL_JIT)
    185    
    186     performVirtualRegisterAllocation(dfg);
    187     dumpAndVerifyGraph(dfg, "Graph after optimization:");
    188 
    189     JITCompiler dataFlowJIT(dfg);
    190     bool result;
    191     if (compileMode == CompileFunction) {
    192         ASSERT(jitCodeWithArityCheck);
    193        
    194         if (!dataFlowJIT.compileFunction())
    195             return false;
    196         compilationScope.leaveEarly();
    197         result = dataFlowJIT.linkFunction(jitCode, *jitCodeWithArityCheck);
    198     } else {
    199         ASSERT(compileMode == CompileOther);
    200         ASSERT(!jitCodeWithArityCheck);
    201        
    202         if (!dataFlowJIT.compile())
    203             return false;
    204         compilationScope.leaveEarly();
    205         result = dataFlowJIT.link(jitCode);
    206     }
    207    
    208     return result;
     111    return true;
    209112}
    210113
Note: See TracChangeset for help on using the changeset viewer.