diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/dfg/DFGDriver.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGDriver.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGDriver.cpp | 190 |
1 files changed, 65 insertions, 125 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp index 09649cc59..0369848b1 100644 --- a/Source/JavaScriptCore/dfg/DFGDriver.cpp +++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,28 +29,22 @@ #include "JSObject.h" #include "JSString.h" - -#if ENABLE(DFG_JIT) - -#include "DFGArgumentsSimplificationPhase.h" -#include "DFGBackwardsPropagationPhase.h" -#include "DFGByteCodeParser.h" -#include "DFGCFAPhase.h" -#include "DFGCFGSimplificationPhase.h" -#include "DFGCPSRethreadingPhase.h" -#include "DFGCSEPhase.h" -#include "DFGConstantFoldingPhase.h" -#include "DFGDCEPhase.h" -#include "DFGFixupPhase.h" -#include "DFGJITCompiler.h" -#include "DFGPredictionInjectionPhase.h" -#include "DFGPredictionPropagationPhase.h" -#include "DFGTypeCheckHoistingPhase.h" -#include "DFGUnificationPhase.h" -#include "DFGValidate.h" -#include "DFGVirtualRegisterAllocationPhase.h" -#include "Operations.h" +#include "CodeBlock.h" +#include "DFGFunctionWhitelist.h" +#include "DFGJITCode.h" +#include "DFGPlan.h" +#include "DFGThunks.h" +#include "DFGWorklist.h" +#include "JITCode.h" +#include "JSCInlines.h" #include "Options.h" +#include "SamplingTool.h" +#include "TypeProfilerLog.h" +#include <wtf/Atomics.h> + +#if ENABLE(FTL_JIT) +#include "FTLThunks.h" +#endif namespace JSC { namespace DFG { @@ -61,128 +55,74 @@ unsigned getNumCompilations() return numCompilations; } -enum CompileMode { CompileFunction, CompileOther }; -inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex) +#if ENABLE(DFG_JIT) +static CompilationResult compileImpl( + VM& vm, CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationMode mode, + unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues, + PassRefPtr<DeferredCompilationCallback> callback) { SamplingRegion samplingRegion("DFG Compilation (Driver)"); + if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount()) + || !FunctionWhitelist::ensureGlobalWhitelist().contains(codeBlock)) + return CompilationFailed; + numCompilations++; ASSERT(codeBlock); ASSERT(codeBlock->alternative()); - ASSERT(codeBlock->alternative()->getJITType() == JITCode::BaselineJIT); - - ASSERT(osrEntryBytecodeIndex != UINT_MAX); - - if (!Options::useDFGJIT()) - return false; - - if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount())) - return false; - - if (logCompilationChanges()) - dataLog("DFG compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n"); + ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT); + ASSERT(!profiledDFGCodeBlock || profiledDFGCodeBlock->jitType() == JITCode::DFGJIT); - // Derive our set of must-handle values. The compilation must be at least conservative - // enough to allow for OSR entry with these values. - unsigned numVarsWithValues; - if (osrEntryBytecodeIndex) - numVarsWithValues = codeBlock->m_numVars; - else - numVarsWithValues = 0; - Operands<JSValue> mustHandleValues(codeBlock->numParameters(), numVarsWithValues); - for (size_t i = 0; i < mustHandleValues.size(); ++i) { - int operand = mustHandleValues.operandForIndex(i); - if (operandIsArgument(operand) - && !operandToArgument(operand) - && compileMode == CompileFunction - && codeBlock->specializationKind() == CodeForConstruct) { - // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will - // also never be used. It doesn't matter what we put into the value for this, - // but it has to be an actual value that can be grokked by subsequent DFG passes, - // so we sanitize it here by turning it into Undefined. - mustHandleValues[i] = jsUndefined(); - } else - mustHandleValues[i] = exec->uncheckedR(operand).jsValue(); - } - - Graph dfg(exec->vm(), codeBlock, osrEntryBytecodeIndex, mustHandleValues); - if (!parse(exec, dfg)) - return 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. - codeBlock->shrinkToFit(CodeBlock::EarlyShrink); - - if (validationEnabled()) - validate(dfg); + if (logCompilationChanges(mode)) + dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n"); - performCPSRethreading(dfg); - performUnification(dfg); - performPredictionInjection(dfg); + // Make sure that any stubs that the DFG is going to use are initialized. We want to + // make sure that all JIT code generation does finalization on the main thread. + vm.getCTIStub(osrExitGenerationThunkGenerator); + vm.getCTIStub(throwExceptionFromCallSlowPathGenerator); + vm.getCTIStub(linkCallThunkGenerator); + vm.getCTIStub(linkPolymorphicCallThunkGenerator); - if (validationEnabled()) - validate(dfg); + if (vm.typeProfiler()) + vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Preparing for DFG compilation.")); - performBackwardsPropagation(dfg); - performPredictionPropagation(dfg); - performFixup(dfg); - performTypeCheckHoisting(dfg); + RefPtr<Plan> plan = adoptRef( + new Plan(codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues)); - dfg.m_fixpointState = FixpointNotConverged; - - performCSE(dfg); - performArgumentsSimplification(dfg); - performCPSRethreading(dfg); // This should usually be a no-op since CSE rarely dethreads, and arguments simplification rarely does anything. - performCFA(dfg); - performConstantFolding(dfg); - performCFGSimplification(dfg); - - dfg.m_fixpointState = FixpointConverged; - - performStoreElimination(dfg); - performCPSRethreading(dfg); - performDCE(dfg); - performVirtualRegisterAllocation(dfg); - - GraphDumpMode modeForFinalValidate = DumpGraph; - if (verboseCompilationEnabled()) { - dataLogF("Graph after optimization:\n"); - dfg.dump(); - modeForFinalValidate = DontDumpGraph; + plan->callback = callback; + if (Options::useConcurrentJIT()) { + Worklist* worklist = ensureGlobalWorklistFor(mode); + if (logCompilationChanges(mode)) + dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", worklist->queueLength(), ".\n"); + worklist->enqueue(plan); + return CompilationDeferred; } - if (validationEnabled()) - validate(dfg, modeForFinalValidate); - JITCompiler dataFlowJIT(dfg); - bool result; - if (compileMode == CompileFunction) { - ASSERT(jitCodeWithArityCheck); - - result = dataFlowJIT.compileFunction(jitCode, *jitCodeWithArityCheck); - } else { - ASSERT(compileMode == CompileOther); - ASSERT(!jitCodeWithArityCheck); - - result = dataFlowJIT.compile(jitCode); - } - - return result; + plan->compileInThread(*vm.dfgState, 0); + return plan->finalizeWithoutNotifyingCallback(); } - -bool tryCompile(ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, unsigned bytecodeIndex) +#else // ENABLE(DFG_JIT) +static CompilationResult compileImpl( + VM&, CodeBlock*, CodeBlock*, CompilationMode, unsigned, const Operands<JSValue>&, + PassRefPtr<DeferredCompilationCallback>) { - return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex); + return CompilationFailed; } +#endif // ENABLE(DFG_JIT) -bool tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex) +CompilationResult compile( + VM& vm, CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationMode mode, + unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues, + PassRefPtr<DeferredCompilationCallback> passedCallback) { - return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck, bytecodeIndex); + RefPtr<DeferredCompilationCallback> callback = passedCallback; + CompilationResult result = compileImpl( + vm, codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues, + callback); + if (result != CompilationDeferred) + callback->compilationDidComplete(codeBlock, profiledDFGCodeBlock, result); + return result; } } } // namespace JSC::DFG - -#endif // ENABLE(DFG_JIT) - |