Changeset 154804 in webkit
- Timestamp:
- Aug 28, 2013 9:03:05 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 added
- 2 deleted
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r154629 r154804 54 54 bytecode/CodeType.cpp 55 55 bytecode/DFGExitProfile.cpp 56 bytecode/DeferredCompilationCallback.cpp 56 57 bytecode/ExecutionCounter.cpp 57 58 bytecode/ExitKind.cpp … … 244 245 jit/JITStubs.cpp 245 246 jit/JITThunks.cpp 247 jit/JITToDFGDeferredCompilationCallback.cpp 246 248 jit/JumpReplacementWatchpoint.cpp 247 249 jit/ThunkGenerators.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r154797 r154804 1 2013-08-28 Filip Pizlo <fpizlo@apple.com> 2 3 CodeBlock compilation and installation should be simplified and rationalized 4 https://bugs.webkit.org/show_bug.cgi?id=120326 5 6 Reviewed by Oliver Hunt. 7 8 Previously Executable owned the code for generating JIT code; you always had 9 to go through Executable. But often you also had to go through CodeBlock, 10 because ScriptExecutable couldn't have virtual methods, but CodeBlock could. 11 So you'd ask CodeBlock to do something, which would dispatch through a 12 virtual method that would select the appropriate Executable subtype's method. 13 This all meant that the same code would often be duplicated, because most of 14 the work needed to compile something was identical regardless of code type. 15 But then we tried to fix this, by having templatized helpers in 16 ExecutionHarness.h and JITDriver.h. The result was that if you wanted to find 17 out what happened when you asked for something to be compiled, you'd go on a 18 wild ride that started with CodeBlock, touched upon Executable, and then 19 ricocheted into either ExecutionHarness or JITDriver (likely both). 20 21 Another awkwardness was that for concurrent compiles, the DFG::Worklist had 22 super-special inside knowledge of what JITStubs.cpp's cti_optimize would have 23 done once the compilation finished. 24 25 Also, most of the DFG JIT drivers assumed that they couldn't install the 26 JITCode into the CodeBlock directly - instead they would return it via a 27 reference, which happened to be a reference to the JITCode pointer in 28 Executable. This was super weird. 29 30 Finally, there was no notion of compiling code into a special CodeBlock that 31 wasn't used for handling calls into an Executable. I'd like this for FTL OSR 32 entry. 33 34 This patch solves these problems by reducing all of that complexity into just 35 three primitives: 36 37 - Executable::newCodeBlock(). This gives you a new code block, either for call 38 or for construct, and either to serve as the baseline code or the optimized 39 code. The new code block is then owned by the caller; Executable doesn't 40 register it anywhere. The new code block has no JITCode and isn't callable, 41 but it has all of the bytecode. 42 43 - CodeBlock::prepareForExecution(). This takes the CodeBlock's bytecode and 44 produces a JITCode, and then installs the JITCode into the CodeBlock. This 45 method takes a JITType, and always compiles with that JIT. If you ask for 46 JITCode::InterpreterThunk then you'll get JITCode that just points to the 47 LLInt entrypoints. Once this returns, it is possible to call into the 48 CodeBlock if you do so manually - but the Executable still won't know about 49 it so JS calls to that Executable will still be routed to whatever CodeBlock 50 is associated with the Executable. 51 52 - Executable::installCode(). This takes a CodeBlock and makes it the code-for- 53 entry for that Executable. This involves unlinking the Executable's last 54 CodeBlock, if there was one. This also tells the GC about any effect on 55 memory usage and does a bunch of weird data structure rewiring, since 56 Executable caches some of CodeBlock's fields for the benefit of virtual call 57 fast paths. 58 59 This functionality is then wrapped around three convenience methods: 60 61 - Executable::prepareForExecution(). If there is no code block for that 62 Executable, then one is created (newCodeBlock()), compiled 63 (CodeBlock::prepareForExecution()) and installed (installCode()). 64 65 - CodeBlock::newReplacement(). Asks the Executable for a new CodeBlock that 66 can serve as an optimized replacement of the current one. 67 68 - CodeBlock::install(). Asks the Executable to install this code block. 69 70 This patch allows me to kill *a lot* of code and to remove a lot of 71 specializations for functions vs. not-functions, and a lot of places where we 72 pass around JITCode references and such. ExecutionHarness and JITDriver are 73 both gone. Overall this patch has more red than green. 74 75 It also allows me to work on FTL OSR entry and tier-up: 76 77 - FTL tier-up: this will involve DFGOperations.cpp asking the DFG::Worklist 78 to do some compilation, but it will require the DFG::Worklist to do 79 something different than what JITStubs.cpp would want, once the compilation 80 finishes. This patch introduces a callback mechanism for that purpose. 81 82 - FTL OSR entry: this will involve creating a special auto-jettisoned 83 CodeBlock that is used only for FTL OSR entry. The new set of primitives 84 allows for this: Executable can vend you a fresh new CodeBlock, and you can 85 ask that CodeBlock to compile itself with any JIT of your choosing. Or you 86 can take that CodeBlock and compile it yourself. Previously the act of 87 producing a CodeBlock-for-optimization and the act of compiling code for it 88 were tightly coupled; now you can separate them and you can create such 89 auto-jettisoned CodeBlocks that are used for a one-shot OSR entry. 90 91 * CMakeLists.txt: 92 * GNUmakefile.list.am: 93 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 94 * JavaScriptCore.xcodeproj/project.pbxproj: 95 * Target.pri: 96 * bytecode/CodeBlock.cpp: 97 (JSC::CodeBlock::prepareForExecution): 98 (JSC::CodeBlock::install): 99 (JSC::CodeBlock::newReplacement): 100 (JSC::FunctionCodeBlock::jettisonImpl): 101 (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult): 102 * bytecode/CodeBlock.h: 103 (JSC::CodeBlock::hasBaselineJITProfiling): 104 * bytecode/DeferredCompilationCallback.cpp: Added. 105 (JSC::DeferredCompilationCallback::DeferredCompilationCallback): 106 (JSC::DeferredCompilationCallback::~DeferredCompilationCallback): 107 * bytecode/DeferredCompilationCallback.h: Added. 108 * dfg/DFGDriver.cpp: 109 (JSC::DFG::tryCompile): 110 * dfg/DFGDriver.h: 111 (JSC::DFG::tryCompile): 112 * dfg/DFGFailedFinalizer.cpp: 113 (JSC::DFG::FailedFinalizer::finalize): 114 (JSC::DFG::FailedFinalizer::finalizeFunction): 115 * dfg/DFGFailedFinalizer.h: 116 * dfg/DFGFinalizer.h: 117 * dfg/DFGJITFinalizer.cpp: 118 (JSC::DFG::JITFinalizer::finalize): 119 (JSC::DFG::JITFinalizer::finalizeFunction): 120 * dfg/DFGJITFinalizer.h: 121 * dfg/DFGOSRExitPreparation.cpp: 122 (JSC::DFG::prepareCodeOriginForOSRExit): 123 * dfg/DFGOperations.cpp: 124 * dfg/DFGPlan.cpp: 125 (JSC::DFG::Plan::Plan): 126 (JSC::DFG::Plan::compileInThreadImpl): 127 (JSC::DFG::Plan::finalizeWithoutNotifyingCallback): 128 (JSC::DFG::Plan::finalizeAndNotifyCallback): 129 * dfg/DFGPlan.h: 130 * dfg/DFGWorklist.cpp: 131 (JSC::DFG::Worklist::completeAllReadyPlansForVM): 132 * ftl/FTLJITFinalizer.cpp: 133 (JSC::FTL::JITFinalizer::finalize): 134 (JSC::FTL::JITFinalizer::finalizeFunction): 135 * ftl/FTLJITFinalizer.h: 136 * heap/Heap.h: 137 (JSC::Heap::isDeferred): 138 * interpreter/Interpreter.cpp: 139 (JSC::Interpreter::execute): 140 (JSC::Interpreter::executeCall): 141 (JSC::Interpreter::executeConstruct): 142 (JSC::Interpreter::prepareForRepeatCall): 143 * jit/JITDriver.h: Removed. 144 * jit/JITStubs.cpp: 145 (JSC::DEFINE_STUB_FUNCTION): 146 (JSC::jitCompileFor): 147 (JSC::lazyLinkFor): 148 * jit/JITToDFGDeferredCompilationCallback.cpp: Added. 149 (JSC::JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback): 150 (JSC::JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback): 151 (JSC::JITToDFGDeferredCompilationCallback::create): 152 (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete): 153 * jit/JITToDFGDeferredCompilationCallback.h: Added. 154 * llint/LLIntEntrypoints.cpp: 155 (JSC::LLInt::setFunctionEntrypoint): 156 (JSC::LLInt::setEvalEntrypoint): 157 (JSC::LLInt::setProgramEntrypoint): 158 * llint/LLIntEntrypoints.h: 159 * llint/LLIntSlowPaths.cpp: 160 (JSC::LLInt::jitCompileAndSetHeuristics): 161 (JSC::LLInt::setUpCall): 162 * runtime/ArrayPrototype.cpp: 163 (JSC::isNumericCompareFunction): 164 * runtime/CommonSlowPaths.cpp: 165 * runtime/CompilationResult.cpp: 166 (WTF::printInternal): 167 * runtime/CompilationResult.h: 168 * runtime/Executable.cpp: 169 (JSC::ScriptExecutable::installCode): 170 (JSC::ScriptExecutable::newCodeBlockFor): 171 (JSC::ScriptExecutable::newReplacementCodeBlockFor): 172 (JSC::ScriptExecutable::prepareForExecutionImpl): 173 * runtime/Executable.h: 174 (JSC::ScriptExecutable::prepareForExecution): 175 (JSC::FunctionExecutable::jettisonOptimizedCodeFor): 176 * runtime/ExecutionHarness.h: Removed. 177 1 178 2013-08-28 Chris Curtis <chris_curtis@apple.com> 2 179 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r154747 r154804 114 114 Source/JavaScriptCore/bytecode/CodeOrigin.cpp \ 115 115 Source/JavaScriptCore/bytecode/CodeOrigin.h \ 116 Source/JavaScriptCore/bytecode/DataFormat.h \117 116 Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \ 118 117 Source/JavaScriptCore/bytecode/DFGExitProfile.h \ 118 Source/JavaScriptCore/bytecode/DataFormat.h \ 119 Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp \ 120 Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h \ 119 121 Source/JavaScriptCore/bytecode/EvalCodeCache.h \ 120 122 Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \ … … 605 607 Source/JavaScriptCore/jit/JITDisassembler.cpp \ 606 608 Source/JavaScriptCore/jit/JITDisassembler.h \ 607 Source/JavaScriptCore/jit/JITDriver.h \608 609 Source/JavaScriptCore/jit/JIT.cpp \ 609 610 Source/JavaScriptCore/jit/JIT.h \ … … 629 630 Source/JavaScriptCore/jit/JITThunks.cpp \ 630 631 Source/JavaScriptCore/jit/JITThunks.h \ 632 Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp \ 633 Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h \ 631 634 Source/JavaScriptCore/jit/JITWriteBarrier.h \ 632 635 Source/JavaScriptCore/jit/JSInterfaceJIT.h \ … … 784 787 Source/JavaScriptCore/runtime/Executable.cpp \ 785 788 Source/JavaScriptCore/runtime/Executable.h \ 786 Source/JavaScriptCore/runtime/ExecutionHarness.h \787 789 Source/JavaScriptCore/runtime/Float32Array.h \ 788 790 Source/JavaScriptCore/runtime/Float64Array.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r154638 r154804 303 303 <ClCompile Include="..\bytecode\CodeOrigin.cpp" /> 304 304 <ClCompile Include="..\bytecode\CodeType.cpp" /> 305 <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" /> 305 306 <ClCompile Include="..\bytecode\ExecutionCounter.cpp" /> 306 307 <ClCompile Include="..\bytecode\ExitKind.cpp" /> … … 378 379 <ClCompile Include="..\jit\JITStubs.cpp" /> 379 380 <ClCompile Include="..\jit\JITThunks.cpp" /> 381 <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" /> 380 382 <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" /> 381 383 <ClCompile Include="..\jit\ThunkGenerators.cpp" /> … … 624 626 <ClInclude Include="..\bytecode\Comment.h" /> 625 627 <ClInclude Include="..\bytecode\DataFormat.h" /> 628 <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" /> 626 629 <ClInclude Include="..\bytecode\EvalCodeCache.h" /> 627 630 <ClInclude Include="..\bytecode\ExecutionCounter.h" /> … … 741 744 <ClInclude Include="..\jit\JITCompilationEffort.h" /> 742 745 <ClInclude Include="..\jit\JITDisassembler.h" /> 743 <ClInclude Include="..\jit\JITDriver.h" />744 746 <ClInclude Include="..\jit\JITExceptions.h" /> 745 747 <ClInclude Include="..\jit\JITInlines.h" /> … … 751 753 <ClInclude Include="..\jit\JITStubsX86_64.h" /> 752 754 <ClInclude Include="..\jit\JITThunks.h" /> 755 <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" /> 753 756 <ClInclude Include="..\jit\JITWriteBarrier.h" /> 754 757 <ClInclude Include="..\jit\JSInterfaceJIT.h" /> … … 838 841 <ClInclude Include="..\runtime\ExceptionHelpers.h" /> 839 842 <ClInclude Include="..\runtime\Executable.h" /> 840 <ClInclude Include="..\runtime\ExecutionHarness.h" />841 843 <ClInclude Include="..\runtime\Float32Array.h" /> 842 844 <ClInclude Include="..\runtime\Float64Array.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r154629 r154804 87 87 0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; }; 88 88 0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */; settings = {ATTRIBUTES = (Private, ); }; }; 89 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };90 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };91 89 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; }; 92 90 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 348 346 0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; }; 349 347 0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; }; 348 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; }; 349 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; }; 350 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; }; 351 0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; }; 350 352 0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; 351 353 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; }; … … 1244 1246 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; }; 1245 1247 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSilentRegisterSavePlan.h; path = dfg/DFGSilentRegisterSavePlan.h; sourceTree = "<group>"; }; 1246 0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };1247 1248 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; }; 1248 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };1249 1249 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; }; 1250 1250 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; }; … … 1515 1515 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; }; 1516 1516 0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; }; 1517 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; }; 1518 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; }; 1519 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; }; 1520 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JITToDFGDeferredCompilationCallback.h; sourceTree = "<group>"; }; 1517 1521 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; }; 1518 1522 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; }; … … 2637 2641 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */, 2638 2642 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */, 2639 0F21C26614BE5F5E00ADC64B /* JITDriver.h */,2640 2643 0F46807F14BA572700BFE272 /* JITExceptions.cpp */, 2641 2644 0F46808014BA572700BFE272 /* JITExceptions.h */, … … 2659 2662 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */, 2660 2663 0F5EF91C16878F78003E5C25 /* JITThunks.h */, 2664 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */, 2665 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */, 2661 2666 A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */, 2662 2667 A76C51741182748D00715B05 /* JSInterfaceJIT.h */, … … 3041 3046 86CA032D1038E8440028A609 /* Executable.cpp */, 3042 3047 86CAFEE21035DDE60028A609 /* Executable.h */, 3043 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,3044 3048 A7A8AF2917ADB5F3005AB174 /* Float32Array.h */, 3045 3049 A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */, … … 3649 3653 0F0B83A514BCF50400885B4F /* CodeType.h */, 3650 3654 0F426A4A1460CD6B00131F8F /* DataFormat.h */, 3655 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */, 3656 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */, 3651 3657 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */, 3652 3658 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */, … … 3797 3803 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */, 3798 3804 0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */, 3805 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */, 3799 3806 BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */, 3800 3807 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */, … … 3938 3945 A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */, 3939 3946 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */, 3940 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,3941 3947 0FB105861675481200F8AB6E /* ExitKind.h in Headers */, 3942 3948 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */, … … 4027 4033 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */, 4028 4034 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */, 4029 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,4030 4035 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */, 4031 4036 86CC85A10EE79A4700288682 /* JITInlines.h in Headers */, … … 4097 4102 BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */, 4098 4103 A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */, 4104 0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */, 4099 4105 A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */, 4100 4106 BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */, … … 5010 5016 148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */, 5011 5017 93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */, 5018 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */, 5012 5019 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */, 5013 5020 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */, … … 5088 5095 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */, 5089 5096 14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */, 5097 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */, 5090 5098 0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */, 5091 5099 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */, -
trunk/Source/JavaScriptCore/Target.pri
r154629 r154804 62 62 bytecode/CodeType.cpp \ 63 63 bytecode/DFGExitProfile.cpp \ 64 bytecode/DeferredCompilationCallback.cpp \ 64 65 bytecode/ExecutionCounter.cpp \ 65 66 bytecode/ExitKind.cpp \ … … 222 223 jit/JITStubs.cpp \ 223 224 jit/JITThunks.cpp \ 225 jit/JITToDFGDeferredCompilationCallback.cpp \ 224 226 jit/JumpReplacementWatchpoint.cpp \ 225 227 jit/ThunkGenerators.cpp \ -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r154162 r154804 35 35 #include "DFGCapabilities.h" 36 36 #include "DFGCommon.h" 37 #include "DFGDriver.h" 37 38 #include "DFGNode.h" 38 39 #include "DFGRepatch.h" … … 46 47 #include "JSFunction.h" 47 48 #include "JSNameScope.h" 49 #include "LLIntEntrypoints.h" 48 50 #include "LowLevelInterpreter.h" 49 51 #include "Operations.h" … … 2537 2539 m_incomingCalls.push(incoming); 2538 2540 } 2541 #endif // ENABLE(JIT) 2539 2542 2540 2543 void CodeBlock::unlinkIncomingCalls() … … 2543 2546 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) 2544 2547 m_incomingLLIntCalls.begin()->unlink(); 2545 #endif 2548 #endif // ENABLE(LLINT) 2549 #if ENABLE(JIT) 2546 2550 if (m_incomingCalls.isEmpty()) 2547 2551 return; … … 2549 2553 while (m_incomingCalls.begin() != m_incomingCalls.end()) 2550 2554 m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer); 2551 }2552 2555 #endif // ENABLE(JIT) 2556 } 2553 2557 2554 2558 #if ENABLE(LLINT) … … 2690 2694 } 2691 2695 2696 CompilationResult CodeBlock::prepareForExecutionImpl( 2697 ExecState* exec, JITCode::JITType jitType, JITCompilationEffort effort, 2698 unsigned bytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback) 2699 { 2700 VM& vm = exec->vm(); 2701 2702 if (jitType == JITCode::InterpreterThunk) { 2703 switch (codeType()) { 2704 case GlobalCode: 2705 LLInt::setProgramEntrypoint(vm, static_cast<ProgramCodeBlock*>(this)); 2706 break; 2707 case EvalCode: 2708 LLInt::setEvalEntrypoint(vm, static_cast<EvalCodeBlock*>(this)); 2709 break; 2710 case FunctionCode: 2711 LLInt::setFunctionEntrypoint(vm, static_cast<FunctionCodeBlock*>(this)); 2712 break; 2713 } 2714 return CompilationSuccessful; 2715 } 2716 2717 #if ENABLE(JIT) 2718 if (JITCode::isOptimizingJIT(jitType)) { 2719 ASSERT(effort == JITCompilationCanFail); 2720 bool hadCallback = !!callback; 2721 CompilationResult result = DFG::tryCompile(exec, this, bytecodeIndex, callback); 2722 ASSERT_UNUSED(hadCallback, result != CompilationDeferred || hadCallback); 2723 return result; 2724 } 2725 2726 MacroAssemblerCodePtr jitCodeWithArityCheck; 2727 RefPtr<JITCode> jitCode = JIT::compile(&vm, this, effort, &jitCodeWithArityCheck); 2728 if (!jitCode) 2729 return CompilationFailed; 2730 setJITCode(jitCode, jitCodeWithArityCheck); 2731 return CompilationSuccessful; 2732 #else 2733 UNUSED_PARAM(effort); 2734 UNUSED_PARAM(bytecodeIndex); 2735 UNUSED_PARAM(callback); 2736 return CompilationFailed; 2737 #endif // ENABLE(JIT) 2738 } 2739 2740 CompilationResult CodeBlock::prepareForExecution( 2741 ExecState* exec, JITCode::JITType jitType, 2742 JITCompilationEffort effort, unsigned bytecodeIndex) 2743 { 2744 CompilationResult result = 2745 prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, 0); 2746 ASSERT(result != CompilationDeferred); 2747 return result; 2748 } 2749 2750 CompilationResult CodeBlock::prepareForExecutionAsynchronously( 2751 ExecState* exec, JITCode::JITType jitType, 2752 PassRefPtr<DeferredCompilationCallback> passedCallback, 2753 JITCompilationEffort effort, unsigned bytecodeIndex) 2754 { 2755 RefPtr<DeferredCompilationCallback> callback = passedCallback; 2756 CompilationResult result = 2757 prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, callback); 2758 if (result != CompilationDeferred) 2759 callback->compilationDidComplete(this, result); 2760 return result; 2761 } 2762 2763 void CodeBlock::install() 2764 { 2765 ownerExecutable()->installCode(this); 2766 } 2767 2768 PassRefPtr<CodeBlock> CodeBlock::newReplacement() 2769 { 2770 return ownerExecutable()->newReplacementCodeBlockFor(specializationKind()); 2771 } 2772 2692 2773 #if ENABLE(JIT) 2693 2774 void CodeBlock::reoptimize() … … 2715 2796 return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall); 2716 2797 } 2717 2718 #if ENABLE(DFG_JIT)2719 JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)2720 {2721 if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {2722 result = CompilationNotNeeded;2723 return 0;2724 }2725 JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);2726 return error;2727 }2728 2729 CompilationResult ProgramCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)2730 {2731 return static_cast<ProgramExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);2732 }2733 2734 JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)2735 {2736 if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {2737 result = CompilationNotNeeded;2738 return 0;2739 }2740 JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);2741 return error;2742 }2743 2744 CompilationResult EvalCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)2745 {2746 return static_cast<EvalExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);2747 }2748 2749 JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)2750 {2751 if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {2752 result = CompilationNotNeeded;2753 return 0;2754 }2755 JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, result, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall);2756 return error;2757 }2758 2759 CompilationResult FunctionCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)2760 {2761 return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall);2762 }2763 #endif // ENABLE(DFG_JIT)2764 2798 2765 2799 DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal() … … 2804 2838 { 2805 2839 static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall); 2806 }2807 2808 CompilationResult ProgramCodeBlock::jitCompileImpl(ExecState* exec)2809 {2810 ASSERT(jitType() == JITCode::InterpreterThunk);2811 ASSERT(this == replacement());2812 return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);2813 }2814 2815 CompilationResult EvalCodeBlock::jitCompileImpl(ExecState* exec)2816 {2817 ASSERT(jitType() == JITCode::InterpreterThunk);2818 ASSERT(this == replacement());2819 return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);2820 }2821 2822 CompilationResult FunctionCodeBlock::jitCompileImpl(ExecState* exec)2823 {2824 ASSERT(jitType() == JITCode::InterpreterThunk);2825 ASSERT(this == replacement());2826 return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall);2827 2840 } 2828 2841 #endif -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r154245 r154804 49 49 #include "DFGOSRExit.h" 50 50 #include "DFGVariableEventStream.h" 51 #include "DeferredCompilationCallback.h" 51 52 #include "EvalCodeCache.h" 52 53 #include "ExecutionCounter.h" … … 203 204 unsigned bytecodeOffset(ExecState*, ReturnAddressPtr); 204 205 206 void unlinkIncomingCalls(); 207 205 208 #if ENABLE(JIT) 206 209 unsigned bytecodeOffsetForCallAtIndex(unsigned index) … … 232 235 #endif // ENABLE(LLINT) 233 236 234 void unlinkIncomingCalls();235 236 237 #if ENABLE(DFG_JIT) || ENABLE(LLINT) 237 238 void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap) … … 265 266 int argumentIndexAfterCapture(size_t argument); 266 267 267 #if ENABLE(JIT) 268 // Prepares this code block for execution. This is synchronous. This compile 269 // may fail, if you passed JITCompilationCanFail. 270 CompilationResult prepareForExecution( 271 ExecState*, JITCode::JITType, 272 JITCompilationEffort = JITCompilationMustSucceed, 273 unsigned bytecodeIndex = UINT_MAX); 274 275 // Use this method for asynchronous compiles. This will do a compile at some 276 // point in time between when you called into this method and some point in the 277 // future. If you're lucky then it might complete before this method returns. 278 // Once it completes, the callback is called with the result. If the compile 279 // did happen to complete before the method returns, the result of the compile 280 // may be returned. If the compile didn't happen to complete yet, or if we 281 // didn't happen to notice that the compile already completed, we return 282 // CompilationDeferred. 283 // 284 // Note that asynchronous compiles don't actually complete unless you call into 285 // DFG::Worklist::completeAllReadyPlansForVM(). You usually force a call to 286 // this on the main thread by listening to the callback's 287 // compilationDidBecomeReadyAsynchronously() notification. Note that this call 288 // happens on another thread. 289 CompilationResult prepareForExecutionAsynchronously( 290 ExecState*, JITCode::JITType, PassRefPtr<DeferredCompilationCallback>, 291 JITCompilationEffort = JITCompilationMustSucceed, 292 unsigned bytecodeIndex = UINT_MAX); 293 294 // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock); 295 void install(); 296 297 // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind()) 298 PassRefPtr<CodeBlock> newReplacement(); 299 268 300 void setJITCode(PassRefPtr<JITCode> code, MacroAssemblerCodePtr codeWithArityCheck) 269 301 { … … 287 319 return result; 288 320 } 321 322 #if ENABLE(JIT) 289 323 bool hasBaselineJITProfiling() const 290 324 { 291 325 return jitType() == JITCode::BaselineJIT; 292 326 } 293 #if ENABLE(DFG_JIT)294 virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0;295 virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0;296 #endif // ENABLE(DFG_JIT)297 327 void jettison(); 298 CompilationResult jitCompile(ExecState* exec) 299 { 300 if (jitType() != JITCode::InterpreterThunk) { 301 ASSERT(jitType() == JITCode::BaselineJIT); 302 return CompilationNotNeeded; 303 } 304 return jitCompileImpl(exec); 305 } 328 306 329 virtual CodeBlock* replacement() = 0; 307 330 … … 316 339 317 340 bool hasOptimizedReplacement(); 318 #else319 JITCode::JITType jitType() const { return JITCode::InterpreterThunk; }320 341 #endif 321 342 … … 970 991 protected: 971 992 #if ENABLE(JIT) 972 virtual CompilationResult jitCompileImpl(ExecState*) = 0;973 993 virtual void jettisonImpl() = 0; 974 994 #endif … … 984 1004 private: 985 1005 friend class DFGCodeBlocks; 1006 1007 CompilationResult prepareForExecutionImpl( 1008 ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex, 1009 PassRefPtr<DeferredCompilationCallback>); 986 1010 987 1011 void noticeIncomingCall(ExecState* callerFrame); … … 1086 1110 SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls; 1087 1111 #endif 1112 RefPtr<JITCode> m_jitCode; 1113 MacroAssemblerCodePtr m_jitCodeWithArityCheck; 1088 1114 #if ENABLE(JIT) 1089 1115 Vector<StructureStubInfo> m_structureStubInfos; 1090 1116 Vector<ByValInfo> m_byValInfos; 1091 1117 Vector<CallLinkInfo> m_callLinkInfos; 1092 RefPtr<JITCode> m_jitCode;1093 MacroAssemblerCodePtr m_jitCodeWithArityCheck;1094 1118 SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls; 1095 1119 #endif … … 1195 1219 #if ENABLE(JIT) 1196 1220 protected: 1197 #if ENABLE(DFG_JIT)1198 virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);1199 virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);1200 #endif // ENABLE(DFG_JIT)1201 1202 1221 virtual void jettisonImpl(); 1203 virtual CompilationResult jitCompileImpl(ExecState*);1204 1222 virtual CodeBlock* replacement(); 1205 1223 virtual DFG::CapabilityLevel capabilityLevelInternal(); … … 1224 1242 #if ENABLE(JIT) 1225 1243 protected: 1226 #if ENABLE(DFG_JIT)1227 virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);1228 virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);1229 #endif // ENABLE(DFG_JIT)1230 1231 1244 virtual void jettisonImpl(); 1232 virtual CompilationResult jitCompileImpl(ExecState*);1233 1245 virtual CodeBlock* replacement(); 1234 1246 virtual DFG::CapabilityLevel capabilityLevelInternal(); … … 1253 1265 #if ENABLE(JIT) 1254 1266 protected: 1255 #if ENABLE(DFG_JIT)1256 virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);1257 virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);1258 #endif // ENABLE(DFG_JIT)1259 1260 1267 virtual void jettisonImpl(); 1261 virtual CompilationResult jitCompileImpl(ExecState*);1262 1268 virtual CodeBlock* replacement(); 1263 1269 virtual DFG::CapabilityLevel capabilityLevelInternal(); -
trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp
r153778 r154804 56 56 } 57 57 58 static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)58 CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback) 59 59 { 60 60 SamplingRegion samplingRegion("DFG Compilation (Driver)"); … … 100 100 numVarsWithValues = 0; 101 101 RefPtr<Plan> plan = adoptRef( 102 new Plan(co mpileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues));102 new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues)); 103 103 for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) { 104 104 int operand = plan->mustHandleValues.operandForIndex(i); 105 105 if (operandIsArgument(operand) 106 106 && !operandToArgument(operand) 107 && co mpileMode == CompileFunction107 && codeBlock->codeType() == FunctionCode 108 108 && codeBlock->specializationKind() == CodeForConstruct) { 109 109 // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will … … 116 116 } 117 117 118 if (enableConcurrentJIT()) { 118 if (enableConcurrentJIT() && callback) { 119 plan->callback = callback; 119 120 if (!vm.worklist) 120 121 vm.worklist = globalWorklist(); … … 126 127 127 128 plan->compileInThread(*vm.dfgState); 128 return plan->finalize(jitCode, jitCodeWithArityCheck); 129 } 130 131 CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex) 132 { 133 return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex); 134 } 135 136 CompilationResult tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex) 137 { 138 return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck, bytecodeIndex); 139 } 140 141 CompilationResult tryFinalizePlan(PassRefPtr<Plan> plan, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck) 142 { 143 return plan->finalize(jitCode, jitCodeWithArityCheck); 129 return plan->finalizeWithoutNotifyingCallback(); 144 130 } 145 131 -
trunk/Source/JavaScriptCore/dfg/DFGDriver.h
r153216 r154804 43 43 44 44 #if ENABLE(DFG_JIT) 45 CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned bytecodeIndex); 46 CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex); 47 CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr* jitCodeWithArityCheck); 45 CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>); 48 46 #else 49 inline CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return CompilationFailed; } 50 inline CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return CompilationFailed; } 51 inline CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr*) 52 { 53 UNREACHABLE_FOR_PLATFORM(); 54 return CompilationFailed; 55 } 47 inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; } 56 48 #endif 57 49 -
trunk/Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp
r153161 r154804 40 40 } 41 41 42 bool FailedFinalizer::finalize( RefPtr<JSC::JITCode>&)42 bool FailedFinalizer::finalize() 43 43 { 44 44 return false; 45 45 } 46 46 47 bool FailedFinalizer::finalizeFunction( RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&)47 bool FailedFinalizer::finalizeFunction() 48 48 { 49 49 return false; -
trunk/Source/JavaScriptCore/dfg/DFGFailedFinalizer.h
r153161 r154804 40 40 virtual ~FailedFinalizer(); 41 41 42 bool finalize( RefPtr<JSC::JITCode>& entry);43 bool finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);42 bool finalize(); 43 bool finalizeFunction(); 44 44 }; 45 45 -
trunk/Source/JavaScriptCore/dfg/DFGFinalizer.h
r153161 r154804 47 47 virtual ~Finalizer(); 48 48 49 virtual bool finalize( RefPtr<JSC::JITCode>& entry) = 0;50 virtual bool finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) = 0;49 virtual bool finalize() = 0; 50 virtual bool finalizeFunction() = 0; 51 51 52 52 protected: -
trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp
r153165 r154804 29 29 #if ENABLE(DFG_JIT) 30 30 31 #include "CodeBlock.h" 31 32 #include "DFGCommon.h" 32 33 #include "DFGPlan.h" … … 46 47 } 47 48 48 bool JITFinalizer::finalize( RefPtr<JSC::JITCode>& entry)49 bool JITFinalizer::finalize() 49 50 { 50 51 finalizeCommon(); 51 52 52 53 m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); 53 entry = m_jitCode;54 m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr()); 54 55 55 56 return true; 56 57 } 57 58 58 bool JITFinalizer::finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)59 bool JITFinalizer::finalizeFunction() 59 60 { 60 61 finalizeCommon(); 61 62 62 withArityCheck = m_linkBuffer->locationOf(m_arityCheck);63 MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck); 63 64 m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); 64 entry = m_jitCode;65 m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck); 65 66 66 67 return true; -
trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.h
r153161 r154804 43 43 virtual ~JITFinalizer(); 44 44 45 bool finalize( RefPtr<JSC::JITCode>& entry);46 bool finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);45 bool finalize(); 46 bool finalizeFunction(); 47 47 48 48 private: -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp
r153123 r154804 31 31 #include "CodeBlock.h" 32 32 #include "Executable.h" 33 #include "JITCode.h" 33 34 #include "Operations.h" 34 35 … … 37 38 void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin) 38 39 { 40 DeferGC deferGC(exec->vm().heap); 41 39 42 for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) { 40 43 FunctionExecutable* executable = … … 43 46 codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct); 44 47 45 codeBlock->jitCompile(exec); 48 if (codeBlock->jitType() == JSC::JITCode::BaselineJIT) 49 continue; 50 ASSERT(codeBlock->jitType() == JSC::JITCode::InterpreterThunk); 51 CompilationResult result = codeBlock->prepareForExecution( 52 exec, JSC::JITCode::BaselineJIT, JITCompilationMustSucceed); 53 ASSERT_UNUSED(result, result == CompilationSuccessful); 54 codeBlock->install(); 46 55 } 47 56 } -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r154797 r154804 1282 1282 else { 1283 1283 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 1284 JSObject* error = functionExecutable-> compileFor(execCallee, callee->scope(), kind);1284 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); 1285 1285 if (error) { 1286 1286 vm->throwException(exec, createStackOverflowError(exec)); … … 1327 1327 if (UNLIKELY(!executable->hasJITCodeFor(kind))) { 1328 1328 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 1329 JSObject* error = functionExecutable-> compileFor(execCallee, function->scope(), kind);1329 JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind); 1330 1330 if (error) { 1331 1331 exec->vm().throwException(execCallee, error); -
trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp
r154468 r154804 81 81 82 82 Plan::Plan( 83 CompileMode compileMode,PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,83 PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex, 84 84 unsigned numVarsWithValues) 85 : compileMode(compileMode) 86 , vm(*passedCodeBlock->vm()) 85 : vm(*passedCodeBlock->vm()) 87 86 , codeBlock(passedCodeBlock) 88 87 , osrEntryBytecodeIndex(osrEntryBytecodeIndex) … … 209 208 #if ENABLE(FTL_JIT) 210 209 if (Options::useExperimentalFTL() 211 && co mpileMode == CompileFunction210 && codeBlock->codeType() == FunctionCode 212 211 && FTL::canCompile(dfg)) { 213 212 … … 256 255 257 256 JITCompiler dataFlowJIT(dfg); 258 if (co mpileMode == CompileFunction) {257 if (codeBlock->codeType() == FunctionCode) { 259 258 dataFlowJIT.compileFunction(); 260 259 dataFlowJIT.linkFunction(); 261 260 } else { 262 ASSERT(compileMode == CompileOther);263 264 261 dataFlowJIT.compile(); 265 262 dataFlowJIT.link(); … … 284 281 } 285 282 286 CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck) 283 void Plan::notifyReady() 284 { 285 callback->compilationDidBecomeReadyAsynchronously(codeBlock.get()); 286 isCompiled = true; 287 } 288 289 CompilationResult Plan::finalizeWithoutNotifyingCallback() 287 290 { 288 291 if (!isStillValid()) … … 290 293 291 294 bool result; 292 if (co mpileMode == CompileFunction)293 result = finalizer->finalizeFunction( jitCode, *jitCodeWithArityCheck);295 if (codeBlock->codeType() == FunctionCode) 296 result = finalizer->finalizeFunction(); 294 297 else 295 result = finalizer->finalize( jitCode);298 result = finalizer->finalize(); 296 299 297 300 if (!result) 298 301 return CompilationFailed; 299 302 300 reallyAdd( jitCode->dfgCommon());303 reallyAdd(codeBlock->jitCode()->dfgCommon()); 301 304 302 305 return CompilationSuccessful; 303 306 } 304 307 308 void Plan::finalizeAndNotifyCallback() 309 { 310 callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback()); 311 } 312 305 313 CodeBlock* Plan::key() 306 314 { -
trunk/Source/JavaScriptCore/dfg/DFGPlan.h
r154162 r154804 37 37 #include "DFGDesiredWriteBarriers.h" 38 38 #include "DFGFinalizer.h" 39 #include "DeferredCompilationCallback.h" 39 40 #include "Operands.h" 40 41 #include "ProfilerCompilation.h" … … 49 50 class LongLivedState; 50 51 51 enum CompileMode { CompileFunction, CompileOther };52 53 52 #if ENABLE(DFG_JIT) 54 53 55 54 struct Plan : public ThreadSafeRefCounted<Plan> { 56 55 Plan( 57 CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock, 58 unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues); 56 PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues); 59 57 ~Plan(); 60 58 61 59 void compileInThread(LongLivedState&); 62 60 63 CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck); 61 CompilationResult finalizeWithoutNotifyingCallback(); 62 void finalizeAndNotifyCallback(); 63 64 void notifyReady(); 64 65 65 66 CodeBlock* key(); 66 67 67 const CompileMode compileMode;68 68 VM& vm; 69 69 RefPtr<CodeBlock> codeBlock; … … 87 87 bool isCompiled; 88 88 89 RefPtr<DeferredCompilationCallback> callback; 90 89 91 private: 90 92 enum CompilationPath { FailPath, DFGPath, FTLPath }; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r154403 r154804 3838 3838 } 3839 3839 3840 if (isCellSpeculation(node->child1()->prediction())) { 3840 switch (node->child1().useKind()) { 3841 case CellUse: { 3841 3842 SpeculateCellOperand base(this, node->child1()); 3842 3843 GPRTemporary resultTag(this, base); … … 3855 3856 } 3856 3857 3857 JSValueOperand base(this, node->child1()); 3858 GPRTemporary resultTag(this, base); 3859 GPRTemporary resultPayload(this); 3860 3861 GPRReg baseTagGPR = base.tagGPR(); 3862 GPRReg basePayloadGPR = base.payloadGPR(); 3863 GPRReg resultTagGPR = resultTag.gpr(); 3864 GPRReg resultPayloadGPR = resultPayload.gpr(); 3865 3866 base.use(); 3867 3868 JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); 3869 3870 cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell); 3871 3872 jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly); 3858 case UntypedUse: { 3859 JSValueOperand base(this, node->child1()); 3860 GPRTemporary resultTag(this, base); 3861 GPRTemporary resultPayload(this); 3862 3863 GPRReg baseTagGPR = base.tagGPR(); 3864 GPRReg basePayloadGPR = base.payloadGPR(); 3865 GPRReg resultTagGPR = resultTag.gpr(); 3866 GPRReg resultPayloadGPR = resultPayload.gpr(); 3867 3868 base.use(); 3869 3870 JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); 3871 3872 cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell); 3873 3874 jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly); 3875 break; 3876 } 3877 3878 default: 3879 RELEASE_ASSERT_NOT_REACHED(); 3880 break; 3881 } 3873 3882 break; 3874 3883 } -
trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp
r153321 r154804 166 166 RELEASE_ASSERT(plan->isCompiled); 167 167 168 CompilationResult compilationResult = 169 profiledBlock->replaceWithDeferredOptimizedCode(plan); 170 RELEASE_ASSERT(compilationResult != CompilationDeferred); 171 profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult); 168 plan->finalizeAndNotifyCallback(); 172 169 173 170 if (profiledBlock == requestedProfiledBlock) … … 244 241 { 245 242 MutexLocker locker(m_lock); 246 plan->key()->forceOptimizationSlowPathConcurrently(); 247 plan->isCompiled = true; 243 plan->notifyReady(); 248 244 249 245 if (Options::verboseCompilationQueue()) { -
trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp
r153172 r154804 45 45 } 46 46 47 bool JITFinalizer::finalize( RefPtr<JSC::JITCode>&)47 bool JITFinalizer::finalize() 48 48 { 49 49 RELEASE_ASSERT_NOT_REACHED(); … … 51 51 } 52 52 53 bool JITFinalizer::finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)53 bool JITFinalizer::finalizeFunction() 54 54 { 55 55 for (unsigned i = m_jitCode->handles().size(); i--;) { … … 65 65 } // else this function had no OSR exits, so no exit thunks. 66 66 67 withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);67 MacroAssemblerCodePtr withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck); 68 68 m_jitCode->initializeCode( 69 69 FINALIZE_DFG_CODE( 70 70 *m_entrypointLinkBuffer, 71 71 ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), m_function))); 72 entry = m_jitCode; 72 73 m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck); 73 74 74 75 return true; -
trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h
r153256 r154804 66 66 } 67 67 68 bool finalize( RefPtr<JSC::JITCode>& entry);69 bool finalizeFunction( RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);68 bool finalize(); 69 bool finalizeFunction(); 70 70 71 71 private: -
trunk/Source/JavaScriptCore/heap/Heap.h
r154471 r154804 185 185 186 186 void addReference(JSCell*, ArrayBuffer*); 187 188 bool isDeferred() const { return !!m_deferralDepth; } 187 189 188 190 private: -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r154797 r154804 735 735 return checkedReturn(callFrame->vm().throwException(callFrame, error)); 736 736 737 if (JSObject* error = program-> compile(callFrame, scope))737 if (JSObject* error = program->prepareForExecution(callFrame, scope, CodeForCall)) 738 738 return checkedReturn(callFrame->vm().throwException(callFrame, error)); 739 739 … … 804 804 if (isJSCall) { 805 805 // Compile the callee: 806 JSObject* compileError = callData.js.functionExecutable-> compileForCall(callFrame, scope);806 JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall); 807 807 if (UNLIKELY(!!compileError)) { 808 808 return checkedReturn(callFrame->vm().throwException(callFrame, compileError)); … … 883 883 if (isJSConstruct) { 884 884 // Compile the callee: 885 JSObject* compileError = constructData.js.functionExecutable-> compileForConstruct(callFrame, scope);885 JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct); 886 886 if (UNLIKELY(!!compileError)) { 887 887 return checkedReturn(callFrame->vm().throwException(callFrame, compileError)); … … 957 957 958 958 // Compile the callee: 959 JSObject* error = functionExecutable-> compileForCall(callFrame, scope);959 JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall); 960 960 if (error) { 961 961 callFrame->vm().throwException(callFrame, error); … … 1073 1073 } 1074 1074 1075 JSObject* compileError = eval-> compile(callFrame, scope);1075 JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall); 1076 1076 if (UNLIKELY(!!compileError)) 1077 1077 return checkedReturn(callFrame->vm().throwException(callFrame, compileError)); -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r154797 r154804 52 52 #include "JIT.h" 53 53 #include "JITExceptions.h" 54 #include "JITToDFGDeferredCompilationCallback.h" 54 55 #include "JSActivation.h" 55 56 #include "JSArray.h" … … 999 1000 dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n"); 1000 1001 // If we have an optimized replacement, then it must be the case that we entered 1001 // cti_optimize from a loop. That's because i sthere's an optimized replacement,1002 // cti_optimize from a loop. That's because if there's an optimized replacement, 1002 1003 // then all calls to this function will be relinked to the replacement and so 1003 1004 // the prologue OSR will never fire. … … 1033 1034 dataLog("Triggering optimized compilation of ", *codeBlock, "\n"); 1034 1035 1035 JSScope* scope = callFrame->scope(); 1036 CompilationResult result; 1037 JSObject* error = codeBlock->compileOptimized(callFrame, scope, result, bytecodeIndex); 1038 if (Options::verboseOSR()) { 1039 dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n"); 1040 if (error) 1041 dataLog("WARNING: optimized compilation failed with a JS error.\n"); 1042 } 1036 RefPtr<DeferredCompilationCallback> callback = 1037 JITToDFGDeferredCompilationCallback::create(); 1038 RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement(); 1039 CompilationResult result = newCodeBlock->prepareForExecutionAsynchronously( 1040 callFrame, JITCode::DFGJIT, callback, JITCompilationCanFail, bytecodeIndex); 1043 1041 1044 codeBlock->setOptimizationThresholdBasedOnCompilationResult(result);1045 1042 if (result != CompilationSuccessful) 1046 1043 return; … … 1169 1166 FunctionExecutable* executable = function->jsExecutable(); 1170 1167 JSScope* callDataScopeChain = function->scope(); 1171 JSObject* error = executable-> compileFor(callFrame, callDataScopeChain, kind);1168 JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind); 1172 1169 if (!error) 1173 1170 return function; … … 1268 1265 else { 1269 1266 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 1270 if (JSObject* error = functionExecutable-> compileFor(callFrame, callee->scope(), kind)) {1267 if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) { 1271 1268 callFrame->vm().throwException(callFrame, error); 1272 1269 return 0; … … 1345 1342 FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable); 1346 1343 JSScope* scopeChain = callee->scope(); 1347 JSObject* error = functionExecutable-> compileFor(callFrame, scopeChain, CodeForCall);1344 JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall); 1348 1345 if (error) { 1349 1346 callFrame->vm().throwException(callFrame, error); -
trunk/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
r153113 r154804 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if ENABLE(LLINT) 30 30 31 #include "CodeBlock.h" 31 32 #include "JITCode.h" 32 #include "VM.h"33 33 #include "JSObject.h" 34 34 #include "LLIntThunks.h" 35 35 #include "LowLevelInterpreter.h" 36 #include "VM.h" 36 37 37 38 38 39 namespace JSC { namespace LLInt { 39 40 40 void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck)41 void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock) 41 42 { 43 CodeSpecializationKind kind = codeBlock->specializationKind(); 44 42 45 if (!vm.canUseJIT()) { 43 46 if (kind == CodeForCall) { 44 jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)); 45 arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check); 47 codeBlock->setJITCode( 48 adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)), 49 MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check)); 46 50 return; 47 51 } 48 52 49 53 ASSERT(kind == CodeForConstruct); 50 jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)); 51 arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check); 54 codeBlock->setJITCode( 55 adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)), 56 MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check)); 52 57 return; 53 58 } … … 55 60 #if ENABLE(JIT) 56 61 if (kind == CodeForCall) { 57 jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)); 58 arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code(); 62 codeBlock->setJITCode( 63 adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)), 64 vm.getCTIStub(functionForCallArityCheckThunkGenerator).code()); 59 65 return; 60 66 } 61 67 62 68 ASSERT(kind == CodeForConstruct); 63 jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)); 64 arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code(); 69 codeBlock->setJITCode( 70 adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)), 71 vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code()); 65 72 #endif // ENABLE(JIT) 66 73 } 67 74 68 void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)75 void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock) 69 76 { 70 77 if (!vm.canUseJIT()) { 71 jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)); 78 codeBlock->setJITCode( 79 adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)), 80 MacroAssemblerCodePtr()); 72 81 return; 73 82 } 74 #if ENABLE(JIT) 75 jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)); 83 #if ENABLE(JIT) 84 codeBlock->setJITCode( 85 adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)), 86 MacroAssemblerCodePtr()); 76 87 #endif 77 88 } 78 89 79 void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)90 void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock) 80 91 { 81 92 if (!vm.canUseJIT()) { 82 jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)); 93 codeBlock->setJITCode( 94 adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)), 95 MacroAssemblerCodePtr()); 83 96 return; 84 97 } 85 98 #if ENABLE(JIT) 86 jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)); 99 codeBlock->setJITCode( 100 adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)), 101 MacroAssemblerCodePtr()); 87 102 #endif 88 103 } -
trunk/Source/JavaScriptCore/llint/LLIntEntrypoints.h
r153113 r154804 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 39 39 class EvalCodeBlock; 40 class FunctionCodeBlock; 40 41 class VM; 41 42 class MacroAssemblerCodePtr; … … 45 46 namespace LLInt { 46 47 47 void getFunctionEntrypoint(VM&, CodeSpecializationKind, RefPtr<JITCode>&, MacroAssemblerCodePtr& arityCheck); 48 void getEvalEntrypoint(VM&, RefPtr<JITCode>&); 49 void getProgramEntrypoint(VM&, RefPtr<JITCode>&); 50 51 inline void getEntrypoint(VM& vm, EvalCodeBlock*, RefPtr<JITCode>& jitCode) 52 { 53 getEvalEntrypoint(vm, jitCode); 54 } 55 56 inline void getEntrypoint(VM& vm, ProgramCodeBlock*, RefPtr<JITCode>& jitCode) 57 { 58 getProgramEntrypoint(vm, jitCode); 59 } 48 void setFunctionEntrypoint(VM&, FunctionCodeBlock*); 49 void setEvalEntrypoint(VM&, EvalCodeBlock*); 50 void setProgramEntrypoint(VM&, ProgramCodeBlock*); 60 51 61 52 } } // namespace JSC::LLInt -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r154797 r154804 38 38 #include "Interpreter.h" 39 39 #include "JIT.h" 40 #include "JITDriver.h"41 40 #include "JSActivation.h" 42 41 #include "JSCJSValue.h" … … 281 280 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec) 282 281 { 282 DeferGC deferGC(exec->vm().heap); 283 283 284 codeBlock->updateAllValueProfilePredictions(); 284 285 … … 289 290 } 290 291 291 CompilationResult result = codeBlock->jitCompile(exec); 292 switch (result) { 293 case CompilationNotNeeded: 292 switch (codeBlock->jitType()) { 293 case JITCode::BaselineJIT: { 294 294 if (Options::verboseOSR()) 295 295 dataLogF(" Code was already compiled.\n"); 296 296 codeBlock->jitSoon(); 297 297 return true; 298 case CompilationFailed: 299 if (Options::verboseOSR()) 300 dataLogF(" JIT compilation failed.\n"); 301 codeBlock->dontJITAnytimeSoon(); 302 return false; 303 case CompilationSuccessful: 304 if (Options::verboseOSR()) 305 dataLogF(" JIT compilation successful.\n"); 306 codeBlock->jitSoon(); 307 return true; 298 } 299 case JITCode::InterpreterThunk: { 300 CompilationResult result = codeBlock->prepareForExecution( 301 exec, JITCode::BaselineJIT, JITCompilationCanFail); 302 switch (result) { 303 case CompilationFailed: 304 if (Options::verboseOSR()) 305 dataLogF(" JIT compilation failed.\n"); 306 codeBlock->dontJITAnytimeSoon(); 307 return false; 308 case CompilationSuccessful: 309 if (Options::verboseOSR()) 310 dataLogF(" JIT compilation successful.\n"); 311 codeBlock->install(); 312 codeBlock->jitSoon(); 313 return true; 314 default: 315 RELEASE_ASSERT_NOT_REACHED(); 316 return false; 317 } 318 } 308 319 default: 309 320 RELEASE_ASSERT_NOT_REACHED(); … … 1005 1016 else { 1006 1017 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 1007 JSObject* error = functionExecutable-> compileFor(execCallee, callee->scope(), kind);1018 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); 1008 1019 if (error) 1009 1020 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error); -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
r154373 r154804 79 79 FunctionExecutable* executable = callData.js.functionExecutable; 80 80 81 JSObject* error = executable-> compileForCall(exec, callData.js.scope);81 JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall); 82 82 if (error) 83 83 return false; -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r154797 r154804 38 38 #include "Interpreter.h" 39 39 #include "JIT.h" 40 #include "JITDriver.h"41 40 #include "JITStubs.h" 42 41 #include "JSActivation.h" -
trunk/Source/JavaScriptCore/runtime/CompilationResult.cpp
r153165 r154804 43 43 out.print("CompilationSuccessful"); 44 44 return; 45 case CompilationNotNeeded:46 out.print("CompilationNotNeeded");47 return;48 45 case CompilationDeferred: 49 46 out.print("CompilationDeferred"); -
trunk/Source/JavaScriptCore/runtime/CompilationResult.h
r153165 r154804 31 31 namespace JSC { 32 32 33 enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred }; 33 enum CompilationResult { 34 // We tried to compile the code, but we couldn't compile it. This could be 35 // because we ran out of memory, or because the compiler encountered an 36 // internal error and decided to bail out gracefully. Either way, this implies 37 // that we shouldn't try to compile this code block again. 38 CompilationFailed, 39 40 // The profiling assumptions that were fed into the compiler were invalidated 41 // even before we finished compiling. This means we should try again: in such 42 // cases the profiling will now be updated and the next compilation won't 43 // encounter the same problem. But it does mean that we should exercise 44 // exponential back-off, to get even more profiling so that new profiling 45 // pathologies aren't encountered. 46 CompilationInvalidated, 47 48 // The compilation succeeded and the code block now has JITCode for the newly 49 // compiled code. However, compilation success doesn't mean that the CodeBlock 50 // will execute yet; you typically have to install it first, unless you plan 51 // on invoking it manually (something that *could* be done for some kinds of 52 // OSR entry). 53 CompilationSuccessful, 54 55 // We decided to do the compilation asynchronously. This means that we haven't 56 // yet compiled the code. This only happens when you pass a 57 // DeferredCompilationCallback. That callback will get called with some 58 // interesting result, once compilation completes. 59 CompilationDeferred 60 }; 34 61 35 62 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r154797 r154804 1 1 /* 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 #include "CodeBlock.h" 32 32 #include "DFGDriver.h" 33 #include "ExecutionHarness.h"34 33 #include "JIT.h" 35 #include "JITDriver.h"36 34 #include "Operations.h" 37 35 #include "Parser.h" … … 115 113 #endif 116 114 115 void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) 116 { 117 RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this); 118 119 VM& vm = *genericCodeBlock->vm(); 120 121 if (vm.m_perBytecodeProfiler) 122 vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock); 123 124 ASSERT(vm.heap.isDeferred()); 125 126 if (JITCode::isJIT(genericCodeBlock->jitType())) { 127 vm.heap.reportExtraMemoryCost( 128 sizeof(CodeBlock) + genericCodeBlock->jitCode()->size()); 129 } else 130 vm.heap.reportExtraMemoryCost(sizeof(CodeBlock)); 131 132 CodeSpecializationKind kind = genericCodeBlock->specializationKind(); 133 134 RefPtr<CodeBlock> oldCodeBlock; 135 136 switch (kind) { 137 case CodeForCall: 138 m_jitCodeForCall = genericCodeBlock->jitCode(); 139 m_jitCodeForCallWithArityCheck = genericCodeBlock->jitCodeWithArityCheck(); 140 m_numParametersForCall = genericCodeBlock->numParameters(); 141 break; 142 case CodeForConstruct: 143 m_jitCodeForConstruct = genericCodeBlock->jitCode(); 144 m_jitCodeForConstructWithArityCheck = genericCodeBlock->jitCodeWithArityCheck(); 145 m_numParametersForConstruct = genericCodeBlock->numParameters(); 146 break; 147 } 148 149 switch (genericCodeBlock->codeType()) { 150 case GlobalCode: { 151 ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); 152 ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock); 153 154 ASSERT(!codeBlock->jitCodeWithArityCheck()); 155 ASSERT(kind == CodeForCall); 156 157 oldCodeBlock = executable->m_programCodeBlock; 158 executable->m_programCodeBlock = codeBlock; 159 break; 160 } 161 162 case EvalCode: { 163 EvalExecutable* executable = jsCast<EvalExecutable*>(this); 164 EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock); 165 166 ASSERT(!codeBlock->jitCodeWithArityCheck()); 167 ASSERT(kind == CodeForCall); 168 169 oldCodeBlock = executable->m_evalCodeBlock; 170 executable->m_evalCodeBlock = codeBlock; 171 break; 172 } 173 174 case FunctionCode: { 175 FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); 176 FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock); 177 178 switch (kind) { 179 case CodeForCall: 180 oldCodeBlock = executable->m_codeBlockForCall; 181 executable->m_codeBlockForCall = codeBlock; 182 break; 183 case CodeForConstruct: 184 oldCodeBlock = executable->m_codeBlockForConstruct; 185 executable->m_codeBlockForConstruct = codeBlock; 186 break; 187 } 188 break; 189 } } 190 191 if (oldCodeBlock) 192 oldCodeBlock->unlinkIncomingCalls(); 193 } 194 195 PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor( 196 CodeSpecializationKind kind, JSScope* scope, JSObject*& exception) 197 { 198 VM* vm = scope->vm(); 199 200 ASSERT(vm->heap.isDeferred()); 201 202 if (classInfo() == EvalExecutable::info()) { 203 EvalExecutable* executable = jsCast<EvalExecutable*>(this); 204 RELEASE_ASSERT(kind == CodeForCall); 205 RELEASE_ASSERT(!executable->m_evalCodeBlock); 206 return adoptRef(new EvalCodeBlock( 207 executable, executable->m_unlinkedEvalCodeBlock.get(), scope, 208 executable->source().provider())); 209 } 210 211 if (classInfo() == ProgramExecutable::info()) { 212 ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); 213 RELEASE_ASSERT(kind == CodeForCall); 214 RELEASE_ASSERT(!executable->m_programCodeBlock); 215 return adoptRef(new ProgramCodeBlock( 216 executable, executable->m_unlinkedProgramCodeBlock.get(), scope, 217 executable->source().provider(), executable->source().startColumn())); 218 } 219 220 RELEASE_ASSERT(classInfo() == FunctionExecutable::info()); 221 FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); 222 RELEASE_ASSERT(!executable->codeBlockFor(kind)); 223 JSGlobalObject* globalObject = scope->globalObject(); 224 ParserError error; 225 DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff; 226 ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff; 227 UnlinkedFunctionCodeBlock* unlinkedCodeBlock = 228 executable->m_unlinkedExecutable->codeBlockFor( 229 *vm, executable->m_source, kind, debuggerMode, profilerMode, error); 230 if (!unlinkedCodeBlock) { 231 exception = vm->throwException( 232 globalObject->globalExec(), 233 error.toErrorObject(globalObject, executable->m_source)); 234 return 0; 235 } 236 237 SourceProvider* provider = executable->source().provider(); 238 unsigned sourceOffset = executable->source().startOffset(); 239 unsigned startColumn = executable->source().startColumn(); 240 241 return adoptRef(new FunctionCodeBlock( 242 executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn)); 243 } 244 245 PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor( 246 CodeSpecializationKind kind) 247 { 248 if (classInfo() == EvalExecutable::info()) { 249 RELEASE_ASSERT(kind == CodeForCall); 250 EvalExecutable* executable = jsCast<EvalExecutable*>(this); 251 RefPtr<EvalCodeBlock> result = adoptRef(new EvalCodeBlock( 252 CodeBlock::CopyParsedBlock, *executable->m_evalCodeBlock)); 253 result->setAlternative(executable->m_evalCodeBlock); 254 return result; 255 } 256 257 if (classInfo() == ProgramExecutable::info()) { 258 RELEASE_ASSERT(kind == CodeForCall); 259 ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); 260 RefPtr<ProgramCodeBlock> result = adoptRef(new ProgramCodeBlock( 261 CodeBlock::CopyParsedBlock, *executable->m_programCodeBlock)); 262 result->setAlternative(executable->m_programCodeBlock); 263 return result; 264 } 265 266 RELEASE_ASSERT(classInfo() == FunctionExecutable::info()); 267 FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); 268 RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock( 269 CodeBlock::CopyParsedBlock, *executable->codeBlockFor(kind))); 270 result->setAlternative(executable->codeBlockFor(kind)); 271 return result; 272 } 273 274 JSObject* ScriptExecutable::prepareForExecutionImpl( 275 ExecState* exec, JSScope* scope, CodeSpecializationKind kind) 276 { 277 VM& vm = exec->vm(); 278 DeferGC deferGC(vm.heap); 279 280 JSObject* exception = 0; 281 RefPtr<CodeBlock> codeBlock = newCodeBlockFor(kind, scope, exception); 282 if (!codeBlock) { 283 RELEASE_ASSERT(exception); 284 return exception; 285 } 286 287 JITCode::JITType jitType; 288 #if ENABLE(LLINT) 289 jitType = JITCode::InterpreterThunk; 290 #else 291 jitType = JITCode::BaselineJIT; 292 #endif 293 codeBlock->prepareForExecution(exec, jitType); 294 295 installCode(codeBlock.get()); 296 return 0; 297 } 298 117 299 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) }; 118 300 … … 176 358 static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable(); 177 359 } 178 179 #if ENABLE(DFG_JIT)180 JSObject* EvalExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)181 {182 ASSERT(exec->vm().dynamicGlobalObject);183 ASSERT(!!m_evalCodeBlock);184 JSObject* error = 0;185 if (!JITCode::isOptimizingJIT(m_evalCodeBlock->jitType()))186 error = compileInternal(exec, scope, JITCode::nextTierJIT(m_evalCodeBlock->jitType()), &result, bytecodeIndex);187 else188 result = CompilationNotNeeded;189 ASSERT(!!m_evalCodeBlock);190 return error;191 }192 #endif // ENABLE(DFG_JIT)193 194 #if ENABLE(JIT)195 CompilationResult EvalExecutable::jitCompile(ExecState* exec)196 {197 return jitCompileIfAppropriate(exec, m_evalCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);198 }199 #endif200 360 201 361 inline const char* samplingDescription(JITCode::JITType jitType) … … 216 376 } 217 377 218 JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)219 {220 SamplingRegion samplingRegion(samplingDescription(jitType));221 222 if (result)223 *result = CompilationFailed;224 225 RefPtr<EvalCodeBlock> newCodeBlock;226 227 if (!!m_evalCodeBlock) {228 newCodeBlock = adoptRef(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));229 newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock));230 } else {231 newCodeBlock = adoptRef(new EvalCodeBlock(this, m_unlinkedEvalCodeBlock.get(), scope, source().provider()));232 ASSERT((jitType == JITCode::bottomTierJIT()) == !m_evalCodeBlock);233 }234 235 CompilationResult theResult = prepareForExecution(236 exec, m_evalCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);237 if (result)238 *result = theResult;239 240 return 0;241 }242 243 #if ENABLE(DFG_JIT)244 CompilationResult EvalExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)245 {246 return JSC::replaceWithDeferredOptimizedCode(247 plan, m_evalCodeBlock, m_jitCodeForCall, 0, 0);248 }249 #endif // ENABLE(DFG_JIT)250 251 378 #if ENABLE(JIT) 252 379 void EvalExecutable::jettisonOptimizedCode(VM& vm) … … 299 426 } 300 427 301 #if ENABLE(DFG_JIT)302 JSObject* ProgramExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)303 {304 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);305 ASSERT(!!m_programCodeBlock);306 JSObject* error = 0;307 if (!JITCode::isOptimizingJIT(m_programCodeBlock->jitType()))308 error = compileInternal(exec, scope, JITCode::nextTierJIT(m_programCodeBlock->jitType()), &result, bytecodeIndex);309 else310 result = CompilationNotNeeded;311 ASSERT(!!m_programCodeBlock);312 return error;313 }314 #endif // ENABLE(DFG_JIT)315 316 #if ENABLE(JIT)317 CompilationResult ProgramExecutable::jitCompile(ExecState* exec)318 {319 return jitCompileIfAppropriate(exec, m_programCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);320 }321 #endif322 323 JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)324 {325 SamplingRegion samplingRegion(samplingDescription(jitType));326 327 if (result)328 *result = CompilationFailed;329 330 RefPtr<ProgramCodeBlock> newCodeBlock;331 332 if (!!m_programCodeBlock) {333 newCodeBlock = adoptRef(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));334 newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock));335 } else {336 newCodeBlock = adoptRef(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), scope, source().provider(), source().startColumn()));337 }338 339 CompilationResult theResult = prepareForExecution(340 exec, m_programCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);341 if (result)342 *result = theResult;343 344 return 0;345 }346 347 #if ENABLE(DFG_JIT)348 CompilationResult ProgramExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)349 {350 return JSC::replaceWithDeferredOptimizedCode(351 plan, m_programCodeBlock, m_jitCodeForCall, 0, 0);352 }353 #endif // ENABLE(DFG_JIT)354 355 428 #if ENABLE(JIT) 356 429 void ProgramExecutable::jettisonOptimizedCode(VM& vm) … … 444 517 return result; 445 518 } 446 447 #if ENABLE(DFG_JIT)448 JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)449 {450 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);451 ASSERT(!!m_codeBlockForCall);452 JSObject* error = 0;453 if (!JITCode::isOptimizingJIT(m_codeBlockForCall->jitType()))454 error = compileForCallInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForCall->jitType()), &result, bytecodeIndex);455 else456 result = CompilationNotNeeded;457 ASSERT(!!m_codeBlockForCall);458 return error;459 }460 461 JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)462 {463 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);464 ASSERT(!!m_codeBlockForConstruct);465 JSObject* error = 0;466 if (!JITCode::isOptimizingJIT(m_codeBlockForConstruct->jitType()))467 error = compileForConstructInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForConstruct->jitType()), &result, bytecodeIndex);468 else469 result = CompilationNotNeeded;470 ASSERT(!!m_codeBlockForConstruct);471 return error;472 }473 #endif // ENABLE(DFG_JIT)474 475 #if ENABLE(JIT)476 CompilationResult FunctionExecutable::jitCompileForCall(ExecState* exec)477 {478 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);479 }480 481 CompilationResult FunctionExecutable::jitCompileForConstruct(ExecState* exec)482 {483 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);484 }485 #endif486 487 PassRefPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)488 {489 RefPtr<FunctionCodeBlock> alternative = codeBlockFor(specializationKind);490 491 if (!!alternative) {492 RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));493 result->setAlternative(alternative);494 return result.release();495 }496 497 VM* vm = scope->vm();498 JSGlobalObject* globalObject = scope->globalObject();499 ParserError error;500 DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;501 ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;502 UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, m_source, specializationKind, debuggerMode, profilerMode, error);503 recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());504 505 if (!unlinkedCodeBlock) {506 exception = vm->throwException(globalObject->globalExec(), error.toErrorObject(globalObject, m_source));507 return 0;508 }509 510 SourceProvider* provider = source().provider();511 unsigned sourceOffset = source().startOffset();512 unsigned startColumn = source().startColumn();513 514 return adoptRef(new FunctionCodeBlock(this, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));515 }516 517 518 JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)519 {520 SamplingRegion samplingRegion(samplingDescription(jitType));521 522 if (result)523 *result = CompilationFailed;524 525 ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);526 JSObject* exception = 0;527 528 RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception);529 if (!newCodeBlock)530 return exception;531 532 CompilationResult theResult = prepareFunctionForExecution(533 exec, m_codeBlockForCall, newCodeBlock.get(), m_jitCodeForCall,534 m_jitCodeForCallWithArityCheck, m_numParametersForCall, jitType,535 bytecodeIndex, CodeForCall);536 if (result)537 *result = theResult;538 return 0;539 }540 541 #if ENABLE(DFG_JIT)542 CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan> plan)543 {544 return JSC::replaceWithDeferredOptimizedCode(545 plan, m_codeBlockForCall, m_jitCodeForCall, &m_jitCodeForCallWithArityCheck,546 &m_numParametersForCall);547 }548 #endif // ENABLE(DFG_JIT)549 550 JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)551 {552 SamplingRegion samplingRegion(samplingDescription(jitType));553 554 if (result)555 *result = CompilationFailed;556 557 ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);558 JSObject* exception = 0;559 RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception);560 if (!newCodeBlock)561 return exception;562 563 CompilationResult theResult = prepareFunctionForExecution(564 exec, m_codeBlockForConstruct, newCodeBlock.get(), m_jitCodeForConstruct,565 m_jitCodeForConstructWithArityCheck, m_numParametersForConstruct, jitType,566 bytecodeIndex, CodeForConstruct);567 if (result)568 *result = theResult;569 570 return 0;571 }572 573 #if ENABLE(DFG_JIT)574 CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan> plan)575 {576 return JSC::replaceWithDeferredOptimizedCode(577 plan, m_codeBlockForConstruct, m_jitCodeForConstruct,578 &m_jitCodeForConstructWithArityCheck, &m_numParametersForConstruct);579 }580 #endif // ENABLE(DFG_JIT)581 519 582 520 #if ENABLE(JIT) -
trunk/Source/JavaScriptCore/runtime/Executable.h
r154632 r154804 162 162 } 163 163 164 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind) 165 { 166 if (kind == CodeForCall) 167 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck); 168 ASSERT(kind == CodeForConstruct); 169 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck); 170 } 171 172 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind) 173 { 174 if (kind == CodeForCall) 175 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall); 176 ASSERT(kind == CodeForConstruct); 177 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct); 178 } 179 #endif // ENABLE(JIT) 180 164 181 bool hasJITCodeForCall() const 165 182 { … … 179 196 return hasJITCodeForConstruct(); 180 197 } 181 182 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)183 {184 if (kind == CodeForCall)185 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);186 ASSERT(kind == CodeForConstruct);187 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);188 }189 190 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)191 {192 if (kind == CodeForCall)193 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);194 ASSERT(kind == CodeForConstruct);195 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);196 }197 #endif // ENABLE(JIT)198 198 199 199 // Intrinsics are only for calls, currently. … … 245 245 #endif 246 246 } 247 247 248 #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP) 248 249 … … 403 404 } 404 405 406 void installCode(CodeBlock*); 407 PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception); 408 PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind); 409 410 JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind) 411 { 412 if (hasJITCodeFor(kind)) 413 return 0; 414 return prepareForExecutionImpl(exec, scope, kind); 415 } 416 417 private: 418 JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind); 419 405 420 protected: 406 421 void finishCreation(VM& vm) … … 431 446 static void destroy(JSCell*); 432 447 433 JSObject* compile(ExecState* exec, JSScope* scope)434 {435 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);436 JSObject* error = 0;437 if (!m_evalCodeBlock)438 error = compileInternal(exec, scope, JITCode::bottomTierJIT());439 ASSERT(!error == !!m_evalCodeBlock);440 return error;441 }442 443 #if ENABLE(DFG_JIT)444 JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);445 CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);446 #endif // ENABLE(DFG_JIT)447 448 448 #if ENABLE(JIT) 449 449 void jettisonOptimizedCode(VM&); 450 CompilationResult jitCompile(ExecState*);451 450 #endif 452 451 … … 482 481 483 482 private: 483 friend class ScriptExecutable; 484 484 static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; 485 485 EvalExecutable(ExecState*, const SourceCode&, bool); 486 486 487 JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);488 487 static void visitChildren(JSCell*, SlotVisitor&); 489 488 … … 509 508 static void destroy(JSCell*); 510 509 511 JSObject* compile(ExecState* exec, JSScope* scope)512 {513 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);514 JSObject* error = 0;515 if (!m_programCodeBlock)516 error = compileInternal(exec, scope, JITCode::bottomTierJIT());517 ASSERT(!error == !!m_programCodeBlock);518 return error;519 }520 521 #if ENABLE(DFG_JIT)522 JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);523 CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);524 #endif // ENABLE(DFG_JIT)525 526 510 #if ENABLE(JIT) 527 511 void jettisonOptimizedCode(VM&); 528 CompilationResult jitCompile(ExecState*);529 512 #endif 530 513 … … 558 541 559 542 private: 543 friend class ScriptExecutable; 544 560 545 static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; 561 546 562 547 ProgramExecutable(ExecState*, const SourceCode&); 563 548 564 JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);565 549 static void visitChildren(JSCell*, SlotVisitor&); 566 550 … … 601 585 } 602 586 603 PassRefPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);604 605 JSObject* compileForCall(ExecState* exec, JSScope* scope)606 {607 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);608 JSObject* error = 0;609 if (!m_codeBlockForCall)610 error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT());611 ASSERT(!error == !!m_codeBlockForCall);612 return error;613 }614 615 #if ENABLE(DFG_JIT)616 JSObject* compileOptimizedForCall(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);617 CompilationResult replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan>);618 #endif // ENABLE(DFG_JIT)619 620 587 #if ENABLE(JIT) 621 588 void jettisonOptimizedCodeForCall(VM&); 622 CompilationResult jitCompileForCall(ExecState*);623 589 #endif 624 590 … … 634 600 } 635 601 636 JSObject* compileForConstruct(ExecState* exec, JSScope* scope)637 {638 RELEASE_ASSERT(exec->vm().dynamicGlobalObject);639 JSObject* error = 0;640 if (!m_codeBlockForConstruct)641 error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT());642 ASSERT(!error == !!m_codeBlockForConstruct);643 return error;644 }645 646 #if ENABLE(DFG_JIT)647 JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);648 CompilationResult replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan>);649 #endif // ENABLE(DFG_JIT)650 651 602 #if ENABLE(JIT) 652 603 void jettisonOptimizedCodeForConstruct(VM&); 653 CompilationResult jitCompileForConstruct(ExecState*);654 604 #endif 655 605 … … 665 615 } 666 616 667 JSObject* compileFor(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)668 {669 ASSERT(exec->callee());670 ASSERT(exec->callee()->inherits(JSFunction::info()));671 ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);672 673 if (kind == CodeForCall)674 return compileForCall(exec, scope);675 ASSERT(kind == CodeForConstruct);676 return compileForConstruct(exec, scope);677 }678 679 #if ENABLE(DFG_JIT)680 JSObject* compileOptimizedFor(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex, CodeSpecializationKind kind)681 {682 ASSERT(exec->callee());683 ASSERT(exec->callee()->inherits(JSFunction::info()));684 ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);685 686 if (kind == CodeForCall)687 return compileOptimizedForCall(exec, scope, result, bytecodeIndex);688 ASSERT(kind == CodeForConstruct);689 return compileOptimizedForConstruct(exec, scope, result, bytecodeIndex);690 }691 692 CompilationResult replaceWithDeferredOptimizedCodeFor(PassRefPtr<DFG::Plan> plan, CodeSpecializationKind kind)693 {694 if (kind == CodeForCall)695 return replaceWithDeferredOptimizedCodeForCall(plan);696 return replaceWithDeferredOptimizedCodeForConstruct(plan);697 }698 #endif // ENABLE(DFG_JIT)699 700 617 #if ENABLE(JIT) 701 618 void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind) … … 708 625 } 709 626 } 710 711 CompilationResult jitCompileFor(ExecState* exec, CodeSpecializationKind kind)712 {713 if (kind == CodeForCall)714 return jitCompileForCall(exec);715 ASSERT(kind == CodeForConstruct);716 return jitCompileForConstruct(exec);717 }718 627 #endif 719 628 … … 765 674 FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn); 766 675 767 JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);768 JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);769 770 676 RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind) 771 677 { … … 786 692 return false; 787 693 } 694 695 friend class ScriptExecutable; 788 696 789 697 static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
Note: See TracChangeset
for help on using the changeset viewer.