WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 118.83 KB, created by
Filip Pizlo
on 2013-08-27 21:46:03 PDT
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-08-27 21:46:03 PDT
Size:
118.83 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 154722) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,174 @@ >+2013-08-27 Filip Pizlo <fpizlo@apple.com> >+ >+ CodeBlock compilation and installation should be simplified and rationalized >+ https://bugs.webkit.org/show_bug.cgi?id=120326 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Previously Executable owned the code for generating JIT code; you always had >+ to go through Executable. But often you also had to go through CodeBlock, >+ because ScriptExecutable couldn't have virtual methods, but CodeBlock could. >+ So you'd ask CodeBlock to do something, which would dispatch through a >+ virtual method that would select the appropriate Executable subtype's method. >+ This all meant that the same code would often be duplicated, because most of >+ the work needed to compile something was identical regardless of code type. >+ But then we tried to fix this, by having templatized helpers in >+ ExecutionHarness.h and JITDriver.h. The result was that if you wanted to find >+ out what happened when you asked for something to be compiled, you'd go on a >+ wild ride that started with CodeBlock, touched upon Executable, and then >+ ricocheted into either ExecutionHarness or JITDriver (likely both). >+ >+ Another awkwardness was that for concurrent compiles, the DFG::Worklist had >+ super-special inside knowledge of what JITStubs.cpp's cti_optimize would have >+ done once the compilation finished. >+ >+ Also, most of the DFG JIT drivers assumed that they couldn't install the >+ JITCode into the CodeBlock directly - instead they would return it via a >+ reference, which happened to be a reference to the JITCode pointer in >+ Executable. This was super weird. >+ >+ Finally, there was no notion of compiling code into a special CodeBlock that >+ wasn't used for handling calls into an Executable. I'd like this for FTL OSR >+ entry. >+ >+ This patch solves these problems by reducing all of that complexity into just >+ three primitives: >+ >+ - Executable::newCodeBlock(). This gives you a new code block, either for call >+ or for construct, and either to serve as the baseline code or the optimized >+ code. The new code block is then owned by the caller; Executable doesn't >+ register it anywhere. The new code block has no JITCode and isn't callable, >+ but it has all of the bytecode. >+ >+ - CodeBlock::prepareForExecution(). This takes the CodeBlock's bytecode and >+ produces a JITCode, and then installs the JITCode into the CodeBlock. This >+ method takes a JITType, and always compiles with that JIT. If you ask for >+ JITCode::InterpreterThunk then you'll get JITCode that just points to the >+ LLInt entrypoints. Once this returns, it is possible to call into the >+ CodeBlock if you do so manually - but the Executable still won't know about >+ it so JS calls to that Executable will still be routed to whatever CodeBlock >+ is associated with the Executable. >+ >+ - Executable::installCode(). This takes a CodeBlock and makes it the code-for- >+ entry for that Executable. This involves unlinking the Executable's last >+ CodeBlock, if there was one. This also tells the GC about any effect on >+ memory usage and does a bunch of weird data structure rewiring, since >+ Executable caches some of CodeBlock's fields for the benefit of virtual call >+ fast paths. >+ >+ This functionality is then wrapped around three convenience methods: >+ >+ - Executable::prepareForExecution(). If there is no code block for that >+ Executable, then one is created (newCodeBlock()), compiled >+ (CodeBlock::prepareForExecution()) and installed (installCode()). >+ >+ - CodeBlock::newReplacement(). Asks the Executable for a new CodeBlock that >+ can serve as an optimized replacement of the current one. >+ >+ - CodeBlock::install(). Asks the Executable to install this code block. >+ >+ This patch allows me to kill *a lot* of code and to remove a lot of >+ specializations for functions vs. not-functions, and a lot of places where we >+ pass around JITCode references and such. >+ >+ It also allows me to work on FTL OSR entry and tier-up: >+ >+ - FTL tier-up: this will involve DFGOperations.cpp asking the DFG::Worklist >+ to do some compilation, but it will require the DFG::Worklist to do >+ something different than what JITStubs.cpp would want, once the compilation >+ finishes. This patch introduces a callback mechanism for that purpose. >+ >+ - FTL OSR entry: this will involve creating a special auto-jettisoned >+ CodeBlock that is used only for FTL OSR entry. The new set of primitives >+ allows for this: Executable can vend you a fresh new CodeBlock, and you can >+ ask that CodeBlock to compile itself with any JIT of your choosing. Or you >+ can take that CodeBlock and compile it yourself. Previously the act of >+ producing a CodeBlock-for-optimization and the act of compiling code for it >+ were tightly coupled; now you can separate them and you can create such >+ auto-jettisoned CodeBlocks that are used for a one-shot OSR entry. >+ >+ * CMakeLists.txt: >+ * GNUmakefile.list.am: >+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Target.pri: >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::prepareForExecution): >+ (JSC::CodeBlock::install): >+ (JSC::CodeBlock::newReplacement): >+ (JSC::FunctionCodeBlock::jettisonImpl): >+ (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult): >+ * bytecode/CodeBlock.h: >+ (JSC::CodeBlock::hasBaselineJITProfiling): >+ * bytecode/DeferredCompilationCallback.cpp: Added. >+ (JSC::DeferredCompilationCallback::DeferredCompilationCallback): >+ (JSC::DeferredCompilationCallback::~DeferredCompilationCallback): >+ * bytecode/DeferredCompilationCallback.h: Added. >+ * dfg/DFGDriver.cpp: >+ (JSC::DFG::tryCompile): >+ * dfg/DFGDriver.h: >+ (JSC::DFG::tryCompile): >+ * 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::finalizeWithoutNotifyingCallback): >+ (JSC::DFG::Plan::finalizeAndNotifyCallback): >+ * dfg/DFGPlan.h: >+ * dfg/DFGWorklist.cpp: >+ (JSC::DFG::Worklist::completeAllReadyPlansForVM): >+ * heap/Heap.h: >+ (JSC::Heap::isDeferred): >+ * interpreter/Interpreter.cpp: >+ (JSC::Interpreter::execute): >+ (JSC::Interpreter::executeCall): >+ (JSC::Interpreter::executeConstruct): >+ (JSC::Interpreter::prepareForRepeatCall): >+ * jit/JITDriver.h: Removed. >+ * jit/JITStubs.cpp: >+ (JSC::DEFINE_STUB_FUNCTION): >+ (JSC::jitCompileFor): >+ (JSC::lazyLinkFor): >+ * jit/JITToDFGDeferredCompilationCallback.cpp: Added. >+ (JSC::JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback): >+ (JSC::JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback): >+ (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete): >+ * jit/JITToDFGDeferredCompilationCallback.h: Added. >+ * llint/LLIntEntrypoints.cpp: >+ (JSC::LLInt::setFunctionEntrypoint): >+ (JSC::LLInt::setEvalEntrypoint): >+ (JSC::LLInt::setProgramEntrypoint): >+ * llint/LLIntEntrypoints.h: >+ * 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::ScriptExecutable::installCode): >+ (JSC::ScriptExecutable::newCodeBlockFor): >+ (JSC::ScriptExecutable::newReplacementCodeBlockFor): >+ (JSC::ScriptExecutable::prepareForExecutionImpl): >+ * runtime/Executable.h: >+ (JSC::ScriptExecutable::prepareForExecution): >+ (JSC::FunctionExecutable::jettisonOptimizedCodeFor): >+ * runtime/ExecutionHarness.h: Removed. >+ > 2013-08-23 Andy Estes <aestes@apple.com> > > Fix issues found by the Clang Static Analyzer >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 154718) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -53,6 +53,7 @@ set(JavaScriptCore_SOURCES > bytecode/CodeOrigin.cpp > bytecode/CodeType.cpp > bytecode/DFGExitProfile.cpp >+ bytecode/DeferredCompilationCallback.cpp > bytecode/ExecutionCounter.cpp > bytecode/ExitKind.cpp > bytecode/GetByIdStatus.cpp >@@ -243,6 +244,7 @@ set(JavaScriptCore_SOURCES > jit/JITStubRoutine.cpp > jit/JITStubs.cpp > jit/JITThunks.cpp >+ jit/JITToDFGDeferredCompilationCallback.cpp > jit/JumpReplacementWatchpoint.cpp > jit/ThunkGenerators.cpp > >Index: Source/JavaScriptCore/GNUmakefile.list.am >=================================================================== >--- Source/JavaScriptCore/GNUmakefile.list.am (revision 154718) >+++ Source/JavaScriptCore/GNUmakefile.list.am (working copy) >@@ -113,9 +113,11 @@ javascriptcore_sources += \ > 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 \ >@@ -569,6 +571,8 @@ javascriptcore_sources += \ > 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 \ >Index: Source/JavaScriptCore/Target.pri >=================================================================== >--- Source/JavaScriptCore/Target.pri (revision 154718) >+++ Source/JavaScriptCore/Target.pri (working copy) >@@ -61,6 +61,7 @@ SOURCES += \ > bytecode/CodeOrigin.cpp \ > bytecode/CodeType.cpp \ > bytecode/DFGExitProfile.cpp \ >+ bytecode/DeferredCompilationCallback.cpp \ > bytecode/ExecutionCounter.cpp \ > bytecode/ExitKind.cpp \ > bytecode/GetByIdStatus.cpp \ >@@ -221,6 +222,7 @@ SOURCES += \ > jit/JITStubRoutine.cpp \ > jit/JITStubs.cpp \ > jit/JITThunks.cpp \ >+ jit/JITToDFGDeferredCompilationCallback.cpp \ > jit/JumpReplacementWatchpoint.cpp \ > jit/ThunkGenerators.cpp \ > llint/LLIntCLoop.cpp \ >Index: Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (revision 154718) >+++ Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (working copy) >@@ -302,6 +302,7 @@ > <ClCompile Include="..\bytecode\CodeBlockHash.cpp" /> > <ClCompile Include="..\bytecode\CodeOrigin.cpp" /> > <ClCompile Include="..\bytecode\CodeType.cpp" /> >+ <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" /> > <ClCompile Include="..\bytecode\ExecutionCounter.cpp" /> > <ClCompile Include="..\bytecode\ExitKind.cpp" /> > <ClCompile Include="..\bytecode\GetByIdStatus.cpp" /> >@@ -377,6 +378,7 @@ > <ClCompile Include="..\jit\JITStubRoutine.cpp" /> > <ClCompile Include="..\jit\JITStubs.cpp" /> > <ClCompile Include="..\jit\JITThunks.cpp" /> >+ <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" /> > <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" /> > <ClCompile Include="..\jit\ThunkGenerators.cpp" /> > <ClCompile Include="..\llint\LLIntCLoop.cpp" /> >@@ -623,6 +625,7 @@ > <ClInclude Include="..\bytecode\CodeType.h" /> > <ClInclude Include="..\bytecode\Comment.h" /> > <ClInclude Include="..\bytecode\DataFormat.h" /> >+ <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" /> > <ClInclude Include="..\bytecode\EvalCodeCache.h" /> > <ClInclude Include="..\bytecode\ExecutionCounter.h" /> > <ClInclude Include="..\bytecode\ExitKind.h" /> >@@ -750,6 +753,7 @@ > <ClInclude Include="..\jit\JITStubsX86Common.h" /> > <ClInclude Include="..\jit\JITStubsX86_64.h" /> > <ClInclude Include="..\jit\JITThunks.h" /> >+ <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" /> > <ClInclude Include="..\jit\JITWriteBarrier.h" /> > <ClInclude Include="..\jit\JSInterfaceJIT.h" /> > <ClInclude Include="..\jit\JumpReplacementWatchpoint.h" /> >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 154718) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -86,8 +86,6 @@ > 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 */; }; >@@ -347,6 +345,10 @@ > 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, ); }; }; >@@ -1243,9 +1245,7 @@ > 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>"; }; >@@ -1514,6 +1514,10 @@ > 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>"; }; >@@ -2636,7 +2640,6 @@ > 0F0776BD14FF002800102332 /* JITCompilationEffort.h */, > 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */, > 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */, >- 0F21C26614BE5F5E00ADC64B /* JITDriver.h */, > 0F46807F14BA572700BFE272 /* JITExceptions.cpp */, > 0F46808014BA572700BFE272 /* JITExceptions.h */, > 86CC85A00EE79A4700288682 /* JITInlines.h */, >@@ -2658,6 +2661,8 @@ > A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */, > 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */, > 0F5EF91C16878F78003E5C25 /* JITThunks.h */, >+ 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */, >+ 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */, > A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */, > A76C51741182748D00715B05 /* JSInterfaceJIT.h */, > 0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */, >@@ -3040,7 +3045,6 @@ > A72701B30DADE94900E548D7 /* ExceptionHelpers.h */, > 86CA032D1038E8440028A609 /* Executable.cpp */, > 86CAFEE21035DDE60028A609 /* Executable.h */, >- 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */, > A7A8AF2917ADB5F3005AB174 /* Float32Array.h */, > A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */, > BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */, >@@ -3648,6 +3652,8 @@ > 0F8F943F1667632D00D61971 /* CodeType.cpp */, > 0F0B83A514BCF50400885B4F /* CodeType.h */, > 0F426A4A1460CD6B00131F8F /* DataFormat.h */, >+ 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */, >+ 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */, > 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */, > 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */, > 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */, >@@ -3796,6 +3802,7 @@ > 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 */, >@@ -3937,7 +3944,6 @@ > 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 */, >@@ -4026,7 +4032,6 @@ > 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 */, >@@ -4096,6 +4101,7 @@ > 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 */, >@@ -5009,6 +5015,7 @@ > 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 */, >@@ -5087,6 +5094,7 @@ > 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 */, >Index: Source/JavaScriptCore/bytecode/CodeBlock.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.cpp (revision 154718) >+++ Source/JavaScriptCore/bytecode/CodeBlock.cpp (working copy) >@@ -34,6 +34,7 @@ > #include "CallLinkStatus.h" > #include "DFGCapabilities.h" > #include "DFGCommon.h" >+#include "DFGDriver.h" > #include "DFGNode.h" > #include "DFGRepatch.h" > #include "DFGWorklist.h" >@@ -45,6 +46,7 @@ > #include "JSCJSValue.h" > #include "JSFunction.h" > #include "JSNameScope.h" >+#include "LLIntEntrypoints.h" > #include "LowLevelInterpreter.h" > #include "Operations.h" > #include "PolymorphicPutByIdList.h" >@@ -2689,6 +2691,60 @@ void CodeBlock::copyPostParseDataFromAlt > copyPostParseDataFrom(m_alternative.get()); > } > >+CompilationResult CodeBlock::prepareForExecution( >+ 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::install() >+{ >+ ownerExecutable()->installCode(this); >+} >+ >+PassRefPtr<CodeBlock> CodeBlock::newReplacement() >+{ >+ return ownerExecutable()->newReplacementCodeBlockFor(specializationKind()); >+} >+ > #if ENABLE(JIT) > void CodeBlock::reoptimize() > { >@@ -2715,53 +2771,6 @@ CodeBlock* FunctionCodeBlock::replacemen > return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall); > } > >-#if ENABLE(DFG_JIT) >-JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex) >-{ >- if (JITCode::isHigherTier(replacement()->jitType(), jitType())) { >- result = CompilationNotNeeded; >- return 0; >- } >- JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex); >- return error; >-} >- >-CompilationResult ProgramCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<ProgramExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan); >-} >- >-JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex) >-{ >- if (JITCode::isHigherTier(replacement()->jitType(), jitType())) { >- result = CompilationNotNeeded; >- return 0; >- } >- JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex); >- return error; >-} >- >-CompilationResult EvalCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<EvalExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan); >-} >- >-JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex) >-{ >- 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; >-} >- >-CompilationResult FunctionCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall); >-} >-#endif // ENABLE(DFG_JIT) >- > DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal() > { > return DFG::programCapabilityLevel(this); >@@ -2804,27 +2813,6 @@ void FunctionCodeBlock::jettisonImpl() > { > 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) >@@ -3106,10 +3094,8 @@ void CodeBlock::forceOptimizationSlowPat > void CodeBlock::setOptimizationThresholdBasedOnCompilationResult(CompilationResult result) > { > RELEASE_ASSERT(jitType() == JITCode::BaselineJIT); >- RELEASE_ASSERT((result == CompilationSuccessful) == (replacement() != this)); > switch (result) { > case CompilationSuccessful: >- RELEASE_ASSERT(JITCode::isOptimizingJIT(replacement()->jitType())); > optimizeNextInvocation(); > break; > case CompilationFailed: >Index: Source/JavaScriptCore/bytecode/CodeBlock.h >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.h (revision 154718) >+++ Source/JavaScriptCore/bytecode/CodeBlock.h (working copy) >@@ -48,6 +48,7 @@ > #include "DFGOSREntry.h" > #include "DFGOSRExit.h" > #include "DFGVariableEventStream.h" >+#include "DeferredCompilationCallback.h" > #include "EvalCodeCache.h" > #include "ExecutionCounter.h" > #include "ExpressionRangeInfo.h" >@@ -290,19 +291,19 @@ public: > { > 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); >- } >+ CompilationResult prepareForExecution( >+ ExecState*, JITCode::JITType, >+ JITCompilationEffort = JITCompilationMustSucceed, >+ unsigned bytecodeIndex = UINT_MAX, >+ PassRefPtr<DeferredCompilationCallback> = 0); >+ >+ // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock); >+ void install(); >+ >+ // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind()) >+ PassRefPtr<CodeBlock> newReplacement(); >+ > virtual CodeBlock* replacement() = 0; > > virtual DFG::CapabilityLevel capabilityLevelInternal() = 0; >@@ -969,7 +970,6 @@ public: > > protected: > #if ENABLE(JIT) >- virtual CompilationResult jitCompileImpl(ExecState*) = 0; > virtual void jettisonImpl() = 0; > #endif > virtual void visitWeakReferences(SlotVisitor&); >@@ -1194,13 +1194,7 @@ public: > > #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 >@@ -1223,13 +1217,7 @@ public: > > #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 >@@ -1252,13 +1240,7 @@ public: > > #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 >Index: Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp (working copy) >@@ -0,0 +1,35 @@ >+/* >+ * 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 >+ >Index: Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h >=================================================================== >--- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h (revision 0) >+++ Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h (working copy) >@@ -0,0 +1,47 @@ >+/* >+ * 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> { >+public: >+ DeferredCompilationCallback(); >+ virtual ~DeferredCompilationCallback(); >+ >+ virtual void compilationDidComplete(CodeBlock*, CompilationResult) = 0; >+}; >+ >+} // namespace JSC >+ >+#endif // DeferredCompilationCallback_h >+ >Index: Source/JavaScriptCore/dfg/DFGDriver.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDriver.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGDriver.cpp (working copy) >@@ -55,7 +55,7 @@ unsigned getNumCompilations() > return numCompilations; > } > >-static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex) >+CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback) > { > SamplingRegion samplingRegion("DFG Compilation (Driver)"); > >@@ -99,12 +99,12 @@ static CompilationResult compile(Compile > else > numVarsWithValues = 0; > RefPtr<Plan> plan = adoptRef( >- new Plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues)); >+ new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues)); > for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) { > int operand = plan->mustHandleValues.operandForIndex(i); > if (operandIsArgument(operand) > && !operandToArgument(operand) >- && compileMode == CompileFunction >+ && codeBlock->codeType() == FunctionCode > && 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, >@@ -115,7 +115,8 @@ static CompilationResult compile(Compile > plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue(); > } > >- if (enableConcurrentJIT()) { >+ if (enableConcurrentJIT() && callback) { >+ plan->callback = callback; > if (!vm.worklist) > vm.worklist = globalWorklist(); > if (logCompilationChanges()) >@@ -125,22 +126,7 @@ static CompilationResult compile(Compile > } > > plan->compileInThread(*vm.dfgState); >- 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); >+ return plan->finalizeWithoutNotifyingCallback(); > } > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGDriver.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDriver.h (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGDriver.h (working copy) >@@ -42,17 +42,9 @@ namespace DFG { > JS_EXPORT_PRIVATE unsigned getNumCompilations(); > > #if ENABLE(DFG_JIT) >-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); >+CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>); > #else >-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; >-} >+inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; } > #endif > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp (working copy) >@@ -39,12 +39,12 @@ FailedFinalizer::~FailedFinalizer() > { > } > >-bool FailedFinalizer::finalize(RefPtr<JSC::JITCode>&) >+bool FailedFinalizer::finalize() > { > return false; > } > >-bool FailedFinalizer::finalizeFunction(RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&) >+bool FailedFinalizer::finalizeFunction() > { > return false; > } >Index: Source/JavaScriptCore/dfg/DFGFailedFinalizer.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFailedFinalizer.h (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGFailedFinalizer.h (working copy) >@@ -39,8 +39,8 @@ public: > FailedFinalizer(Plan&); > virtual ~FailedFinalizer(); > >- bool finalize(RefPtr<JSC::JITCode>& entry); >- bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck); >+ bool finalize(); >+ bool finalizeFunction(); > }; > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGFinalizer.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFinalizer.h (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGFinalizer.h (working copy) >@@ -46,8 +46,8 @@ public: > Finalizer(Plan&); > virtual ~Finalizer(); > >- virtual bool finalize(RefPtr<JSC::JITCode>& entry) = 0; >- virtual bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) = 0; >+ virtual bool finalize() = 0; >+ virtual bool finalizeFunction() = 0; > > protected: > Plan& m_plan; >Index: Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (working copy) >@@ -28,6 +28,7 @@ > > #if ENABLE(DFG_JIT) > >+#include "CodeBlock.h" > #include "DFGCommon.h" > #include "DFGPlan.h" > >@@ -45,23 +46,23 @@ JITFinalizer::~JITFinalizer() > { > } > >-bool JITFinalizer::finalize(RefPtr<JSC::JITCode>& entry) >+bool JITFinalizer::finalize() > { > finalizeCommon(); > > m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); >- entry = m_jitCode; >+ m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr()); > > return true; > } > >-bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) >+bool JITFinalizer::finalizeFunction() > { > finalizeCommon(); > >- withArityCheck = m_linkBuffer->locationOf(m_arityCheck); >+ MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck); > m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); >- entry = m_jitCode; >+ m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck); > > return true; > } >Index: Source/JavaScriptCore/dfg/DFGJITFinalizer.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITFinalizer.h (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGJITFinalizer.h (working copy) >@@ -42,8 +42,8 @@ public: > JITFinalizer(Plan&, PassRefPtr<JITCode>, PassOwnPtr<LinkBuffer>, MacroAssembler::Label arityCheck = MacroAssembler::Label()); > virtual ~JITFinalizer(); > >- bool finalize(RefPtr<JSC::JITCode>& entry); >- bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck); >+ bool finalize(); >+ bool finalizeFunction(); > > private: > void finalizeCommon(); >Index: Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp (working copy) >@@ -30,19 +30,28 @@ > > #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); > >- codeBlock->jitCompile(exec); >+ 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(); > } > } > >Index: Source/JavaScriptCore/dfg/DFGOperations.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOperations.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGOperations.cpp (working copy) >@@ -1281,7 +1281,7 @@ inline char* linkFor(ExecState* execCall > codePtr = executable->generatedJITCodeFor(kind)->addressForCall(); > else { > FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); >- JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); >+ JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); > if (error) { > vm->exception = createStackOverflowError(exec); > return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); >@@ -1326,7 +1326,7 @@ inline char* virtualForWithFunction(Exec > ExecutableBase* executable = function->executable(); > if (UNLIKELY(!executable->hasJITCodeFor(kind))) { > FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); >- JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind); >+ JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind); > if (error) { > exec->vm().exception = error; > return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -80,10 +80,9 @@ static void dumpAndVerifyGraph(Graph& gr > } > > Plan::Plan( >- CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex, >+ PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex, > unsigned numVarsWithValues) >- : compileMode(compileMode) >- , vm(*passedCodeBlock->vm()) >+ : vm(*passedCodeBlock->vm()) > , codeBlock(passedCodeBlock) > , osrEntryBytecodeIndex(osrEntryBytecodeIndex) > , numVarsWithValues(numVarsWithValues) >@@ -208,7 +207,7 @@ Plan::CompilationPath Plan::compileInThr > > #if ENABLE(FTL_JIT) > if (Options::useExperimentalFTL() >- && compileMode == CompileFunction >+ && codeBlock->codeType() == FunctionCode > && FTL::canCompile(dfg)) { > > performCriticalEdgeBreaking(dfg); >@@ -255,12 +254,10 @@ Plan::CompilationPath Plan::compileInThr > dumpAndVerifyGraph(dfg, "Graph after optimization:"); > > JITCompiler dataFlowJIT(dfg); >- if (compileMode == CompileFunction) { >+ if (codeBlock->codeType() == FunctionCode) { > dataFlowJIT.compileFunction(); > dataFlowJIT.linkFunction(); > } else { >- ASSERT(compileMode == CompileOther); >- > dataFlowJIT.compile(); > dataFlowJIT.link(); > } >@@ -283,25 +280,30 @@ void Plan::reallyAdd(CommonData* commonD > writeBarriers.trigger(vm); > } > >-CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck) >+CompilationResult Plan::finalizeWithoutNotifyingCallback() > { > if (!isStillValid()) > return CompilationInvalidated; > > bool result; >- if (compileMode == CompileFunction) >- result = finalizer->finalizeFunction(jitCode, *jitCodeWithArityCheck); >+ if (codeBlock->codeType() == FunctionCode) >+ result = finalizer->finalizeFunction(); > else >- result = finalizer->finalize(jitCode); >+ result = finalizer->finalize(); > > if (!result) > return CompilationFailed; > >- reallyAdd(jitCode->dfgCommon()); >+ reallyAdd(codeBlock->jitCode()->dfgCommon()); > > return CompilationSuccessful; > } > >+void Plan::finalizeAndNotifyCallback() >+{ >+ callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback()); >+} >+ > CodeBlock* Plan::key() > { > return codeBlock->alternative(); >Index: Source/JavaScriptCore/dfg/DFGPlan.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.h (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGPlan.h (working copy) >@@ -36,6 +36,7 @@ > #include "DFGDesiredWeakReferences.h" > #include "DFGDesiredWriteBarriers.h" > #include "DFGFinalizer.h" >+#include "DeferredCompilationCallback.h" > #include "Operands.h" > #include "ProfilerCompilation.h" > #include <wtf/ThreadSafeRefCounted.h> >@@ -48,23 +49,20 @@ namespace DFG { > > class LongLivedState; > >-enum CompileMode { CompileFunction, CompileOther }; >- > #if ENABLE(DFG_JIT) > > struct Plan : public ThreadSafeRefCounted<Plan> { > Plan( >- CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock, >- unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues); >+ PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues); > ~Plan(); > > void compileInThread(LongLivedState&); > >- CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck); >+ CompilationResult finalizeWithoutNotifyingCallback(); >+ void finalizeAndNotifyCallback(); > > CodeBlock* key(); > >- const CompileMode compileMode; > VM& vm; > RefPtr<CodeBlock> codeBlock; > const unsigned osrEntryBytecodeIndex; >@@ -86,6 +84,8 @@ struct Plan : public ThreadSafeRefCounte > > bool isCompiled; > >+ RefPtr<DeferredCompilationCallback> callback; >+ > private: > enum CompilationPath { FailPath, DFGPath, FTLPath }; > CompilationPath compileInThreadImpl(LongLivedState&); >Index: Source/JavaScriptCore/dfg/DFGWorklist.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGWorklist.cpp (revision 154718) >+++ Source/JavaScriptCore/dfg/DFGWorklist.cpp (working copy) >@@ -165,10 +165,7 @@ Worklist::State Worklist::completeAllRea > > RELEASE_ASSERT(plan->isCompiled); > >- CompilationResult compilationResult = >- profiledBlock->replaceWithDeferredOptimizedCode(plan); >- RELEASE_ASSERT(compilationResult != CompilationDeferred); >- profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult); >+ plan->finalizeAndNotifyCallback(); > > if (profiledBlock == requestedProfiledBlock) > resultingState = Compiled; >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 154718) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -184,6 +184,8 @@ namespace JSC { > const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; } > > void addReference(JSCell*, ArrayBuffer*); >+ >+ bool isDeferred() const { return !!m_deferralDepth; } > > private: > friend class CodeBlock; >Index: Source/JavaScriptCore/interpreter/Interpreter.cpp >=================================================================== >--- Source/JavaScriptCore/interpreter/Interpreter.cpp (revision 154718) >+++ Source/JavaScriptCore/interpreter/Interpreter.cpp (working copy) >@@ -817,7 +817,7 @@ failedJSONP: > if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope)) > return checkedReturn(throwError(callFrame, error)); > >- if (JSObject* error = program->compile(callFrame, scope)) >+ if (JSObject* error = program->prepareForExecution(callFrame, scope, CodeForCall)) > return checkedReturn(throwError(callFrame, error)); > > ProgramCodeBlock* codeBlock = &program->generatedBytecode(); >@@ -886,7 +886,7 @@ JSValue Interpreter::executeCall(CallFra > > if (isJSCall) { > // Compile the callee: >- JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope); >+ JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall); > if (UNLIKELY(!!compileError)) { > return checkedReturn(throwError(callFrame, compileError)); > } >@@ -965,7 +965,7 @@ JSObject* Interpreter::executeConstruct( > > if (isJSConstruct) { > // Compile the callee: >- JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope); >+ JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct); > if (UNLIKELY(!!compileError)) { > return checkedReturn(throwError(callFrame, compileError)); > } >@@ -1039,7 +1039,7 @@ CallFrameClosure Interpreter::prepareFor > } > > // Compile the callee: >- JSObject* error = functionExecutable->compileForCall(callFrame, scope); >+ JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall); > if (error) { > throwError(callFrame, error); > return CallFrameClosure(); >@@ -1155,7 +1155,7 @@ JSValue Interpreter::execute(EvalExecuta > } > } > >- JSObject* compileError = eval->compile(callFrame, scope); >+ JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall); > if (UNLIKELY(!!compileError)) > return checkedReturn(throwError(callFrame, compileError)); > EvalCodeBlock* codeBlock = &eval->generatedBytecode(); >Index: Source/JavaScriptCore/jit/JITDriver.h >=================================================================== >--- Source/JavaScriptCore/jit/JITDriver.h (revision 154718) >+++ Source/JavaScriptCore/jit/JITDriver.h (working copy) >@@ -1,153 +0,0 @@ >-/* >- * 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 >- >Index: Source/JavaScriptCore/jit/JITStubs.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITStubs.cpp (revision 154718) >+++ Source/JavaScriptCore/jit/JITStubs.cpp (working copy) >@@ -50,6 +50,7 @@ > #include <wtf/InlineASM.h> > #include "JIT.h" > #include "JITExceptions.h" >+#include "JITToDFGDeferredCompilationCallback.h" > #include "JSActivation.h" > #include "JSArray.h" > #include "JSFunction.h" >@@ -1019,7 +1020,7 @@ DEFINE_STUB_FUNCTION(void, optimize) > 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 is there's an optimized replacement, >+ // cti_optimize from a loop. That's because if 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. > >@@ -1053,18 +1054,19 @@ DEFINE_STUB_FUNCTION(void, optimize) > if (Options::verboseOSR()) > dataLog("Triggering optimized compilation of ", *codeBlock, "\n"); > >- JSScope* scope = callFrame->scope(); >- CompilationResult result; >- JSObject* error = codeBlock->compileOptimized(callFrame, scope, result, bytecodeIndex); >- if (Options::verboseOSR()) { >+ RefPtr<DeferredCompilationCallback> callback = adoptRef( >+ new JITToDFGDeferredCompilationCallback()); >+ RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement(); >+ CompilationResult result = newCodeBlock->prepareForExecution( >+ callFrame, JITCode::DFGJIT, JITCompilationCanFail, bytecodeIndex, callback); >+ 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; >+ >+ newCodeBlock->install(); > } > > CodeBlock* optimizedCodeBlock = codeBlock->replacement(); >@@ -1189,7 +1191,7 @@ inline void* jitCompileFor(CallFrame* ca > ASSERT(!function->isHostFunction()); > FunctionExecutable* executable = function->jsExecutable(); > JSScope* callDataScopeChain = function->scope(); >- JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind); >+ JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind); > if (!error) > return function; > callFrame->vm().exception = error; >@@ -1288,7 +1290,7 @@ inline void* lazyLinkFor(CallFrame* call > codePtr = executable->generatedJITCodeFor(kind)->addressForCall(); > else { > FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); >- if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) { >+ if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) { > callFrame->vm().exception = error; > return 0; > } >@@ -1365,7 +1367,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkC > > FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable); > JSScope* scopeChain = callee->scope(); >- JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall); >+ JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall); > if (error) { > callFrame->vm().exception = error; > return 0; >Index: Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp (revision 0) >+++ Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp (working copy) >@@ -0,0 +1,49 @@ >+/* >+ * 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" >+ >+#include "CodeBlock.h" >+#include "Executable.h" >+ >+namespace JSC { >+ >+JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback() { } >+JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback() { } >+ >+void JITToDFGDeferredCompilationCallback::compilationDidComplete( >+ CodeBlock* codeBlock, CompilationResult result) >+{ >+ ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT); >+ >+ if (result == CompilationSuccessful) >+ codeBlock->install(); >+ >+ codeBlock->alternative()->setOptimizationThresholdBasedOnCompilationResult(result); >+} >+ >+} // JSC >+ >Index: Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h >=================================================================== >--- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h (revision 0) >+++ Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h (working copy) >@@ -0,0 +1,46 @@ >+/* >+ * 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 "DeferredCompilationCallback.h" >+ >+namespace JSC { >+ >+class ScriptExecutable; >+ >+class JITToDFGDeferredCompilationCallback : public DeferredCompilationCallback { >+public: >+ JITToDFGDeferredCompilationCallback(); >+ virtual ~JITToDFGDeferredCompilationCallback(); >+ >+ virtual void compilationDidComplete(CodeBlock*, CompilationResult); >+}; >+ >+} // namespace JSC >+ >+#endif // JITToDFGDeferredCompilationCallback_h >+ >Index: Source/JavaScriptCore/llint/LLIntEntrypoints.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntEntrypoints.cpp (revision 154718) >+++ Source/JavaScriptCore/llint/LLIntEntrypoints.cpp (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012 Apple Inc. All rights reserved. >+ * 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 >@@ -28,62 +28,77 @@ > > #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 getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck) >+void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock) > { >+ CodeSpecializationKind kind = codeBlock->specializationKind(); >+ > if (!vm.canUseJIT()) { > if (kind == CodeForCall) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)); >- arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check)); > return; > } > > ASSERT(kind == CodeForConstruct); >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)); >- arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check)); > return; > } > > #if ENABLE(JIT) > if (kind == CodeForCall) { >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)); >- arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code(); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)), >+ vm.getCTIStub(functionForCallArityCheckThunkGenerator).code()); > return; > } > > ASSERT(kind == CodeForConstruct); >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)); >- arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code(); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)), >+ vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code()); > #endif // ENABLE(JIT) > } > >-void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode) >+void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock) > { > if (!vm.canUseJIT()) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > return; > } >-#if ENABLE(JIT) >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)); >+#if ENABLE(JIT) >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > #endif > } > >-void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode) >+void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock) > { > if (!vm.canUseJIT()) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > return; > } > #if ENABLE(JIT) >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > #endif > } > >Index: Source/JavaScriptCore/llint/LLIntEntrypoints.h >=================================================================== >--- Source/JavaScriptCore/llint/LLIntEntrypoints.h (revision 154718) >+++ Source/JavaScriptCore/llint/LLIntEntrypoints.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012 Apple Inc. All rights reserved. >+ * 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 >@@ -37,6 +37,7 @@ > namespace JSC { > > class EvalCodeBlock; >+class FunctionCodeBlock; > class VM; > class MacroAssemblerCodePtr; > class MacroAssemblerCodeRef; >@@ -44,19 +45,9 @@ class ProgramCodeBlock; > > namespace LLInt { > >-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); >-} >+void setFunctionEntrypoint(VM&, FunctionCodeBlock*); >+void setEvalEntrypoint(VM&, EvalCodeBlock*); >+void setProgramEntrypoint(VM&, ProgramCodeBlock*); > > } } // namespace JSC::LLInt > >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (revision 154718) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (working copy) >@@ -37,7 +37,6 @@ > #include "HostCallReturnValue.h" > #include "Interpreter.h" > #include "JIT.h" >-#include "JITDriver.h" > #include "JSActivation.h" > #include "JSCJSValue.h" > #include "JSGlobalObjectFunctions.h" >@@ -280,6 +279,8 @@ inline bool shouldJIT(ExecState* exec) > // 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()) { >@@ -288,23 +289,33 @@ inline bool jitCompileAndSetHeuristics(C > return false; > } > >- CompilationResult result = codeBlock->jitCompile(exec); >- switch (result) { >- case CompilationNotNeeded: >+ switch (codeBlock->jitType()) { >+ case JITCode::BaselineJIT: { > if (Options::verboseOSR()) > dataLogF(" Code was already compiled.\n"); > codeBlock->jitSoon(); > return true; >- 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; >+ } >+ 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; >+ } >+ } > default: > RELEASE_ASSERT_NOT_REACHED(); > return false; >@@ -1004,7 +1015,7 @@ inline SlowPathReturnType setUpCall(Exec > codePtr = executable->hostCodeEntryFor(kind); > else { > FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); >- JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); >+ JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); > if (error) > LLINT_CALL_THROW(execCallee->callerFrame(), pc, error); > codeBlock = &functionExecutable->generatedBytecodeFor(kind); >Index: Source/JavaScriptCore/runtime/ArrayPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ArrayPrototype.cpp (revision 154718) >+++ Source/JavaScriptCore/runtime/ArrayPrototype.cpp (working copy) >@@ -78,7 +78,7 @@ static inline bool isNumericCompareFunct > > FunctionExecutable* executable = callData.js.functionExecutable; > >- JSObject* error = executable->compileForCall(exec, callData.js.scope); >+ JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall); > if (error) > return false; > >Index: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (revision 154718) >+++ Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (working copy) >@@ -37,7 +37,6 @@ > #include "HostCallReturnValue.h" > #include "Interpreter.h" > #include "JIT.h" >-#include "JITDriver.h" > #include "JITStubs.h" > #include "JSActivation.h" > #include "JSCJSValue.h" >Index: Source/JavaScriptCore/runtime/CompilationResult.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/CompilationResult.cpp (revision 154718) >+++ Source/JavaScriptCore/runtime/CompilationResult.cpp (working copy) >@@ -42,9 +42,6 @@ void printInternal(PrintStream& out, Com > case CompilationSuccessful: > out.print("CompilationSuccessful"); > return; >- case CompilationNotNeeded: >- out.print("CompilationNotNeeded"); >- return; > case CompilationDeferred: > out.print("CompilationDeferred"); > return; >Index: Source/JavaScriptCore/runtime/CompilationResult.h >=================================================================== >--- Source/JavaScriptCore/runtime/CompilationResult.h (revision 154718) >+++ Source/JavaScriptCore/runtime/CompilationResult.h (working copy) >@@ -30,7 +30,32 @@ > > namespace JSC { > >-enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred }; >+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. >+ CompilationDeferred >+}; > > } // namespace JSC > >Index: Source/JavaScriptCore/runtime/Executable.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/Executable.cpp (revision 154718) >+++ Source/JavaScriptCore/runtime/Executable.cpp (working copy) >@@ -30,9 +30,7 @@ > #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> >@@ -114,6 +112,188 @@ void ScriptExecutable::destroy(JSCell* c > } > #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 = 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) >@@ -176,28 +356,6 @@ void FunctionExecutable::destroy(JSCell* > 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) { >@@ -215,39 +373,6 @@ inline const char* samplingDescription(J > } > } > >-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) > { >@@ -298,60 +423,6 @@ JSObject* ProgramExecutable::checkSyntax > 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) > { >@@ -444,141 +515,6 @@ FunctionCodeBlock* FunctionExecutable::b > 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 = 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) > { >Index: Source/JavaScriptCore/runtime/Executable.h >=================================================================== >--- Source/JavaScriptCore/runtime/Executable.h (revision 154718) >+++ Source/JavaScriptCore/runtime/Executable.h (working copy) >@@ -244,6 +244,7 @@ public: > return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter); > #endif > } >+ > #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP) > > protected: >@@ -402,6 +403,20 @@ public: > 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) > { >@@ -430,24 +445,8 @@ public: > > 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() >@@ -481,10 +480,10 @@ public: > 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; >@@ -508,24 +507,8 @@ public: > > 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() >@@ -557,11 +540,12 @@ public: > 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; >@@ -600,26 +584,8 @@ public: > 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 >@@ -633,24 +599,8 @@ public: > 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 >@@ -664,39 +614,6 @@ public: > 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) > { >@@ -707,14 +624,6 @@ public: > 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) >@@ -764,9 +673,6 @@ public: > 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) >@@ -786,6 +692,8 @@ private: > return false; > } > >+ friend class ScriptExecutable; >+ > static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; > WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable; > RefPtr<FunctionCodeBlock> m_codeBlockForCall; >Index: Source/JavaScriptCore/runtime/ExecutionHarness.h >=================================================================== >--- Source/JavaScriptCore/runtime/ExecutionHarness.h (revision 154718) >+++ Source/JavaScriptCore/runtime/ExecutionHarness.h (working copy) >@@ -1,167 +0,0 @@ >-/* >- * 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 >-
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 120326
:
209681
|
209794
|
209797
|
209834
|
209837
|
209845
|
209846