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.
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 \
<ClCompile Include="..\jit\ThunkGenerators.cpp" />\r
<ClCompile Include="..\llint\LLIntCLoop.cpp" />\r
<ClCompile Include="..\llint\LLIntData.cpp" />\r
- <ClCompile Include="..\llint\LLIntEntrypoints.cpp" />\r
+ <ClCompile Include="..\llint\LLIntEntrypoint.cpp" />\r
<ClCompile Include="..\llint\LLIntExceptions.cpp" />\r
<ClCompile Include="..\llint\LLIntOffsetsExtractor.cpp" />\r
<ClCompile Include="..\llint\LLIntSlowPaths.cpp" />\r
<ClInclude Include="..\llint\LLIntCLoop.h" />\r
<ClInclude Include="..\llint\LLIntCommon.h" />\r
<ClInclude Include="..\llint\LLIntData.h" />\r
- <ClInclude Include="..\llint\LLIntEntrypoints.h" />\r
+ <ClInclude Include="..\llint\LLIntEntrypoint.h" />\r
<ClInclude Include="..\llint\LLIntExceptions.h" />\r
<ClInclude Include="..\llint\LLIntOfflineAsmConfig.h" />\r
<ClInclude Include="..\llint\LLIntOpcode.h" />\r
/* 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, ); }; };
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 */; };
/* 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>"; };
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>"; };
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 */,
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 */,
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 */,
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 */,
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 */,
jit/ThunkGenerators.cpp \
llint/LLIntCLoop.cpp \
llint/LLIntData.cpp \
- llint/LLIntEntrypoints.cpp \
+ llint/LLIntEntrypoint.cpp \
llint/LLIntExceptions.cpp \
llint/LLIntSlowPaths.cpp \
llint/LLIntThunks.cpp \
#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSNameScope.h"
-#include "LLIntEntrypoints.h"
#include "LowLevelInterpreter.h"
#include "Operations.h"
#include "PolymorphicPutByIdList.h"
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);
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();
private:
friend class DFGCodeBlocks;
- CompilationResult prepareForExecutionImpl(
- ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex,
- PassRefPtr<DeferredCompilationCallback>);
-
void noticeIncomingCall(ExecState* callerFrame);
double optimizationThresholdScalingFactor();
#include "JSObject.h"
#include "JSString.h"
-#if ENABLE(DFG_JIT)
-
#include "CodeBlock.h"
#include "DFGJITCode.h"
#include "DFGPlan.h"
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)");
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
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
#include "CodeBlock.h"
#include "Executable.h"
+#include "JIT.h"
#include "JITCode.h"
#include "Operations.h"
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 =
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();
}
}
Worklist* globalWorklist()
{
+ if (!enableConcurrentJIT())
+ return 0;
pthread_once(&initializeGlobalWorklistKeyOnce, initializeGlobalWorklistOnce);
return theGlobalWorklist;
}
// 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
}
}
-PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort effort)
+CompilationResult JIT::privateCompile(JITCompilationEffort effort)
{
#if ENABLE(VALUE_PROFILER)
DFG::CapabilityLevel level = m_codeBlock->capabilityLevel();
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) {
}
#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);
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)
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)
void privateCompileMainPass();
void privateCompileLinkPass();
void privateCompileSlowCases();
- PassRefPtr<JITCode> privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
+ CompilationResult privateCompile(JITCompilationEffort);
void privateCompileClosureCall(CallLinkInfo*, CodeBlock* calleeCodeBlock, Structure*, ExecutableBase*, MacroAssemblerCodePtr);
#include "CodeBlock.h"
#include "CodeProfiling.h"
#include "CommonSlowPaths.h"
+#include "DFGDriver.h"
#include "DFGOSREntry.h"
#include "DFGWorklist.h"
#include "Debugger.h"
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
+ VM& vm = callFrame->vm();
unsigned bytecodeIndex = stackFrame.args[0].int32();
if (bytecodeIndex) {
// 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
// optimized code is already available.
worklistState =
- stackFrame.vm->worklist->completeAllReadyPlansForVM(*stackFrame.vm, codeBlock);
+ vm.worklist->completeAllReadyPlansForVM(vm, codeBlock);
} else
worklistState = DFG::Worklist::NotKnown;
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;
*/
#include "config.h"
-#include "LLIntEntrypoints.h"
+#include "LLIntEntrypoint.h"
#if ENABLE(LLINT)
namespace JSC { namespace LLInt {
-void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
+static void setFunctionEntrypoint(VM& vm, CodeBlock* codeBlock)
{
CodeSpecializationKind kind = codeBlock->specializationKind();
#endif // ENABLE(JIT)
}
-void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
+static void setEvalEntrypoint(VM& vm, CodeBlock* codeBlock)
{
if (!vm.canUseJIT()) {
codeBlock->setJITCode(
#endif
}
-void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
+static void setProgramEntrypoint(VM& vm, CodeBlock* codeBlock)
{
if (!vm.canUseJIT()) {
codeBlock->setJITCode(
#endif
}
+void setEntrypoint(VM& vm, CodeBlock* codeBlock)
+{
+ switch (codeBlock->codeType()) {
+ case GlobalCode:
+ setProgramEntrypoint(vm, codeBlock);
+ return;
+ case EvalCode:
+ setEvalEntrypoint(vm, codeBlock);
+ return;
+ case FunctionCode:
+ setFunctionEntrypoint(vm, codeBlock);
+ return;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
} } // namespace JSC::LLInt
#endif // ENABLE(LLINT)
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LLIntEntrypoints_h
-#define LLIntEntrypoints_h
+#ifndef LLIntEntrypoint_h
+#define LLIntEntrypoint_h
#include <wtf/Platform.h>
#if ENABLE(LLINT)
#include "CodeSpecializationKind.h"
-#include "JITCode.h"
-#include <wtf/RefPtr.h>
namespace JSC {
-class EvalCodeBlock;
-class FunctionCodeBlock;
+class CodeBlock;
class VM;
-class MacroAssemblerCodePtr;
-class MacroAssemblerCodeRef;
-class ProgramCodeBlock;
namespace LLInt {
-void setFunctionEntrypoint(VM&, FunctionCodeBlock*);
-void setEvalEntrypoint(VM&, EvalCodeBlock*);
-void setProgramEntrypoint(VM&, ProgramCodeBlock*);
+void setEntrypoint(VM&, CodeBlock*);
} } // namespace JSC::LLInt
#endif // ENABLE(LLINT)
-#endif // LLIntEntrypoints_h
+#endif // LLIntEntrypoint_h
// Returns true if we should try to OSR.
inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
{
- DeferGC deferGC(exec->vm().heap);
+ VM& vm = exec->vm();
+ DeferGC deferGC(vm.heap);
codeBlock->updateAllValueProfilePredictions();
return true;
}
case JITCode::InterpreterThunk: {
- CompilationResult result = codeBlock->prepareForExecution(
- exec, JITCode::BaselineJIT, JITCompilationCanFail);
+ CompilationResult result = JIT::compile(&vm, codeBlock, JITCompilationCanFail);
switch (result) {
case CompilationFailed:
if (Options::verboseOSR())
#include "CodeBlock.h"
#include "DFGDriver.h"
#include "JIT.h"
+#include "LLIntEntrypoint.h"
#include "Operations.h"
#include "Parser.h"
#include <wtf/Vector.h>
return exception;
}
- JITCode::JITType jitType;
#if ENABLE(LLINT)
- jitType = JITCode::InterpreterThunk;
+ LLInt::setEntrypoint(vm, codeBlock.get());
#else
- jitType = JITCode::BaselineJIT;
-#endif
- CompilationResult result = codeBlock->prepareForExecution(exec, jitType);
+ CompilationResult result = JIT::compile(&vm, codeBlock.get(), JITCompilationMustSucceed);
RELEASE_ASSERT(result == CompilationSuccessful);
+#endif
installCode(codeBlock.get());
return 0;