Commit 1342e7a8 authored by fpizlo@apple.com's avatar fpizlo@apple.com

CodeBlock::prepareForExecution() is silly

https://bugs.webkit.org/show_bug.cgi?id=120453

Reviewed by Oliver Hunt.
        
Instead of saying:
        
    codeBlock->prepareForExecution(stuff, BaselineJIT, more stuff)
        
we should just say:
        
    JIT::compile(stuff, codeBlock, more stuff);
        
And similarly for the LLInt and DFG.
        
This kills a bunch of code, since CodeBlock::prepareForExecution() is just a
wrapper that uses the JITType argument to call into the appropriate execution
engine, which is what the user wanted to do in the first place.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
(JSC::DFG::compile):
* dfg/DFGDriver.h:
(JSC::DFG::tryCompile):
* dfg/DFGOSRExitPreparation.cpp:
(JSC::DFG::prepareCodeOriginForOSRExit):
* dfg/DFGWorklist.cpp:
(JSC::DFG::globalWorklist):
* dfg/DFGWorklist.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JSC::JIT::compile):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntEntrypoint.cpp: Copied from Source/JavaScriptCore/llint/LLIntEntrypoints.cpp.
(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
(JSC::LLInt::setEntrypoint):
* llint/LLIntEntrypoint.h: Copied from Source/JavaScriptCore/llint/LLIntEntrypoints.h.
* llint/LLIntEntrypoints.cpp: Removed.
* llint/LLIntEntrypoints.h: Removed.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/Executable.cpp:
(JSC::ScriptExecutable::prepareForExecutionImpl):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 63a45cfe
......@@ -528,7 +528,7 @@ if (ENABLE_LLINT)
list(APPEND JavaScriptCore_SOURCES
llint/LLIntCLoop.cpp
llint/LLIntData.cpp
llint/LLIntEntrypoints.cpp
llint/LLIntEntrypoint.cpp
llint/LLIntExceptions.cpp
llint/LLIntSlowPaths.cpp
llint/LLIntThunks.cpp
......
2013-08-29 Filip Pizlo <fpizlo@apple.com>
CodeBlock::prepareForExecution() is silly
https://bugs.webkit.org/show_bug.cgi?id=120453
Reviewed by Oliver Hunt.
Instead of saying:
codeBlock->prepareForExecution(stuff, BaselineJIT, more stuff)
we should just say:
JIT::compile(stuff, codeBlock, more stuff);
And similarly for the LLInt and DFG.
This kills a bunch of code, since CodeBlock::prepareForExecution() is just a
wrapper that uses the JITType argument to call into the appropriate execution
engine, which is what the user wanted to do in the first place.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
(JSC::DFG::compile):
* dfg/DFGDriver.h:
(JSC::DFG::tryCompile):
* dfg/DFGOSRExitPreparation.cpp:
(JSC::DFG::prepareCodeOriginForOSRExit):
* dfg/DFGWorklist.cpp:
(JSC::DFG::globalWorklist):
* dfg/DFGWorklist.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JSC::JIT::compile):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntEntrypoint.cpp: Copied from Source/JavaScriptCore/llint/LLIntEntrypoints.cpp.
(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
(JSC::LLInt::setEntrypoint):
* llint/LLIntEntrypoint.h: Copied from Source/JavaScriptCore/llint/LLIntEntrypoints.h.
* llint/LLIntEntrypoints.cpp: Removed.
* llint/LLIntEntrypoints.h: Removed.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/Executable.cpp:
(JSC::ScriptExecutable::prepareForExecutionImpl):
2013-08-29 Mark Lam <mark.lam@apple.com>
Gardening: fixed broken non-DFG build.
......
......@@ -645,8 +645,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/llint/LLIntCLoop.h \
Source/JavaScriptCore/llint/LLIntData.cpp \
Source/JavaScriptCore/llint/LLIntData.h \
Source/JavaScriptCore/llint/LLIntEntrypoints.cpp \
Source/JavaScriptCore/llint/LLIntEntrypoints.h \
Source/JavaScriptCore/llint/LLIntEntrypoint.cpp \
Source/JavaScriptCore/llint/LLIntEntrypoint.h \
Source/JavaScriptCore/llint/LLIntExceptions.cpp \
Source/JavaScriptCore/llint/LLIntExceptions.h \
Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h \
......
......@@ -383,7 +383,7 @@
<ClCompile Include="..\jit\ThunkGenerators.cpp" />
<ClCompile Include="..\llint\LLIntCLoop.cpp" />
<ClCompile Include="..\llint\LLIntData.cpp" />
<ClCompile Include="..\llint\LLIntEntrypoints.cpp" />
<ClCompile Include="..\llint\LLIntEntrypoint.cpp" />
<ClCompile Include="..\llint\LLIntExceptions.cpp" />
<ClCompile Include="..\llint\LLIntOffsetsExtractor.cpp" />
<ClCompile Include="..\llint\LLIntSlowPaths.cpp" />
......@@ -762,7 +762,7 @@
<ClInclude Include="..\llint\LLIntCLoop.h" />
<ClInclude Include="..\llint\LLIntCommon.h" />
<ClInclude Include="..\llint\LLIntData.h" />
<ClInclude Include="..\llint\LLIntEntrypoints.h" />
<ClInclude Include="..\llint\LLIntEntrypoint.h" />
<ClInclude Include="..\llint\LLIntExceptions.h" />
<ClInclude Include="..\llint\LLIntOfflineAsmConfig.h" />
<ClInclude Include="..\llint\LLIntOpcode.h" />
......
......@@ -60,8 +60,6 @@
/* Begin PBXBuildFile section */
0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0776BD14FF002800102332 /* JITCompilationEffort.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */; };
0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */; };
0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839814BCF45A00885B4F /* LLIntThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0B83A714BCF50700885B4F /* CodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A514BCF50400885B4F /* CodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -189,6 +187,8 @@
0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */; };
0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */; };
......@@ -1217,8 +1217,6 @@
/* Begin PBXFileReference section */
0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayifySlowPathGenerator.h; path = dfg/DFGArrayifySlowPathGenerator.h; sourceTree = "<group>"; };
0F0776BD14FF002800102332 /* JITCompilationEffort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCompilationEffort.h; sourceTree = "<group>"; };
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
......@@ -1345,6 +1343,8 @@
0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccessStructureList.h; sourceTree = "<group>"; };
0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = "<group>"; };
0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoint.h; path = llint/LLIntEntrypoint.h; sourceTree = "<group>"; };
0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantFoldingPhase.cpp; path = dfg/DFGConstantFoldingPhase.cpp; sourceTree = "<group>"; };
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGConstantFoldingPhase.h; path = dfg/DFGConstantFoldingPhase.h; sourceTree = "<group>"; };
0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFGSimplificationPhase.cpp; path = dfg/DFGCFGSimplificationPhase.cpp; sourceTree = "<group>"; };
......@@ -2454,8 +2454,8 @@
0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */,
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */,
0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */,
0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
......@@ -3941,6 +3941,7 @@
86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */,
0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
......@@ -4153,7 +4154,6 @@
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
......@@ -4972,7 +4972,6 @@
A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */,
FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
......@@ -5031,6 +5030,7 @@
0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */,
14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */,
0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */,
14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */,
ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */,
1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
......
......@@ -227,7 +227,7 @@ SOURCES += \
jit/ThunkGenerators.cpp \
llint/LLIntCLoop.cpp \
llint/LLIntData.cpp \
llint/LLIntEntrypoints.cpp \
llint/LLIntEntrypoint.cpp \
llint/LLIntExceptions.cpp \
llint/LLIntSlowPaths.cpp \
llint/LLIntThunks.cpp \
......
......@@ -46,7 +46,6 @@
#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSNameScope.h"
#include "LLIntEntrypoints.h"
#include "LowLevelInterpreter.h"
#include "Operations.h"
#include "PolymorphicPutByIdList.h"
......@@ -2693,77 +2692,6 @@ void CodeBlock::copyPostParseDataFromAlternative()
copyPostParseDataFrom(m_alternative.get());
}
CompilationResult CodeBlock::prepareForExecutionImpl(
ExecState* exec, JITCode::JITType jitType, JITCompilationEffort effort,
unsigned bytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
{
VM& vm = exec->vm();
if (jitType == JITCode::InterpreterThunk) {
#if ENABLE(LLINT)
switch (codeType()) {
case GlobalCode:
LLInt::setProgramEntrypoint(vm, static_cast<ProgramCodeBlock*>(this));
break;
case EvalCode:
LLInt::setEvalEntrypoint(vm, static_cast<EvalCodeBlock*>(this));
break;
case FunctionCode:
LLInt::setFunctionEntrypoint(vm, static_cast<FunctionCodeBlock*>(this));
break;
}
return CompilationSuccessful;
#else // ENABLE(LLINT)
return CompilationFailed;
#endif // ENABLE(LLINT)
}
#if ENABLE(JIT)
if (JITCode::isOptimizingJIT(jitType)) {
ASSERT(effort == JITCompilationCanFail);
bool hadCallback = !!callback;
CompilationResult result = DFG::tryCompile(exec, this, bytecodeIndex, callback);
ASSERT_UNUSED(hadCallback, result != CompilationDeferred || hadCallback);
return result;
}
MacroAssemblerCodePtr jitCodeWithArityCheck;
RefPtr<JITCode> jitCode = JIT::compile(&vm, this, effort, &jitCodeWithArityCheck);
if (!jitCode)
return CompilationFailed;
setJITCode(jitCode, jitCodeWithArityCheck);
return CompilationSuccessful;
#else
UNUSED_PARAM(effort);
UNUSED_PARAM(bytecodeIndex);
UNUSED_PARAM(callback);
return CompilationFailed;
#endif // ENABLE(JIT)
}
CompilationResult CodeBlock::prepareForExecution(
ExecState* exec, JITCode::JITType jitType,
JITCompilationEffort effort, unsigned bytecodeIndex)
{
CompilationResult result =
prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, 0);
ASSERT(result != CompilationDeferred);
return result;
}
CompilationResult CodeBlock::prepareForExecutionAsynchronously(
ExecState* exec, JITCode::JITType jitType,
PassRefPtr<DeferredCompilationCallback> passedCallback,
JITCompilationEffort effort, unsigned bytecodeIndex)
{
RefPtr<DeferredCompilationCallback> callback = passedCallback;
CompilationResult result =
prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, callback);
if (result != CompilationDeferred)
callback->compilationDidComplete(this, result);
return result;
}
void CodeBlock::install()
{
ownerExecutable()->installCode(this);
......
......@@ -265,32 +265,6 @@ public:
int argumentIndexAfterCapture(size_t argument);
// Prepares this code block for execution. This is synchronous. This compile
// may fail, if you passed JITCompilationCanFail.
CompilationResult prepareForExecution(
ExecState*, JITCode::JITType,
JITCompilationEffort = JITCompilationMustSucceed,
unsigned bytecodeIndex = UINT_MAX);
// Use this method for asynchronous compiles. This will do a compile at some
// point in time between when you called into this method and some point in the
// future. If you're lucky then it might complete before this method returns.
// Once it completes, the callback is called with the result. If the compile
// did happen to complete before the method returns, the result of the compile
// may be returned. If the compile didn't happen to complete yet, or if we
// didn't happen to notice that the compile already completed, we return
// CompilationDeferred.
//
// Note that asynchronous compiles don't actually complete unless you call into
// DFG::Worklist::completeAllReadyPlansForVM(). You usually force a call to
// this on the main thread by listening to the callback's
// compilationDidBecomeReadyAsynchronously() notification. Note that this call
// happens on another thread.
CompilationResult prepareForExecutionAsynchronously(
ExecState*, JITCode::JITType, PassRefPtr<DeferredCompilationCallback>,
JITCompilationEffort = JITCompilationMustSucceed,
unsigned bytecodeIndex = UINT_MAX);
// Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock);
void install();
......@@ -1004,10 +978,6 @@ protected:
private:
friend class DFGCodeBlocks;
CompilationResult prepareForExecutionImpl(
ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex,
PassRefPtr<DeferredCompilationCallback>);
void noticeIncomingCall(ExecState* callerFrame);
double optimizationThresholdScalingFactor();
......
......@@ -29,8 +29,6 @@
#include "JSObject.h"
#include "JSString.h"
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
#include "DFGJITCode.h"
#include "DFGPlan.h"
......@@ -55,7 +53,8 @@ unsigned getNumCompilations()
return numCompilations;
}
CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
#if ENABLE(DFG_JIT)
static CompilationResult compileImpl(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback, Worklist* worklist)
{
SamplingRegion samplingRegion("DFG Compilation (Driver)");
......@@ -115,21 +114,31 @@ CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osr
plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
}
if (enableConcurrentJIT() && callback) {
if (worklist) {
plan->callback = callback;
if (!vm.worklist)
vm.worklist = globalWorklist();
if (logCompilationChanges())
dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", vm.worklist->queueLength(), ".\n");
vm.worklist->enqueue(plan);
dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", worklist->queueLength(), ".\n");
worklist->enqueue(plan);
return CompilationDeferred;
}
plan->compileInThread(*vm.dfgState);
return plan->finalizeWithoutNotifyingCallback();
}
} } // namespace JSC::DFG
#else // ENABLE(DFG_JIT)
static CompilationResult compileImpl(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>, Worklist*)
{
return CompilationFailed;
}
#endif // ENABLE(DFG_JIT)
CompilationResult compile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> passedCallback, Worklist* worklist)
{
RefPtr<DeferredCompilationCallback> callback = passedCallback;
CompilationResult result = compileImpl(exec, codeBlock, osrEntryBytecodeIndex, callback, worklist);
if (result != CompilationDeferred)
callback->compilationDidComplete(codeBlock, result);
return result;
}
} } // namespace JSC::DFG
......@@ -34,19 +34,25 @@ namespace JSC {
class CodeBlock;
class JITCode;
class VM;
class MacroAssemblerCodePtr;
class VM;
namespace DFG {
class Worklist;
JS_EXPORT_PRIVATE unsigned getNumCompilations();
#if ENABLE(DFG_JIT)
CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>);
CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>, Worklist*);
#else
inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; }
inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>, Worklist*) { return CompilationFailed; }
#endif
// If the worklist is non-null, we do a concurrent compile. Otherwise we do a synchronous
// compile. Even if we do a synchronous compile, we call the callback with the result.
CompilationResult compile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>, Worklist*);
} } // namespace JSC::DFG
#endif
......
......@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "Executable.h"
#include "JIT.h"
#include "JITCode.h"
#include "Operations.h"
......@@ -37,7 +38,8 @@ namespace JSC { namespace DFG {
void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
{
DeferGC deferGC(exec->vm().heap);
VM& vm = exec->vm();
DeferGC deferGC(vm.heap);
for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
FunctionExecutable* executable =
......@@ -48,9 +50,7 @@ void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
if (codeBlock->jitType() == JSC::JITCode::BaselineJIT)
continue;
ASSERT(codeBlock->jitType() == JSC::JITCode::InterpreterThunk);
CompilationResult result = codeBlock->prepareForExecution(
exec, JSC::JITCode::BaselineJIT, JITCompilationMustSucceed);
ASSERT_UNUSED(result, result == CompilationSuccessful);
JIT::compile(&vm, codeBlock, JITCompilationMustSucceed);
codeBlock->install();
}
}
......
......@@ -277,6 +277,8 @@ static void initializeGlobalWorklistOnce()
Worklist* globalWorklist()
{
if (!enableConcurrentJIT())
return 0;
pthread_once(&initializeGlobalWorklistKeyOnce, initializeGlobalWorklistOnce);
return theGlobalWorklist;
}
......
......@@ -97,8 +97,10 @@ private:
// For now we use a single global worklist. It's not clear that this
// is the right thing to do, but it is what we do, for now. This function
// will lazily create one when it's needed. Currently this is only called
// from DFGDriver.cpp, when it actually wants to enqueue something.
// will lazily create one when it's needed.
//
// This returns null if for any reason we shouldn't be doing concurrent
// compilation.
Worklist* globalWorklist();
} } // namespace JSC::DFG
......
......@@ -520,7 +520,7 @@ ALWAYS_INLINE void PropertyStubCompilationInfo::copyToStubInfo(StructureStubInfo
}
}
PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort effort)
CompilationResult JIT::privateCompile(JITCompilationEffort effort)
{
#if ENABLE(VALUE_PROFILER)
DFG::CapabilityLevel level = m_codeBlock->capabilityLevel();
......@@ -668,7 +668,7 @@ PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCom
LinkBuffer patchBuffer(*m_vm, this, m_codeBlock, effort);
if (patchBuffer.didFailToAllocate())
return PassRefPtr<JITCode>();
return CompilationFailed;
// Translate vPC offsets into addresses in JIT generated code, for switch tables.
for (unsigned i = 0; i < m_switches.size(); ++i) {
......@@ -755,8 +755,9 @@ PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCom
}
#endif
if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
*functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
MacroAssemblerCodePtr withArityCheck;
if (m_codeBlock->codeType() == FunctionCode)
withArityCheck = patchBuffer.locationOf(arityCheck);
if (Options::showDisassembly())
m_disassembler->dump(patchBuffer);
......@@ -772,12 +773,15 @@ PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCom
static_cast<double>(m_codeBlock->instructions().size()));
m_codeBlock->shrinkToFit(CodeBlock::LateShrink);
m_codeBlock->setJITCode(
adoptRef(new DirectJITCode(result, JITCode::BaselineJIT)),
withArityCheck);
#if ENABLE(JIT_VERBOSE)
dataLogF("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start(), result.executableMemory()->end());
#endif
return adoptRef(new DirectJITCode(result, JITCode::BaselineJIT));
return CompilationSuccessful;
}
void JIT::linkFor(ExecState* exec, JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, VM* vm, CodeSpecializationKind kind)
......
......@@ -298,9 +298,9 @@ namespace JSC {
static const int patchPutByIdDefaultOffset = 256;
public:
static PassRefPtr<JITCode> compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck = 0)
static CompilationResult compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort)
{
return JIT(vm, codeBlock).privateCompile(functionEntryArityCheck, effort);
return JIT(vm, codeBlock).privateCompile(effort);
}
static void compileClosureCall(VM* vm, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
......@@ -403,7 +403,7 @@ namespace JSC {
void privateCompileMainPass();
void privateCompileLinkPass();
void privateCompileSlowCases();
PassRefPtr<JITCode> privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
CompilationResult privateCompile(JITCompilationEffort);
void privateCompileClosureCall(CallLinkInfo*, CodeBlock* calleeCodeBlock, Structure*, ExecutableBase*, MacroAssemblerCodePtr);
......
......@@ -40,6 +40,7 @@
#include "CodeBlock.h"
#include "CodeProfiling.h"
#include "CommonSlowPaths.h"
#include "DFGDriver.h"
#include "DFGOSREntry.h"
#include "DFGWorklist.h"
#include "Debugger.h"
......@@ -906,6 +907,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
VM& vm = callFrame->vm();
unsigned bytecodeIndex = stackFrame.args[0].int32();
if (bytecodeIndex) {
......@@ -945,12 +947,12 @@ DEFINE_STUB_FUNCTION(void, optimize)
// We cannot be in the process of asynchronous compilation and also have an optimized
// replacement.
ASSERT(
!stackFrame.vm->worklist
|| !(stackFrame.vm->worklist->compilationState(codeBlock) != DFG::Worklist::NotKnown
!vm.worklist
|| !(vm.worklist->compilationState(codeBlock) != DFG::Worklist::NotKnown
&& codeBlock->hasOptimizedReplacement()));
DFG::Worklist::State worklistState;
if (stackFrame.vm->worklist) {
if (vm.worklist) {
// The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
// (i.e. compiled) code blocks. But if it completes ours, we also need to know
// what the result was so that we don't plow ahead and attempt OSR or immediate
......@@ -971,7 +973,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
// optimized code is already available.
worklistState =
stackFrame.vm->worklist->completeAllReadyPlansForVM(*stackFrame.vm, codeBlock);
vm.worklist->completeAllReadyPlansForVM(vm, codeBlock);
} else
worklistState = DFG::Worklist::NotKnown;
......@@ -1036,8 +1038,12 @@ DEFINE_STUB_FUNCTION(void, optimize)
RefPtr<DeferredCompilationCallback> callback =
JITToDFGDeferredCompilationCallback::create();
RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement();
CompilationResult result = newCodeBlock->prepareForExecutionAsynchronously(
callFrame, JITCode::DFGJIT, callback, JITCompilationCanFail, bytecodeIndex);
if (!vm.worklist)
vm.worklist = DFG::globalWorklist();
CompilationResult result = DFG::compile(
callFrame, newCodeBlock.get(), bytecodeIndex, callback, vm.worklist.get());
if (result != CompilationSuccessful)
return;
......
......@@ -24,7 +24,7 @@
*/
#include "config.h"
#include "LLIntEntrypoints.h"
#include "LLIntEntrypoint.h"
#if ENABLE(LLINT)
......@@ -38,7 +38,7 @@
namespace JSC { namespace LLInt {
void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
static void setFunctionEntrypoint(VM& vm, CodeBlock* codeBlock)
{
CodeSpecializationKind kind = codeBlock->specializationKind();
......@@ -72,7 +72,7 @@ void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
#endif // ENABLE(JIT)
}
void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
static void setEvalEntrypoint(VM& vm, CodeBlock* codeBlock)
{
if (!vm.canUseJIT()) {
codeBlock->setJITCode(
......@@ -87,7 +87,7 @@ void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
#endif
}
void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
static void setProgramEntrypoint(VM& vm, CodeBlock* codeBlock)
{
if (!vm.canUseJIT()) {
codeBlock->setJITCode(
......@@ -102,6 +102,23 @@ void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
#endif
}
void setEntrypoint(VM& vm, CodeBlock* codeBlock)
{
switch (codeBlock->codeType()) {
case GlobalCode:
setProgramEntrypoint(vm, codeBlock);
return;
case EvalCode:
setEvalEntrypoint(vm, codeBlock);