bytecode/CodeOrigin.cpp
bytecode/CodeType.cpp
bytecode/DFGExitProfile.cpp
- bytecode/DeferredCompilationCallback.cpp
bytecode/ExecutionCounter.cpp
bytecode/ExitKind.cpp
bytecode/GetByIdStatus.cpp
jit/JITStubRoutine.cpp
jit/JITStubs.cpp
jit/JITThunks.cpp
- jit/JITToDFGDeferredCompilationCallback.cpp
jit/JumpReplacementWatchpoint.cpp
jit/ThunkGenerators.cpp
+2013-08-29 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r154804.
+ http://trac.webkit.org/changeset/154804
+ https://bugs.webkit.org/show_bug.cgi?id=120477
+
+ Broke Windows build (assumes LLInt features not enabled on
+ this build) (Requested by bfulgham on #webkit).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::linkIncomingCall):
+ (JSC::CodeBlock::unlinkIncomingCalls):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::ProgramCodeBlock::replacement):
+ (JSC::EvalCodeBlock::replacement):
+ (JSC::FunctionCodeBlock::replacement):
+ (JSC::ProgramCodeBlock::compileOptimized):
+ (JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
+ (JSC::EvalCodeBlock::compileOptimized):
+ (JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
+ (JSC::FunctionCodeBlock::compileOptimized):
+ (JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
+ (JSC::ProgramCodeBlock::jitCompileImpl):
+ (JSC::EvalCodeBlock::jitCompileImpl):
+ (JSC::FunctionCodeBlock::jitCompileImpl):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::jitType):
+ (JSC::CodeBlock::jitCompile):
+ * bytecode/DeferredCompilationCallback.cpp: Removed.
+ * bytecode/DeferredCompilationCallback.h: Removed.
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ (JSC::DFG::tryCompile):
+ (JSC::DFG::tryCompileFunction):
+ (JSC::DFG::tryFinalizePlan):
+ * dfg/DFGDriver.h:
+ (JSC::DFG::tryCompile):
+ (JSC::DFG::tryCompileFunction):
+ (JSC::DFG::tryFinalizePlan):
+ * dfg/DFGFailedFinalizer.cpp:
+ (JSC::DFG::FailedFinalizer::finalize):
+ (JSC::DFG::FailedFinalizer::finalizeFunction):
+ * dfg/DFGFailedFinalizer.h:
+ * dfg/DFGFinalizer.h:
+ * dfg/DFGJITFinalizer.cpp:
+ (JSC::DFG::JITFinalizer::finalize):
+ (JSC::DFG::JITFinalizer::finalizeFunction):
+ * dfg/DFGJITFinalizer.h:
+ * dfg/DFGOSRExitPreparation.cpp:
+ (JSC::DFG::prepareCodeOriginForOSRExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGPlan.cpp:
+ (JSC::DFG::Plan::Plan):
+ (JSC::DFG::Plan::compileInThreadImpl):
+ (JSC::DFG::Plan::finalize):
+ * dfg/DFGPlan.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGWorklist.cpp:
+ (JSC::DFG::Worklist::completeAllReadyPlansForVM):
+ (JSC::DFG::Worklist::runThread):
+ * ftl/FTLJITFinalizer.cpp:
+ (JSC::FTL::JITFinalizer::finalize):
+ (JSC::FTL::JITFinalizer::finalizeFunction):
+ * ftl/FTLJITFinalizer.h:
+ * heap/Heap.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ * jit/JITDriver.h: Added.
+ (JSC::jitCompileIfAppropriateImpl):
+ (JSC::jitCompileFunctionIfAppropriateImpl):
+ (JSC::jitCompileIfAppropriate):
+ (JSC::jitCompileFunctionIfAppropriate):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC::jitCompileFor):
+ (JSC::lazyLinkFor):
+ * jit/JITToDFGDeferredCompilationCallback.cpp: Removed.
+ * jit/JITToDFGDeferredCompilationCallback.h: Removed.
+ * llint/LLIntEntrypoints.cpp:
+ (JSC::LLInt::getFunctionEntrypoint):
+ (JSC::LLInt::getEvalEntrypoint):
+ (JSC::LLInt::getProgramEntrypoint):
+ * llint/LLIntEntrypoints.h:
+ (JSC::LLInt::getEntrypoint):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ (JSC::LLInt::setUpCall):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::isNumericCompareFunction):
+ * runtime/CommonSlowPaths.cpp:
+ * runtime/CompilationResult.cpp:
+ (WTF::printInternal):
+ * runtime/CompilationResult.h:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileOptimized):
+ (JSC::EvalExecutable::jitCompile):
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
+ (JSC::ProgramExecutable::compileOptimized):
+ (JSC::ProgramExecutable::jitCompile):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::ProgramExecutable::replaceWithDeferredOptimizedCode):
+ (JSC::FunctionExecutable::compileOptimizedForCall):
+ (JSC::FunctionExecutable::compileOptimizedForConstruct):
+ (JSC::FunctionExecutable::jitCompileForCall):
+ (JSC::FunctionExecutable::jitCompileForConstruct):
+ (JSC::FunctionExecutable::produceCodeBlockFor):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::offsetOfJITCodeWithArityCheckFor):
+ (JSC::ExecutableBase::offsetOfNumParametersFor):
+ (JSC::ExecutableBase::catchRoutineFor):
+ (JSC::EvalExecutable::compile):
+ (JSC::ProgramExecutable::compile):
+ (JSC::FunctionExecutable::compileForCall):
+ (JSC::FunctionExecutable::compileForConstruct):
+ (JSC::FunctionExecutable::compileFor):
+ (JSC::FunctionExecutable::compileOptimizedFor):
+ (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
+ (JSC::FunctionExecutable::jitCompileFor):
+ * runtime/ExecutionHarness.h: Added.
+ (JSC::prepareForExecutionImpl):
+ (JSC::prepareFunctionForExecutionImpl):
+ (JSC::installOptimizedCode):
+ (JSC::prepareForExecution):
+ (JSC::prepareFunctionForExecution):
+ (JSC::replaceWithDeferredOptimizedCode):
+
2013-08-28 Filip Pizlo <fpizlo@apple.com>
CodeBlock compilation and installation should be simplified and rationalized
Source/JavaScriptCore/bytecode/CodeBlockWithJITType.h \
Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
Source/JavaScriptCore/bytecode/CodeOrigin.h \
+ Source/JavaScriptCore/bytecode/DataFormat.h \
Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \
Source/JavaScriptCore/bytecode/DFGExitProfile.h \
- Source/JavaScriptCore/bytecode/DataFormat.h \
- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp \
- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h \
Source/JavaScriptCore/bytecode/EvalCodeCache.h \
Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
Source/JavaScriptCore/bytecode/ExecutionCounter.h \
Source/JavaScriptCore/jit/JITCompilationEffort.h \
Source/JavaScriptCore/jit/JITDisassembler.cpp \
Source/JavaScriptCore/jit/JITDisassembler.h \
+ Source/JavaScriptCore/jit/JITDriver.h \
Source/JavaScriptCore/jit/JIT.cpp \
Source/JavaScriptCore/jit/JIT.h \
Source/JavaScriptCore/jit/JITExceptions.cpp \
Source/JavaScriptCore/jit/JITStubsX86Common.h \
Source/JavaScriptCore/jit/JITThunks.cpp \
Source/JavaScriptCore/jit/JITThunks.h \
- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp \
- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h \
Source/JavaScriptCore/jit/JITWriteBarrier.h \
Source/JavaScriptCore/jit/JSInterfaceJIT.h \
Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp \
Source/JavaScriptCore/runtime/ExceptionHelpers.h \
Source/JavaScriptCore/runtime/Executable.cpp \
Source/JavaScriptCore/runtime/Executable.h \
+ Source/JavaScriptCore/runtime/ExecutionHarness.h \
Source/JavaScriptCore/runtime/Float32Array.h \
Source/JavaScriptCore/runtime/Float64Array.h \
Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
<ClCompile Include="..\bytecode\CodeBlockHash.cpp" />\r
<ClCompile Include="..\bytecode\CodeOrigin.cpp" />\r
<ClCompile Include="..\bytecode\CodeType.cpp" />\r
- <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" />\r
<ClCompile Include="..\bytecode\ExecutionCounter.cpp" />\r
<ClCompile Include="..\bytecode\ExitKind.cpp" />\r
<ClCompile Include="..\bytecode\GetByIdStatus.cpp" />\r
<ClCompile Include="..\jit\JITStubRoutine.cpp" />\r
<ClCompile Include="..\jit\JITStubs.cpp" />\r
<ClCompile Include="..\jit\JITThunks.cpp" />\r
- <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />\r
<ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" />\r
<ClCompile Include="..\jit\ThunkGenerators.cpp" />\r
<ClCompile Include="..\llint\LLIntCLoop.cpp" />\r
<ClInclude Include="..\bytecode\CodeType.h" />\r
<ClInclude Include="..\bytecode\Comment.h" />\r
<ClInclude Include="..\bytecode\DataFormat.h" />\r
- <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" />\r
<ClInclude Include="..\bytecode\EvalCodeCache.h" />\r
<ClInclude Include="..\bytecode\ExecutionCounter.h" />\r
<ClInclude Include="..\bytecode\ExitKind.h" />\r
<ClInclude Include="..\jit\JITCode.h" />\r
<ClInclude Include="..\jit\JITCompilationEffort.h" />\r
<ClInclude Include="..\jit\JITDisassembler.h" />\r
+ <ClInclude Include="..\jit\JITDriver.h" />\r
<ClInclude Include="..\jit\JITExceptions.h" />\r
<ClInclude Include="..\jit\JITInlines.h" />\r
<ClInclude Include="..\jit\JITStubCall.h" />\r
<ClInclude Include="..\jit\JITStubsX86Common.h" />\r
<ClInclude Include="..\jit\JITStubsX86_64.h" />\r
<ClInclude Include="..\jit\JITThunks.h" />\r
- <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" />\r
<ClInclude Include="..\jit\JITWriteBarrier.h" />\r
<ClInclude Include="..\jit\JSInterfaceJIT.h" />\r
<ClInclude Include="..\jit\JumpReplacementWatchpoint.h" />\r
<ClInclude Include="..\runtime\ErrorPrototype.h" />\r
<ClInclude Include="..\runtime\ExceptionHelpers.h" />\r
<ClInclude Include="..\runtime\Executable.h" />\r
+ <ClInclude Include="..\runtime\ExecutionHarness.h" />\r
<ClInclude Include="..\runtime\Float32Array.h" />\r
<ClInclude Include="..\runtime\Float64Array.h" />\r
<ClInclude Include="..\runtime\FunctionConstructor.h" />\r
0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F235BD117178E1C00690C7F /* FTLCArgumentGetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */; };
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */; };
0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; };
- 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; };
- 0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoubleFormatState.h; path = dfg/DFGDoubleFormatState.h; sourceTree = "<group>"; };
0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; };
0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSilentRegisterSavePlan.h; path = dfg/DFGSilentRegisterSavePlan.h; sourceTree = "<group>"; };
+ 0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
+ 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; };
0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLCArgumentGetter.h; path = ftl/FTLCArgumentGetter.h; sourceTree = "<group>"; };
0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler.cpp; path = dfg/DFGOSRExitCompiler.cpp; sourceTree = "<group>"; };
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
- 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; };
- 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; };
- 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; };
- 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JITToDFGDeferredCompilationCallback.h; sourceTree = "<group>"; };
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; };
0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
0FAF7EFB165BA919000C8455 /* JITDisassembler.h */,
+ 0F21C26614BE5F5E00ADC64B /* JITDriver.h */,
0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
0F46808014BA572700BFE272 /* JITExceptions.h */,
86CC85A00EE79A4700288682 /* JITInlines.h */,
A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */,
0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
0F5EF91C16878F78003E5C25 /* JITThunks.h */,
- 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */,
- 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */,
A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
86CA032D1038E8440028A609 /* Executable.cpp */,
86CAFEE21035DDE60028A609 /* Executable.h */,
+ 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
A7A8AF2917ADB5F3005AB174 /* Float32Array.h */,
A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */,
BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
0F8F943F1667632D00D61971 /* CodeType.cpp */,
0F0B83A514BCF50400885B4F /* CodeType.h */,
0F426A4A1460CD6B00131F8F /* DataFormat.h */,
- 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
- 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
- 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */,
BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
+ 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
+ 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
86CC85A10EE79A4700288682 /* JITInlines.h in Headers */,
960626960FB8EC02009798AB /* JITStubCall.h in Headers */,
BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
- 0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */,
A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */,
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
- 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
- 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */,
0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
bytecode/CodeOrigin.cpp \
bytecode/CodeType.cpp \
bytecode/DFGExitProfile.cpp \
- bytecode/DeferredCompilationCallback.cpp \
bytecode/ExecutionCounter.cpp \
bytecode/ExitKind.cpp \
bytecode/GetByIdStatus.cpp \
jit/JITStubRoutine.cpp \
jit/JITStubs.cpp \
jit/JITThunks.cpp \
- jit/JITToDFGDeferredCompilationCallback.cpp \
jit/JumpReplacementWatchpoint.cpp \
jit/ThunkGenerators.cpp \
llint/LLIntCLoop.cpp \
#include "CallLinkStatus.h"
#include "DFGCapabilities.h"
#include "DFGCommon.h"
-#include "DFGDriver.h"
#include "DFGNode.h"
#include "DFGRepatch.h"
#include "DFGWorklist.h"
#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSNameScope.h"
-#include "LLIntEntrypoints.h"
#include "LowLevelInterpreter.h"
#include "Operations.h"
#include "PolymorphicPutByIdList.h"
noticeIncomingCall(callerFrame);
m_incomingCalls.push(incoming);
}
-#endif // ENABLE(JIT)
void CodeBlock::unlinkIncomingCalls()
{
#if ENABLE(LLINT)
while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
m_incomingLLIntCalls.begin()->unlink();
-#endif // ENABLE(LLINT)
-#if ENABLE(JIT)
+#endif
if (m_incomingCalls.isEmpty())
return;
RepatchBuffer repatchBuffer(this);
while (m_incomingCalls.begin() != m_incomingCalls.end())
m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
-#endif // ENABLE(JIT)
}
+#endif // ENABLE(JIT)
#if ENABLE(LLINT)
void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
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) {
- 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;
- }
-
#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)
+void CodeBlock::reoptimize()
+{
+ ASSERT(replacement() != this);
+ ASSERT(replacement()->alternative() == this);
+ if (DFG::shouldShowDisassembly())
+ dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
+ replacement()->jettison();
+ countReoptimization();
}
-CompilationResult CodeBlock::prepareForExecution(
- ExecState* exec, JITCode::JITType jitType,
- JITCompilationEffort effort, unsigned bytecodeIndex)
+CodeBlock* ProgramCodeBlock::replacement()
{
- CompilationResult result =
- prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, 0);
- ASSERT(result != CompilationDeferred);
- return result;
+ return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
}
-CompilationResult CodeBlock::prepareForExecutionAsynchronously(
- ExecState* exec, JITCode::JITType jitType,
- PassRefPtr<DeferredCompilationCallback> passedCallback,
- JITCompilationEffort effort, unsigned bytecodeIndex)
+CodeBlock* EvalCodeBlock::replacement()
{
- RefPtr<DeferredCompilationCallback> callback = passedCallback;
- CompilationResult result =
- prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, callback);
- if (result != CompilationDeferred)
- callback->compilationDidComplete(this, result);
- return result;
+ return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode();
+}
+
+CodeBlock* FunctionCodeBlock::replacement()
+{
+ return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
}
-void CodeBlock::install()
+#if ENABLE(DFG_JIT)
+JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
{
- ownerExecutable()->installCode(this);
+ if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
+ result = CompilationNotNeeded;
+ return 0;
+ }
+ JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
+ return error;
}
-PassRefPtr<CodeBlock> CodeBlock::newReplacement()
+CompilationResult ProgramCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
{
- return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
+ return static_cast<ProgramExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);
}
-#if ENABLE(JIT)
-void CodeBlock::reoptimize()
+JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
{
- ASSERT(replacement() != this);
- ASSERT(replacement()->alternative() == this);
- if (DFG::shouldShowDisassembly())
- dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
- replacement()->jettison();
- countReoptimization();
+ if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
+ result = CompilationNotNeeded;
+ return 0;
+ }
+ JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
+ return error;
}
-CodeBlock* ProgramCodeBlock::replacement()
+CompilationResult EvalCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
{
- return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
+ return static_cast<EvalExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);
}
-CodeBlock* EvalCodeBlock::replacement()
+JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
{
- return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode();
+ if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
+ result = CompilationNotNeeded;
+ return 0;
+ }
+ JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, result, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall);
+ return error;
}
-CodeBlock* FunctionCodeBlock::replacement()
+CompilationResult FunctionCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
{
- return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
+ return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall);
}
+#endif // ENABLE(DFG_JIT)
DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
{
{
static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
+
+CompilationResult ProgramCodeBlock::jitCompileImpl(ExecState* exec)
+{
+ ASSERT(jitType() == JITCode::InterpreterThunk);
+ ASSERT(this == replacement());
+ return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);
+}
+
+CompilationResult EvalCodeBlock::jitCompileImpl(ExecState* exec)
+{
+ ASSERT(jitType() == JITCode::InterpreterThunk);
+ ASSERT(this == replacement());
+ return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);
+}
+
+CompilationResult FunctionCodeBlock::jitCompileImpl(ExecState* exec)
+{
+ ASSERT(jitType() == JITCode::InterpreterThunk);
+ ASSERT(this == replacement());
+ return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall);
+}
#endif
JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
#include "DFGOSREntry.h"
#include "DFGOSRExit.h"
#include "DFGVariableEventStream.h"
-#include "DeferredCompilationCallback.h"
#include "EvalCodeCache.h"
#include "ExecutionCounter.h"
#include "ExpressionRangeInfo.h"
unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
- void unlinkIncomingCalls();
-
#if ENABLE(JIT)
unsigned bytecodeOffsetForCallAtIndex(unsigned index)
{
void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
#endif // ENABLE(LLINT)
+ void unlinkIncomingCalls();
+
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
{
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();
-
- // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind())
- PassRefPtr<CodeBlock> newReplacement();
-
+#if ENABLE(JIT)
void setJITCode(PassRefPtr<JITCode> code, MacroAssemblerCodePtr codeWithArityCheck)
{
ConcurrentJITLocker locker(m_lock);
WTF::loadLoadFence(); // This probably isn't needed. Oh well, paranoia is good.
return result;
}
-
-#if ENABLE(JIT)
bool hasBaselineJITProfiling() const
{
return jitType() == JITCode::BaselineJIT;
}
+#if ENABLE(DFG_JIT)
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0;
+ virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0;
+#endif // ENABLE(DFG_JIT)
void jettison();
-
+ CompilationResult jitCompile(ExecState* exec)
+ {
+ if (jitType() != JITCode::InterpreterThunk) {
+ ASSERT(jitType() == JITCode::BaselineJIT);
+ return CompilationNotNeeded;
+ }
+ return jitCompileImpl(exec);
+ }
virtual CodeBlock* replacement() = 0;
virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
bool hasOptimizedReplacement();
+#else
+ JITCode::JITType jitType() const { return JITCode::InterpreterThunk; }
#endif
ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
protected:
#if ENABLE(JIT)
+ virtual CompilationResult jitCompileImpl(ExecState*) = 0;
virtual void jettisonImpl() = 0;
#endif
virtual void visitWeakReferences(SlotVisitor&);
private:
friend class DFGCodeBlocks;
- CompilationResult prepareForExecutionImpl(
- ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex,
- PassRefPtr<DeferredCompilationCallback>);
-
void noticeIncomingCall(ExecState* callerFrame);
double optimizationThresholdScalingFactor();
SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
#endif
- RefPtr<JITCode> m_jitCode;
- MacroAssemblerCodePtr m_jitCodeWithArityCheck;
#if ENABLE(JIT)
Vector<StructureStubInfo> m_structureStubInfos;
Vector<ByValInfo> m_byValInfos;
Vector<CallLinkInfo> m_callLinkInfos;
+ RefPtr<JITCode> m_jitCode;
+ MacroAssemblerCodePtr m_jitCodeWithArityCheck;
SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
#endif
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
#if ENABLE(JIT)
protected:
+#if ENABLE(DFG_JIT)
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
virtual void jettisonImpl();
+ virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
#endif
#if ENABLE(JIT)
protected:
+#if ENABLE(DFG_JIT)
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
virtual void jettisonImpl();
+ virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
#endif
#if ENABLE(JIT)
protected:
+#if ENABLE(DFG_JIT)
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
virtual void jettisonImpl();
+ virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
#endif
+++ /dev/null
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DeferredCompilationCallback.h"
-
-namespace JSC {
-
-DeferredCompilationCallback::DeferredCompilationCallback() { }
-DeferredCompilationCallback::~DeferredCompilationCallback() { }
-
-} // JSC
-
+++ /dev/null
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DeferredCompilationCallback_h
-#define DeferredCompilationCallback_h
-
-#include "CompilationResult.h"
-#include <wtf/RefCounted.h>
-
-namespace JSC {
-
-class CodeBlock;
-
-class DeferredCompilationCallback : public RefCounted<DeferredCompilationCallback> {
-protected:
- DeferredCompilationCallback();
-
-public:
- virtual ~DeferredCompilationCallback();
-
- virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) = 0;
- virtual void compilationDidComplete(CodeBlock*, CompilationResult) = 0;
-};
-
-} // namespace JSC
-
-#endif // DeferredCompilationCallback_h
-
return numCompilations;
}
-CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
+static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
{
SamplingRegion samplingRegion("DFG Compilation (Driver)");
else
numVarsWithValues = 0;
RefPtr<Plan> plan = adoptRef(
- new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
+ new Plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) {
int operand = plan->mustHandleValues.operandForIndex(i);
if (operandIsArgument(operand)
&& !operandToArgument(operand)
- && codeBlock->codeType() == FunctionCode
+ && 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,
plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
}
- if (enableConcurrentJIT() && callback) {
- plan->callback = callback;
+ if (enableConcurrentJIT()) {
if (!vm.worklist)
vm.worklist = globalWorklist();
if (logCompilationChanges())
}
plan->compileInThread(*vm.dfgState);
- return plan->finalizeWithoutNotifyingCallback();
+ return plan->finalize(jitCode, jitCodeWithArityCheck);
+}
+
+CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex)
+{
+ return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex);
+}
+
+CompilationResult tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex)
+{
+ return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck, bytecodeIndex);
+}
+
+CompilationResult tryFinalizePlan(PassRefPtr<Plan> plan, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
+{
+ return plan->finalize(jitCode, jitCodeWithArityCheck);
}
} } // namespace JSC::DFG
JS_EXPORT_PRIVATE unsigned getNumCompilations();
#if ENABLE(DFG_JIT)
-CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>);
+CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned bytecodeIndex);
+CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex);
+CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr* jitCodeWithArityCheck);
#else
-inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; }
+inline CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return CompilationFailed; }
+inline CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return CompilationFailed; }
+inline CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr*)
+{
+ UNREACHABLE_FOR_PLATFORM();
+ return CompilationFailed;
+}
#endif
} } // namespace JSC::DFG
{
}
-bool FailedFinalizer::finalize()
+bool FailedFinalizer::finalize(RefPtr<JSC::JITCode>&)
{
return false;
}
-bool FailedFinalizer::finalizeFunction()
+bool FailedFinalizer::finalizeFunction(RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&)
{
return false;
}
FailedFinalizer(Plan&);
virtual ~FailedFinalizer();
- bool finalize();
- bool finalizeFunction();
+ bool finalize(RefPtr<JSC::JITCode>& entry);
+ bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
};
} } // namespace JSC::DFG
Finalizer(Plan&);
virtual ~Finalizer();
- virtual bool finalize() = 0;
- virtual bool finalizeFunction() = 0;
+ virtual bool finalize(RefPtr<JSC::JITCode>& entry) = 0;
+ virtual bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) = 0;
protected:
Plan& m_plan;
#if ENABLE(DFG_JIT)
-#include "CodeBlock.h"
#include "DFGCommon.h"
#include "DFGPlan.h"
{
}
-bool JITFinalizer::finalize()
+bool JITFinalizer::finalize(RefPtr<JSC::JITCode>& entry)
{
finalizeCommon();
m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
- m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr());
+ entry = m_jitCode;
return true;
}
-bool JITFinalizer::finalizeFunction()
+bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
{
finalizeCommon();
- MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
+ withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
- m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck);
+ entry = m_jitCode;
return true;
}
JITFinalizer(Plan&, PassRefPtr<JITCode>, PassOwnPtr<LinkBuffer>, MacroAssembler::Label arityCheck = MacroAssembler::Label());
virtual ~JITFinalizer();
- bool finalize();
- bool finalizeFunction();
+ bool finalize(RefPtr<JSC::JITCode>& entry);
+ bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
private:
void finalizeCommon();
#include "CodeBlock.h"
#include "Executable.h"
-#include "JITCode.h"
#include "Operations.h"
namespace JSC { namespace DFG {
void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
{
- DeferGC deferGC(exec->vm().heap);
-
for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
FunctionExecutable* executable =
static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get());
CodeBlock* codeBlock = executable->baselineCodeBlockFor(
codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
- 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);
- codeBlock->install();
+ codeBlock->jitCompile(exec);
}
}
codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
+ JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
if (error) {
vm->throwException(exec, createStackOverflowError(exec));
return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
ExecutableBase* executable = function->executable();
if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind);
+ JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
if (error) {
exec->vm().throwException(execCallee, error);
return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
Plan::Plan(
- PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
+ CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
unsigned numVarsWithValues)
- : vm(*passedCodeBlock->vm())
+ : compileMode(compileMode)
+ , vm(*passedCodeBlock->vm())
, codeBlock(passedCodeBlock)
, osrEntryBytecodeIndex(osrEntryBytecodeIndex)
, numVarsWithValues(numVarsWithValues)
#if ENABLE(FTL_JIT)
if (Options::useExperimentalFTL()
- && codeBlock->codeType() == FunctionCode
+ && compileMode == CompileFunction
&& FTL::canCompile(dfg)) {
performCriticalEdgeBreaking(dfg);
dumpAndVerifyGraph(dfg, "Graph after optimization:");
JITCompiler dataFlowJIT(dfg);
- if (codeBlock->codeType() == FunctionCode) {
+ if (compileMode == CompileFunction) {
dataFlowJIT.compileFunction();
dataFlowJIT.linkFunction();
} else {
+ ASSERT(compileMode == CompileOther);
+
dataFlowJIT.compile();
dataFlowJIT.link();
}
writeBarriers.trigger(vm);
}
-void Plan::notifyReady()
-{
- callback->compilationDidBecomeReadyAsynchronously(codeBlock.get());
- isCompiled = true;
-}
-
-CompilationResult Plan::finalizeWithoutNotifyingCallback()
+CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
{
if (!isStillValid())
return CompilationInvalidated;
bool result;
- if (codeBlock->codeType() == FunctionCode)
- result = finalizer->finalizeFunction();
+ if (compileMode == CompileFunction)
+ result = finalizer->finalizeFunction(jitCode, *jitCodeWithArityCheck);
else
- result = finalizer->finalize();
+ result = finalizer->finalize(jitCode);
if (!result)
return CompilationFailed;
- reallyAdd(codeBlock->jitCode()->dfgCommon());
+ reallyAdd(jitCode->dfgCommon());
return CompilationSuccessful;
}
-void Plan::finalizeAndNotifyCallback()
-{
- callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback());
-}
-
CodeBlock* Plan::key()
{
return codeBlock->alternative();
#include "DFGDesiredWeakReferences.h"
#include "DFGDesiredWriteBarriers.h"
#include "DFGFinalizer.h"
-#include "DeferredCompilationCallback.h"
#include "Operands.h"
#include "ProfilerCompilation.h"
#include <wtf/ThreadSafeRefCounted.h>
class LongLivedState;
+enum CompileMode { CompileFunction, CompileOther };
+
#if ENABLE(DFG_JIT)
struct Plan : public ThreadSafeRefCounted<Plan> {
Plan(
- PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
+ CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock,
+ unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
~Plan();
void compileInThread(LongLivedState&);
- CompilationResult finalizeWithoutNotifyingCallback();
- void finalizeAndNotifyCallback();
-
- void notifyReady();
+ CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck);
CodeBlock* key();
+ const CompileMode compileMode;
VM& vm;
RefPtr<CodeBlock> codeBlock;
const unsigned osrEntryBytecodeIndex;
bool isCompiled;
- RefPtr<DeferredCompilationCallback> callback;
-
private:
enum CompilationPath { FailPath, DFGPath, FTLPath };
CompilationPath compileInThreadImpl(LongLivedState&);
break;
}
- switch (node->child1().useKind()) {
- case CellUse: {
+ if (isCellSpeculation(node->child1()->prediction())) {
SpeculateCellOperand base(this, node->child1());
GPRTemporary resultTag(this, base);
GPRTemporary resultPayload(this);
break;
}
- case UntypedUse: {
- JSValueOperand base(this, node->child1());
- GPRTemporary resultTag(this, base);
- GPRTemporary resultPayload(this);
+ JSValueOperand base(this, node->child1());
+ GPRTemporary resultTag(this, base);
+ GPRTemporary resultPayload(this);
- GPRReg baseTagGPR = base.tagGPR();
- GPRReg basePayloadGPR = base.payloadGPR();
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
+ GPRReg baseTagGPR = base.tagGPR();
+ GPRReg basePayloadGPR = base.payloadGPR();
+ GPRReg resultTagGPR = resultTag.gpr();
+ GPRReg resultPayloadGPR = resultPayload.gpr();
- base.use();
+ base.use();
- JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
+ JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
- cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
+ cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
- jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
- break;
- }
-
- default:
- RELEASE_ASSERT_NOT_REACHED();
- break;
- }
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
break;
}
RELEASE_ASSERT(plan->isCompiled);
- plan->finalizeAndNotifyCallback();
+ CompilationResult compilationResult =
+ profiledBlock->replaceWithDeferredOptimizedCode(plan);
+ RELEASE_ASSERT(compilationResult != CompilationDeferred);
+ profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult);
if (profiledBlock == requestedProfiledBlock)
resultingState = Compiled;
{
MutexLocker locker(m_lock);
- plan->notifyReady();
+ plan->key()->forceOptimizationSlowPathConcurrently();
+ plan->isCompiled = true;
if (Options::verboseCompilationQueue()) {
dump(locker, WTF::dataFile());
{
}
-bool JITFinalizer::finalize()
+bool JITFinalizer::finalize(RefPtr<JSC::JITCode>&)
{
RELEASE_ASSERT_NOT_REACHED();
return false;
}
-bool JITFinalizer::finalizeFunction()
+bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
{
for (unsigned i = m_jitCode->handles().size(); i--;) {
MacroAssembler::cacheFlush(
("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data())));
} // else this function had no OSR exits, so no exit thunks.
- MacroAssemblerCodePtr withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
+ withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
m_jitCode->initializeCode(
FINALIZE_DFG_CODE(
*m_entrypointLinkBuffer,
("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), m_function)));
-
- m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck);
+ entry = m_jitCode;
return true;
}
m_jitCode = jitCode;
}
- bool finalize();
- bool finalizeFunction();
+ bool finalize(RefPtr<JSC::JITCode>& entry);
+ bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
private:
OwnPtr<LinkBuffer> m_exitThunksLinkBuffer;
const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
void addReference(JSCell*, ArrayBuffer*);
-
- bool isDeferred() const { return !!m_deferralDepth; }
private:
friend class CodeBlock;
if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
return checkedReturn(callFrame->vm().throwException(callFrame, error));
- if (JSObject* error = program->prepareForExecution(callFrame, scope, CodeForCall))
+ if (JSObject* error = program->compile(callFrame, scope))
return checkedReturn(callFrame->vm().throwException(callFrame, error));
ProgramCodeBlock* codeBlock = &program->generatedBytecode();
if (isJSCall) {
// Compile the callee:
- JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
+ JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope);
if (UNLIKELY(!!compileError)) {
return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
}
if (isJSConstruct) {
// Compile the callee:
- JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct);
+ JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope);
if (UNLIKELY(!!compileError)) {
return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
}
}
// Compile the callee:
- JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
+ JSObject* error = functionExecutable->compileForCall(callFrame, scope);
if (error) {
callFrame->vm().throwException(callFrame, error);
return CallFrameClosure();
}
}
- JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall);
+ JSObject* compileError = eval->compile(callFrame, scope);
if (UNLIKELY(!!compileError))
return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
EvalCodeBlock* codeBlock = &eval->generatedBytecode();
--- /dev/null
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITDriver_h
+#define JITDriver_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#include "BytecodeGenerator.h"
+#include "CompilationResult.h"
+#include "DFGDriver.h"
+#include "JIT.h"
+#include "LLIntEntrypoints.h"
+
+namespace JSC {
+
+template<typename CodeBlockType>
+inline CompilationResult jitCompileIfAppropriateImpl(
+ ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
+ JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
+{
+ VM& vm = exec->vm();
+
+ if (jitType == codeBlock->jitType())
+ return CompilationNotNeeded;
+
+ if (!vm.canUseJIT())
+ return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
+
+ codeBlock->unlinkIncomingCalls();
+
+ RefPtr<JITCode> oldJITCode = jitCode;
+
+ if (JITCode::isOptimizingJIT(jitType)) {
+ CompilationResult result =
+ DFG::tryCompile(exec, codeBlock, jitCode, bytecodeIndex);
+ if (result == CompilationSuccessful)
+ codeBlock->alternative()->unlinkIncomingCalls();
+ else {
+ ASSERT(oldJITCode == jitCode);
+ return result;
+ }
+ } else {
+ RefPtr<JITCode> result = JIT::compile(&vm, codeBlock, effort);
+ if (result)
+ jitCode = result;
+ else
+ return CompilationFailed;
+ }
+
+ return CompilationSuccessful;
+}
+
+inline CompilationResult jitCompileFunctionIfAppropriateImpl(
+ ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
+ MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
+ unsigned bytecodeIndex, JITCompilationEffort effort)
+{
+ VM& vm = exec->vm();
+
+ if (jitType == codeBlock->jitType())
+ return CompilationNotNeeded;
+
+ if (!vm.canUseJIT())
+ return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
+
+ codeBlock->unlinkIncomingCalls();
+
+ RefPtr<JITCode> oldJITCode = jitCode;
+ MacroAssemblerCodePtr oldJITCodeWithArityCheck = jitCodeWithArityCheck;
+
+ if (JITCode::isOptimizingJIT(jitType)) {
+ CompilationResult result = DFG::tryCompileFunction(
+ exec, codeBlock, jitCode, jitCodeWithArityCheck, bytecodeIndex);
+ if (result == CompilationSuccessful)
+ codeBlock->alternative()->unlinkIncomingCalls();
+ else {
+ ASSERT(oldJITCode == jitCode);
+ ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
+ return result;
+ }
+ } else {
+ RefPtr<JITCode> result =
+ JIT::compile(&vm, codeBlock, effort, &jitCodeWithArityCheck);
+ if (result)
+ jitCode = result;
+ else {
+ ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
+ return CompilationFailed;
+ }
+ }
+
+ return CompilationSuccessful;
+}
+
+template<typename CodeBlockType>
+inline CompilationResult jitCompileIfAppropriate(
+ ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
+ JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
+{
+ CompilationResult result = jitCompileIfAppropriateImpl(
+ exec, codeBlock, jitCode, jitType, bytecodeIndex, effort);
+ if (result == CompilationSuccessful) {
+ codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
+ codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
+ }
+ return result;
+}
+
+inline CompilationResult jitCompileFunctionIfAppropriate(
+ ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
+ MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
+ unsigned bytecodeIndex, JITCompilationEffort effort)
+{
+ CompilationResult result = jitCompileFunctionIfAppropriateImpl(
+ exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, effort);
+ if (result == CompilationSuccessful) {
+ codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
+ codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
+ }
+ return result;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITDriver_h
+
#include <wtf/InlineASM.h>
#include "JIT.h"
#include "JITExceptions.h"
-#include "JITToDFGDeferredCompilationCallback.h"
#include "JSActivation.h"
#include "JSArray.h"
#include "JSFunction.h"
if (Options::verboseOSR())
dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
// If we have an optimized replacement, then it must be the case that we entered
- // cti_optimize from a loop. That's because if there's an optimized replacement,
+ // cti_optimize from a loop. That's because is there's an optimized replacement,
// then all calls to this function will be relinked to the replacement and so
// the prologue OSR will never fire.
if (Options::verboseOSR())
dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
- RefPtr<DeferredCompilationCallback> callback =
- JITToDFGDeferredCompilationCallback::create();
- RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement();
- CompilationResult result = newCodeBlock->prepareForExecutionAsynchronously(
- callFrame, JITCode::DFGJIT, callback, JITCompilationCanFail, bytecodeIndex);
+ JSScope* scope = callFrame->scope();
+ CompilationResult result;
+ JSObject* error = codeBlock->compileOptimized(callFrame, scope, result, bytecodeIndex);
+ if (Options::verboseOSR()) {
+ dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n");
+ if (error)
+ dataLog("WARNING: optimized compilation failed with a JS error.\n");
+ }
+ codeBlock->setOptimizationThresholdBasedOnCompilationResult(result);
if (result != CompilationSuccessful)
return;
}
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
JSScope* callDataScopeChain = function->scope();
- JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind);
+ JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
if (!error)
return function;
callFrame->vm().throwException(callFrame, error);
codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) {
+ if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
callFrame->vm().throwException(callFrame, error);
return 0;
}
FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
JSScope* scopeChain = callee->scope();
- JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall);
+ JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
if (error) {
callFrame->vm().throwException(callFrame, error);
return 0;
+++ /dev/null
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JITToDFGDeferredCompilationCallback.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "CodeBlock.h"
-#include "Executable.h"
-
-namespace JSC {
-
-JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback() { }
-JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback() { }
-
-PassRefPtr<JITToDFGDeferredCompilationCallback> JITToDFGDeferredCompilationCallback::create()
-{
- return adoptRef(new JITToDFGDeferredCompilationCallback());
-}
-
-void JITToDFGDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
- CodeBlock* codeBlock)
-{
- ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
-
- if (Options::verboseOSR())
- dataLog("Optimizing compilation of ", *codeBlock, " did become ready.\n");
-
- codeBlock->alternative()->forceOptimizationSlowPathConcurrently();
-}
-
-void JITToDFGDeferredCompilationCallback::compilationDidComplete(
- CodeBlock* codeBlock, CompilationResult result)
-{
- ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
-
- if (Options::verboseOSR())
- dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n");
-
- if (result == CompilationSuccessful)
- codeBlock->install();
-
- codeBlock->alternative()->setOptimizationThresholdBasedOnCompilationResult(result);
-}
-
-} // JSC
-
-#endif // ENABLE(DFG_JIT)
+++ /dev/null
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JITToDFGDeferredCompilationCallback_h
-#define JITToDFGDeferredCompilationCallback_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(DFG_JIT)
-
-#include "DeferredCompilationCallback.h"
-#include <wtf/PassRefPtr.h>
-
-namespace JSC {
-
-class ScriptExecutable;
-
-class JITToDFGDeferredCompilationCallback : public DeferredCompilationCallback {
-protected:
- JITToDFGDeferredCompilationCallback();
-
-public:
- virtual ~JITToDFGDeferredCompilationCallback();
-
- static PassRefPtr<JITToDFGDeferredCompilationCallback> create();
-
- virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
- virtual void compilationDidComplete(CodeBlock*, CompilationResult);
-};
-
-} // namespace JSC
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // JITToDFGDeferredCompilationCallback_h
-
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#if ENABLE(LLINT)
-#include "CodeBlock.h"
#include "JITCode.h"
+#include "VM.h"
#include "JSObject.h"
#include "LLIntThunks.h"
#include "LowLevelInterpreter.h"
-#include "VM.h"
namespace JSC { namespace LLInt {
-void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
+void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck)
{
- CodeSpecializationKind kind = codeBlock->specializationKind();
-
if (!vm.canUseJIT()) {
if (kind == CodeForCall) {
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check));
+ jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk));
+ arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check);
return;
}
ASSERT(kind == CodeForConstruct);
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check));
+ jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk));
+ arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check);
return;
}
#if ENABLE(JIT)
if (kind == CodeForCall) {
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)),
- vm.getCTIStub(functionForCallArityCheckThunkGenerator).code());
+ jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk));
+ arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code();
return;
}
ASSERT(kind == CodeForConstruct);
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)),
- vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code());
+ jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk));
+ arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
#endif // ENABLE(JIT)
}
-void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
+void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
{
if (!vm.canUseJIT()) {
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr());
+ jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk));
return;
}
-#if ENABLE(JIT)
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr());
+#if ENABLE(JIT)
+ jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk));
#endif
}
-void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
+void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
{
if (!vm.canUseJIT()) {
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr());
+ jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk));
return;
}
#if ENABLE(JIT)
- codeBlock->setJITCode(
- adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)),
- MacroAssemblerCodePtr());
+ jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk));
#endif
}
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
namespace JSC {
class EvalCodeBlock;
-class FunctionCodeBlock;
class VM;
class MacroAssemblerCodePtr;
class MacroAssemblerCodeRef;
namespace LLInt {
-void setFunctionEntrypoint(VM&, FunctionCodeBlock*);
-void setEvalEntrypoint(VM&, EvalCodeBlock*);
-void setProgramEntrypoint(VM&, ProgramCodeBlock*);
+void getFunctionEntrypoint(VM&, CodeSpecializationKind, RefPtr<JITCode>&, MacroAssemblerCodePtr& arityCheck);
+void getEvalEntrypoint(VM&, RefPtr<JITCode>&);
+void getProgramEntrypoint(VM&, RefPtr<JITCode>&);
+
+inline void getEntrypoint(VM& vm, EvalCodeBlock*, RefPtr<JITCode>& jitCode)
+{
+ getEvalEntrypoint(vm, jitCode);
+}
+
+inline void getEntrypoint(VM& vm, ProgramCodeBlock*, RefPtr<JITCode>& jitCode)
+{
+ getProgramEntrypoint(vm, jitCode);
+}
} } // namespace JSC::LLInt
#include "HostCallReturnValue.h"
#include "Interpreter.h"
#include "JIT.h"
+#include "JITDriver.h"
#include "JSActivation.h"
#include "JSCJSValue.h"
#include "JSGlobalObjectFunctions.h"
// Returns true if we should try to OSR.
inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
{
- DeferGC deferGC(exec->vm().heap);
-
codeBlock->updateAllValueProfilePredictions();
if (!codeBlock->checkIfJITThresholdReached()) {
return false;
}
- switch (codeBlock->jitType()) {
- case JITCode::BaselineJIT: {
+ CompilationResult result = codeBlock->jitCompile(exec);
+ switch (result) {
+ case CompilationNotNeeded:
if (Options::verboseOSR())
dataLogF(" Code was already compiled.\n");
codeBlock->jitSoon();
return true;
- }
- case JITCode::InterpreterThunk: {
- CompilationResult result = codeBlock->prepareForExecution(
- exec, JITCode::BaselineJIT, JITCompilationCanFail);
- switch (result) {
- case CompilationFailed:
- if (Options::verboseOSR())
- dataLogF(" JIT compilation failed.\n");
- codeBlock->dontJITAnytimeSoon();
- return false;
- case CompilationSuccessful:
- if (Options::verboseOSR())
- dataLogF(" JIT compilation successful.\n");
- codeBlock->install();
- codeBlock->jitSoon();
- return true;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return false;
- }
- }
+ case CompilationFailed:
+ if (Options::verboseOSR())
+ dataLogF(" JIT compilation failed.\n");
+ codeBlock->dontJITAnytimeSoon();
+ return false;
+ case CompilationSuccessful:
+ if (Options::verboseOSR())
+ dataLogF(" JIT compilation successful.\n");
+ codeBlock->jitSoon();
+ return true;
default:
RELEASE_ASSERT_NOT_REACHED();
return false;
codePtr = executable->hostCodeEntryFor(kind);
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
+ JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
if (error)
LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
FunctionExecutable* executable = callData.js.functionExecutable;
- JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall);
+ JSObject* error = executable->compileForCall(exec, callData.js.scope);
if (error)
return false;
#include "HostCallReturnValue.h"
#include "Interpreter.h"
#include "JIT.h"
+#include "JITDriver.h"
#include "JITStubs.h"
#include "JSActivation.h"
#include "JSCJSValue.h"
case CompilationSuccessful:
out.print("CompilationSuccessful");
return;
+ case CompilationNotNeeded:
+ out.print("CompilationNotNeeded");
+ return;
case CompilationDeferred:
out.print("CompilationDeferred");
return;
namespace JSC {
-enum CompilationResult {
- // We tried to compile the code, but we couldn't compile it. This could be
- // because we ran out of memory, or because the compiler encountered an
- // internal error and decided to bail out gracefully. Either way, this implies
- // that we shouldn't try to compile this code block again.
- CompilationFailed,
-
- // The profiling assumptions that were fed into the compiler were invalidated
- // even before we finished compiling. This means we should try again: in such
- // cases the profiling will now be updated and the next compilation won't
- // encounter the same problem. But it does mean that we should exercise
- // exponential back-off, to get even more profiling so that new profiling
- // pathologies aren't encountered.
- CompilationInvalidated,
-
- // The compilation succeeded and the code block now has JITCode for the newly
- // compiled code. However, compilation success doesn't mean that the CodeBlock
- // will execute yet; you typically have to install it first, unless you plan
- // on invoking it manually (something that *could* be done for some kinds of
- // OSR entry).
- CompilationSuccessful,
-
- // We decided to do the compilation asynchronously. This means that we haven't
- // yet compiled the code. This only happens when you pass a
- // DeferredCompilationCallback. That callback will get called with some
- // interesting result, once compilation completes.
- CompilationDeferred
-};
+enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred };
} // namespace JSC
/*
- * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "BytecodeGenerator.h"
#include "CodeBlock.h"
#include "DFGDriver.h"
+#include "ExecutionHarness.h"
#include "JIT.h"
+#include "JITDriver.h"
#include "Operations.h"
#include "Parser.h"
#include <wtf/Vector.h>
}
#endif
-void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
-{
- RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
-
- VM& vm = *genericCodeBlock->vm();
-
- if (vm.m_perBytecodeProfiler)
- vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock);
-
- ASSERT(vm.heap.isDeferred());
-
- if (JITCode::isJIT(genericCodeBlock->jitType())) {
- vm.heap.reportExtraMemoryCost(
- sizeof(CodeBlock) + genericCodeBlock->jitCode()->size());
- } else
- vm.heap.reportExtraMemoryCost(sizeof(CodeBlock));
-
- CodeSpecializationKind kind = genericCodeBlock->specializationKind();
-
- RefPtr<CodeBlock> oldCodeBlock;
-
- switch (kind) {
- case CodeForCall:
- m_jitCodeForCall = genericCodeBlock->jitCode();
- m_jitCodeForCallWithArityCheck = genericCodeBlock->jitCodeWithArityCheck();
- m_numParametersForCall = genericCodeBlock->numParameters();
- break;
- case CodeForConstruct:
- m_jitCodeForConstruct = genericCodeBlock->jitCode();
- m_jitCodeForConstructWithArityCheck = genericCodeBlock->jitCodeWithArityCheck();
- m_numParametersForConstruct = genericCodeBlock->numParameters();
- break;
- }
-
- switch (genericCodeBlock->codeType()) {
- case GlobalCode: {
- ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
- ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock);
-
- ASSERT(!codeBlock->jitCodeWithArityCheck());
- ASSERT(kind == CodeForCall);
-
- oldCodeBlock = executable->m_programCodeBlock;
- executable->m_programCodeBlock = codeBlock;
- break;
- }
-
- case EvalCode: {
- EvalExecutable* executable = jsCast<EvalExecutable*>(this);
- EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock);
-
- ASSERT(!codeBlock->jitCodeWithArityCheck());
- ASSERT(kind == CodeForCall);
-
- oldCodeBlock = executable->m_evalCodeBlock;
- executable->m_evalCodeBlock = codeBlock;
- break;
- }
-
- case FunctionCode: {
- FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
- FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock);
-
- switch (kind) {
- case CodeForCall:
- oldCodeBlock = executable->m_codeBlockForCall;
- executable->m_codeBlockForCall = codeBlock;
- break;
- case CodeForConstruct:
- oldCodeBlock = executable->m_codeBlockForConstruct;
- executable->m_codeBlockForConstruct = codeBlock;
- break;
- }
- break;
- } }
-
- if (oldCodeBlock)
- oldCodeBlock->unlinkIncomingCalls();
-}
-
-PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
- CodeSpecializationKind kind, JSScope* scope, JSObject*& exception)
-{
- VM* vm = scope->vm();
-
- ASSERT(vm->heap.isDeferred());
-
- if (classInfo() == EvalExecutable::info()) {
- EvalExecutable* executable = jsCast<EvalExecutable*>(this);
- RELEASE_ASSERT(kind == CodeForCall);
- RELEASE_ASSERT(!executable->m_evalCodeBlock);
- return adoptRef(new EvalCodeBlock(
- executable, executable->m_unlinkedEvalCodeBlock.get(), scope,
- executable->source().provider()));
- }
-
- if (classInfo() == ProgramExecutable::info()) {
- ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
- RELEASE_ASSERT(kind == CodeForCall);
- RELEASE_ASSERT(!executable->m_programCodeBlock);
- return adoptRef(new ProgramCodeBlock(
- executable, executable->m_unlinkedProgramCodeBlock.get(), scope,
- executable->source().provider(), executable->source().startColumn()));
- }
-
- RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
- FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
- RELEASE_ASSERT(!executable->codeBlockFor(kind));
- JSGlobalObject* globalObject = scope->globalObject();
- ParserError error;
- DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
- ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
- UnlinkedFunctionCodeBlock* unlinkedCodeBlock =
- executable->m_unlinkedExecutable->codeBlockFor(
- *vm, executable->m_source, kind, debuggerMode, profilerMode, error);
- if (!unlinkedCodeBlock) {
- exception = vm->throwException(
- globalObject->globalExec(),
- error.toErrorObject(globalObject, executable->m_source));
- return 0;
- }
-
- SourceProvider* provider = executable->source().provider();
- unsigned sourceOffset = executable->source().startOffset();
- unsigned startColumn = executable->source().startColumn();
-
- return adoptRef(new FunctionCodeBlock(
- executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
-}
-
-PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor(
- CodeSpecializationKind kind)
-{
- if (classInfo() == EvalExecutable::info()) {
- RELEASE_ASSERT(kind == CodeForCall);
- EvalExecutable* executable = jsCast<EvalExecutable*>(this);
- RefPtr<EvalCodeBlock> result = adoptRef(new EvalCodeBlock(
- CodeBlock::CopyParsedBlock, *executable->m_evalCodeBlock));
- result->setAlternative(executable->m_evalCodeBlock);
- return result;
- }
-
- if (classInfo() == ProgramExecutable::info()) {
- RELEASE_ASSERT(kind == CodeForCall);
- ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
- RefPtr<ProgramCodeBlock> result = adoptRef(new ProgramCodeBlock(
- CodeBlock::CopyParsedBlock, *executable->m_programCodeBlock));
- result->setAlternative(executable->m_programCodeBlock);
- return result;
- }
-
- RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
- FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
- RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(
- CodeBlock::CopyParsedBlock, *executable->codeBlockFor(kind)));
- result->setAlternative(executable->codeBlockFor(kind));
- return result;
-}
-
-JSObject* ScriptExecutable::prepareForExecutionImpl(
- ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
-{
- VM& vm = exec->vm();
- DeferGC deferGC(vm.heap);
-
- JSObject* exception = 0;
- RefPtr<CodeBlock> codeBlock = newCodeBlockFor(kind, scope, exception);
- if (!codeBlock) {
- RELEASE_ASSERT(exception);
- return exception;
- }
-
- JITCode::JITType jitType;
-#if ENABLE(LLINT)
- jitType = JITCode::InterpreterThunk;
-#else
- jitType = JITCode::BaselineJIT;
-#endif
- codeBlock->prepareForExecution(exec, jitType);
-
- installCode(codeBlock.get());
- return 0;
-}
-
const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext)
static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
}
+#if ENABLE(DFG_JIT)
+JSObject* EvalExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+{
+ ASSERT(exec->vm().dynamicGlobalObject);
+ ASSERT(!!m_evalCodeBlock);
+ JSObject* error = 0;
+ if (!JITCode::isOptimizingJIT(m_evalCodeBlock->jitType()))
+ error = compileInternal(exec, scope, JITCode::nextTierJIT(m_evalCodeBlock->jitType()), &result, bytecodeIndex);
+ else
+ result = CompilationNotNeeded;
+ ASSERT(!!m_evalCodeBlock);
+ return error;
+}
+#endif // ENABLE(DFG_JIT)
+
+#if ENABLE(JIT)
+CompilationResult EvalExecutable::jitCompile(ExecState* exec)
+{
+ return jitCompileIfAppropriate(exec, m_evalCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
+}
+#endif
+
inline const char* samplingDescription(JITCode::JITType jitType)
{
switch (jitType) {
}
}
+JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
+{
+ SamplingRegion samplingRegion(samplingDescription(jitType));
+
+ if (result)
+ *result = CompilationFailed;
+
+ RefPtr<EvalCodeBlock> newCodeBlock;
+
+ if (!!m_evalCodeBlock) {
+ newCodeBlock = adoptRef(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
+ newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock));
+ } else {
+ newCodeBlock = adoptRef(new EvalCodeBlock(this, m_unlinkedEvalCodeBlock.get(), scope, source().provider()));
+ ASSERT((jitType == JITCode::bottomTierJIT()) == !m_evalCodeBlock);
+ }
+
+ CompilationResult theResult = prepareForExecution(
+ exec, m_evalCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);
+ if (result)
+ *result = theResult;
+
+ return 0;
+}
+
+#if ENABLE(DFG_JIT)
+CompilationResult EvalExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
+{
+ return JSC::replaceWithDeferredOptimizedCode(
+ plan, m_evalCodeBlock, m_jitCodeForCall, 0, 0);
+}
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void EvalExecutable::jettisonOptimizedCode(VM& vm)
{
return error.toErrorObject(lexicalGlobalObject, m_source);
}
+#if ENABLE(DFG_JIT)
+JSObject* ProgramExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+{
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ ASSERT(!!m_programCodeBlock);
+ JSObject* error = 0;
+ if (!JITCode::isOptimizingJIT(m_programCodeBlock->jitType()))
+ error = compileInternal(exec, scope, JITCode::nextTierJIT(m_programCodeBlock->jitType()), &result, bytecodeIndex);
+ else
+ result = CompilationNotNeeded;
+ ASSERT(!!m_programCodeBlock);
+ return error;
+}
+#endif // ENABLE(DFG_JIT)
+
+#if ENABLE(JIT)
+CompilationResult ProgramExecutable::jitCompile(ExecState* exec)
+{
+ return jitCompileIfAppropriate(exec, m_programCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
+}
+#endif
+
+JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
+{
+ SamplingRegion samplingRegion(samplingDescription(jitType));
+
+ if (result)
+ *result = CompilationFailed;
+
+ RefPtr<ProgramCodeBlock> newCodeBlock;
+
+ if (!!m_programCodeBlock) {
+ newCodeBlock = adoptRef(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));
+ newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock));
+ } else {
+ newCodeBlock = adoptRef(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), scope, source().provider(), source().startColumn()));
+ }
+
+ CompilationResult theResult = prepareForExecution(
+ exec, m_programCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);
+ if (result)
+ *result = theResult;
+
+ return 0;
+}
+
+#if ENABLE(DFG_JIT)
+CompilationResult ProgramExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
+{
+ return JSC::replaceWithDeferredOptimizedCode(
+ plan, m_programCodeBlock, m_jitCodeForCall, 0, 0);
+}
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void ProgramExecutable::jettisonOptimizedCode(VM& vm)
{
return result;
}
+#if ENABLE(DFG_JIT)
+JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+{
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ ASSERT(!!m_codeBlockForCall);
+ JSObject* error = 0;
+ if (!JITCode::isOptimizingJIT(m_codeBlockForCall->jitType()))
+ error = compileForCallInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForCall->jitType()), &result, bytecodeIndex);
+ else
+ result = CompilationNotNeeded;
+ ASSERT(!!m_codeBlockForCall);
+ return error;
+}
+
+JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+{
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ ASSERT(!!m_codeBlockForConstruct);
+ JSObject* error = 0;
+ if (!JITCode::isOptimizingJIT(m_codeBlockForConstruct->jitType()))
+ error = compileForConstructInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForConstruct->jitType()), &result, bytecodeIndex);
+ else
+ result = CompilationNotNeeded;
+ ASSERT(!!m_codeBlockForConstruct);
+ return error;
+}
+#endif // ENABLE(DFG_JIT)
+
+#if ENABLE(JIT)
+CompilationResult FunctionExecutable::jitCompileForCall(ExecState* exec)
+{
+ return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
+}
+
+CompilationResult FunctionExecutable::jitCompileForConstruct(ExecState* exec)
+{
+ return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
+}
+#endif
+
+PassRefPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)
+{
+ RefPtr<FunctionCodeBlock> alternative = codeBlockFor(specializationKind);
+
+ if (!!alternative) {
+ RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
+ result->setAlternative(alternative);
+ return result.release();
+ }
+
+ VM* vm = scope->vm();
+ JSGlobalObject* globalObject = scope->globalObject();
+ ParserError error;
+ DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
+ ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
+ UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, m_source, specializationKind, debuggerMode, profilerMode, error);
+ recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());
+
+ if (!unlinkedCodeBlock) {
+ exception = vm->throwException(globalObject->globalExec(), error.toErrorObject(globalObject, m_source));
+ return 0;
+ }
+
+ SourceProvider* provider = source().provider();
+ unsigned sourceOffset = source().startOffset();
+ unsigned startColumn = source().startColumn();
+
+ return adoptRef(new FunctionCodeBlock(this, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
+}
+
+
+JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
+{
+ SamplingRegion samplingRegion(samplingDescription(jitType));
+
+ if (result)
+ *result = CompilationFailed;
+
+ ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);
+ JSObject* exception = 0;
+
+ RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception);
+ if (!newCodeBlock)
+ return exception;
+
+ CompilationResult theResult = prepareFunctionForExecution(
+ exec, m_codeBlockForCall, newCodeBlock.get(), m_jitCodeForCall,
+ m_jitCodeForCallWithArityCheck, m_numParametersForCall, jitType,
+ bytecodeIndex, CodeForCall);
+ if (result)
+ *result = theResult;
+ return 0;
+}
+
+#if ENABLE(DFG_JIT)
+CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan> plan)
+{
+ return JSC::replaceWithDeferredOptimizedCode(
+ plan, m_codeBlockForCall, m_jitCodeForCall, &m_jitCodeForCallWithArityCheck,
+ &m_numParametersForCall);
+}
+#endif // ENABLE(DFG_JIT)
+
+JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
+{
+ SamplingRegion samplingRegion(samplingDescription(jitType));
+
+ if (result)
+ *result = CompilationFailed;
+
+ ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);
+ JSObject* exception = 0;
+ RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception);
+ if (!newCodeBlock)
+ return exception;
+
+ CompilationResult theResult = prepareFunctionForExecution(
+ exec, m_codeBlockForConstruct, newCodeBlock.get(), m_jitCodeForConstruct,
+ m_jitCodeForConstructWithArityCheck, m_numParametersForConstruct, jitType,
+ bytecodeIndex, CodeForConstruct);
+ if (result)
+ *result = theResult;
+
+ return 0;
+}
+
+#if ENABLE(DFG_JIT)
+CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan> plan)
+{
+ return JSC::replaceWithDeferredOptimizedCode(
+ plan, m_codeBlockForConstruct, m_jitCodeForConstruct,
+ &m_jitCodeForConstructWithArityCheck, &m_numParametersForConstruct);
+}
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void FunctionExecutable::jettisonOptimizedCodeForCall(VM& vm)
{
return generatedJITCodeForConstructWithArityCheck();
}
- static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
- {
- if (kind == CodeForCall)
- return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
- ASSERT(kind == CodeForConstruct);
- return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
- }
-
- static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
- {
- if (kind == CodeForCall)
- return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
- ASSERT(kind == CodeForConstruct);
- return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
- }
-#endif // ENABLE(JIT)
-
bool hasJITCodeForCall() const
{
return m_numParametersForCall >= 0;
return hasJITCodeForConstruct();
}
+ static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
+ ASSERT(kind == CodeForConstruct);
+ return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
+ }
+
+ static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
+ ASSERT(kind == CodeForConstruct);
+ return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
+ }
+#endif // ENABLE(JIT)
+
// Intrinsics are only for calls, currently.
Intrinsic intrinsic() const;
return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter);
#endif
}
-
#endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
protected:
m_startColumn = startColumn;
}
- void installCode(CodeBlock*);
- PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception);
- PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
-
- JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
- {
- if (hasJITCodeFor(kind))
- return 0;
- return prepareForExecutionImpl(exec, scope, kind);
- }
-
-private:
- JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind);
-
protected:
void finishCreation(VM& vm)
{
static void destroy(JSCell*);
+ JSObject* compile(ExecState* exec, JSScope* scope)
+ {
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ JSObject* error = 0;
+ if (!m_evalCodeBlock)
+ error = compileInternal(exec, scope, JITCode::bottomTierJIT());
+ ASSERT(!error == !!m_evalCodeBlock);
+ return error;
+ }
+
+#if ENABLE(DFG_JIT)
+ JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void jettisonOptimizedCode(VM&);
+ CompilationResult jitCompile(ExecState*);
#endif
EvalCodeBlock& generatedBytecode()
unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
private:
- friend class ScriptExecutable;
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
EvalExecutable(ExecState*, const SourceCode&, bool);
+ JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
static void visitChildren(JSCell*, SlotVisitor&);
RefPtr<EvalCodeBlock> m_evalCodeBlock;
static void destroy(JSCell*);
+ JSObject* compile(ExecState* exec, JSScope* scope)
+ {
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ JSObject* error = 0;
+ if (!m_programCodeBlock)
+ error = compileInternal(exec, scope, JITCode::bottomTierJIT());
+ ASSERT(!error == !!m_programCodeBlock);
+ return error;
+ }
+
+#if ENABLE(DFG_JIT)
+ JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void jettisonOptimizedCode(VM&);
+ CompilationResult jitCompile(ExecState*);
#endif
ProgramCodeBlock& generatedBytecode()
ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
private:
- friend class ScriptExecutable;
-
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
ProgramExecutable(ExecState*, const SourceCode&);
+ JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
return *m_codeBlockForConstruct;
}
+ PassRefPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);
+
+ JSObject* compileForCall(ExecState* exec, JSScope* scope)
+ {
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ JSObject* error = 0;
+ if (!m_codeBlockForCall)
+ error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT());
+ ASSERT(!error == !!m_codeBlockForCall);
+ return error;
+ }
+
+#if ENABLE(DFG_JIT)
+ JSObject* compileOptimizedForCall(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ CompilationResult replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void jettisonOptimizedCodeForCall(VM&);
+ CompilationResult jitCompileForCall(ExecState*);
#endif
bool isGeneratedForCall() const
return *m_codeBlockForCall;
}
+ JSObject* compileForConstruct(ExecState* exec, JSScope* scope)
+ {
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
+ JSObject* error = 0;
+ if (!m_codeBlockForConstruct)
+ error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT());
+ ASSERT(!error == !!m_codeBlockForConstruct);
+ return error;
+ }
+
+#if ENABLE(DFG_JIT)
+ JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
+ CompilationResult replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan>);
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void jettisonOptimizedCodeForConstruct(VM&);
+ CompilationResult jitCompileForConstruct(ExecState*);
#endif
bool isGeneratedForConstruct() const
return *m_codeBlockForConstruct;
}
+ JSObject* compileFor(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
+ {
+ ASSERT(exec->callee());
+ ASSERT(exec->callee()->inherits(JSFunction::info()));
+ ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
+
+ if (kind == CodeForCall)
+ return compileForCall(exec, scope);
+ ASSERT(kind == CodeForConstruct);
+ return compileForConstruct(exec, scope);
+ }
+
+#if ENABLE(DFG_JIT)
+ JSObject* compileOptimizedFor(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex, CodeSpecializationKind kind)
+ {
+ ASSERT(exec->callee());
+ ASSERT(exec->callee()->inherits(JSFunction::info()));
+ ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
+
+ if (kind == CodeForCall)
+ return compileOptimizedForCall(exec, scope, result, bytecodeIndex);
+ ASSERT(kind == CodeForConstruct);
+ return compileOptimizedForConstruct(exec, scope, result, bytecodeIndex);
+ }
+
+ CompilationResult replaceWithDeferredOptimizedCodeFor(PassRefPtr<DFG::Plan> plan, CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return replaceWithDeferredOptimizedCodeForCall(plan);
+ return replaceWithDeferredOptimizedCodeForConstruct(plan);
+ }
+#endif // ENABLE(DFG_JIT)
+
#if ENABLE(JIT)
void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
{
jettisonOptimizedCodeForConstruct(vm);
}
}
+
+ CompilationResult jitCompileFor(ExecState* exec, CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return jitCompileForCall(exec);
+ ASSERT(kind == CodeForConstruct);
+ return jitCompileForConstruct(exec);
+ }
#endif
bool isGeneratedFor(CodeSpecializationKind kind)
private:
FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
+ JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
+ JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
+
RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
{
if (kind == CodeForCall)
return false;
}
- friend class ScriptExecutable;
-
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
RefPtr<FunctionCodeBlock> m_codeBlockForCall;
--- /dev/null
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ExecutionHarness_h
+#define ExecutionHarness_h
+
+#include <wtf/Platform.h>
+
+#include "CompilationResult.h"
+#include "DFGDriver.h"
+#include "DFGPlan.h"
+#include "JITDriver.h"
+#include "LLIntEntrypoints.h"
+
+namespace JSC {
+
+template<typename CodeBlockType>
+inline CompilationResult prepareForExecutionImpl(
+ ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
+ JITCode::JITType jitType, unsigned bytecodeIndex)
+{
+ UNUSED_PARAM(bytecodeIndex);
+#if ENABLE(LLINT)
+ if (JITCode::isBaselineCode(jitType)) {
+ // Start off in the low level interpreter.
+ LLInt::getEntrypoint(exec->vm(), codeBlock, jitCode);
+ if (exec->vm().m_perBytecodeProfiler)
+ exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock);
+ return CompilationSuccessful;
+ }
+#endif // ENABLE(LLINT)
+#if ENABLE(JIT)
+ return jitCompileIfAppropriateImpl(
+ exec, codeBlock, jitCode, jitType, bytecodeIndex,
+ JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
+#endif
+ RELEASE_ASSERT_NOT_REACHED();
+ return CompilationFailed;
+}
+
+inline CompilationResult prepareFunctionForExecutionImpl(
+ ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
+ MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
+ unsigned bytecodeIndex, CodeSpecializationKind kind)
+{
+ UNUSED_PARAM(bytecodeIndex);
+ UNUSED_PARAM(jitCodeWithArityCheck);
+#if ENABLE(LLINT)
+ if (JITCode::isBaselineCode(jitType)) {
+ // Start off in the low level interpreter.
+ LLInt::getFunctionEntrypoint(exec->vm(), kind, jitCode, jitCodeWithArityCheck);
+ if (exec->vm().m_perBytecodeProfiler)
+ exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock);
+ return CompilationSuccessful;
+ }
+#else
+ UNUSED_PARAM(kind);
+#endif // ENABLE(LLINT)
+#if ENABLE(JIT)
+ return jitCompileFunctionIfAppropriateImpl(
+ exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex,
+ JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
+#endif
+ RELEASE_ASSERT_NOT_REACHED();
+ return CompilationFailed;
+}
+
+template<typename CodeBlockType>
+inline CompilationResult installOptimizedCode(
+ CompilationResult result, RefPtr<CodeBlockType>& sink, CodeBlockType* codeBlock,
+ PassRefPtr<JITCode> jitCode, MacroAssemblerCodePtr jitCodeWithArityCheck,
+ int* numParameters)
+{
+ UNUSED_PARAM(jitCodeWithArityCheck);
+ if (result != CompilationSuccessful)
+ return result;
+
+#if ENABLE(JIT)
+ codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
+#endif
+
+ sink = codeBlock;
+
+ if (numParameters)
+ *numParameters = codeBlock->numParameters();
+
+ if (jitCode)
+ codeBlock->vm()->heap.reportExtraMemoryCost(sizeof(*codeBlock) + jitCode->size());
+ else
+ codeBlock->vm()->heap.reportExtraMemoryCost(sizeof(*codeBlock));
+
+ if (sink != codeBlock) {
+ // This can happen if we GC and decide that the code is invalid.
+ return CompilationInvalidated;
+ }
+
+ return result;
+}
+
+template<typename CodeBlockType>
+inline CompilationResult prepareForExecution(
+ ExecState* exec, RefPtr<CodeBlockType>& sink, CodeBlockType* codeBlock,
+ RefPtr<JITCode>& jitCode, JITCode::JITType jitType, unsigned bytecodeIndex)
+{
+ CompilationResult result = prepareForExecutionImpl(exec, codeBlock, jitCode, jitType, bytecodeIndex);
+ return installOptimizedCode(result, sink, codeBlock, jitCode, MacroAssemblerCodePtr(), 0);
+}
+
+inline CompilationResult prepareFunctionForExecution(
+ ExecState* exec, RefPtr<FunctionCodeBlock>& sink, FunctionCodeBlock* codeBlock,
+ RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck,
+ int& numParameters, JITCode::JITType jitType, unsigned bytecodeIndex,
+ CodeSpecializationKind kind)
+{
+ CompilationResult result = prepareFunctionForExecutionImpl(exec, codeBlock,
+ jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, kind);
+ return installOptimizedCode(result, sink, codeBlock, jitCode, jitCodeWithArityCheck, &numParameters);
+}
+
+#if ENABLE(DFG_JIT)
+template<typename CodeBlockType>
+inline CompilationResult replaceWithDeferredOptimizedCode(
+ PassRefPtr<DFG::Plan> passedPlan, RefPtr<CodeBlockType>& sink, RefPtr<JITCode>& jitCode,
+ MacroAssemblerCodePtr* jitCodeWithArityCheck, int* numParameters)
+{
+ RefPtr<DFG::Plan> plan = passedPlan;
+ CompilationResult result = DFG::tryFinalizePlan(plan, jitCode, jitCodeWithArityCheck);
+ if (Options::verboseOSR()) {
+ dataLog(
+ "Deferred optimizing compilation ", *plan->key(), " -> ", *plan->codeBlock,
+ " result: ", result, "\n");
+ }
+ if (result == CompilationSuccessful)
+ plan->codeBlock->alternative()->unlinkIncomingCalls();
+ return installOptimizedCode(
+ result, sink, static_cast<CodeBlockType*>(plan->codeBlock.get()), jitCode,
+ jitCodeWithArityCheck ? *jitCodeWithArityCheck : MacroAssemblerCodePtr(),
+ numParameters);
+}
+#endif // ENABLE(DFG_JIT)
+
+} // namespace JSC
+
+#endif // ExecutionHarness_h
+