summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGDriver.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/dfg/DFGDriver.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-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.cpp190
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)
-