Changeset 154804 in webkit


Ignore:
Timestamp:
Aug 28, 2013 9:03:05 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

CodeBlock compilation and installation should be simplified and rationalized
https://bugs.webkit.org/show_bug.cgi?id=120326

Reviewed by Oliver Hunt.

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. ExecutionHarness and JITDriver are
both gone. Overall this patch has more red than green.

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):

  • ftl/FTLJITFinalizer.cpp:

(JSC::FTL::JITFinalizer::finalize):
(JSC::FTL::JITFinalizer::finalizeFunction):

  • ftl/FTLJITFinalizer.h:
  • 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::create):
(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.
Location:
trunk/Source/JavaScriptCore
Files:
4 added
2 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r154629 r154804  
    5454    bytecode/CodeType.cpp
    5555    bytecode/DFGExitProfile.cpp
     56    bytecode/DeferredCompilationCallback.cpp
    5657    bytecode/ExecutionCounter.cpp
    5758    bytecode/ExitKind.cpp
     
    244245    jit/JITStubs.cpp
    245246    jit/JITThunks.cpp
     247    jit/JITToDFGDeferredCompilationCallback.cpp
    246248    jit/JumpReplacementWatchpoint.cpp
    247249    jit/ThunkGenerators.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r154797 r154804  
     12013-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
    11782013-08-28  Chris Curtis  <chris_curtis@apple.com>
    2179
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r154747 r154804  
    114114        Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
    115115        Source/JavaScriptCore/bytecode/CodeOrigin.h \
    116         Source/JavaScriptCore/bytecode/DataFormat.h \
    117116        Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \
    118117        Source/JavaScriptCore/bytecode/DFGExitProfile.h \
     118        Source/JavaScriptCore/bytecode/DataFormat.h \
     119        Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp \
     120        Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h \
    119121        Source/JavaScriptCore/bytecode/EvalCodeCache.h \
    120122        Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
     
    605607        Source/JavaScriptCore/jit/JITDisassembler.cpp \
    606608        Source/JavaScriptCore/jit/JITDisassembler.h \
    607         Source/JavaScriptCore/jit/JITDriver.h \
    608609        Source/JavaScriptCore/jit/JIT.cpp \
    609610        Source/JavaScriptCore/jit/JIT.h \
     
    629630        Source/JavaScriptCore/jit/JITThunks.cpp \
    630631        Source/JavaScriptCore/jit/JITThunks.h \
     632        Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp \
     633        Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h \
    631634        Source/JavaScriptCore/jit/JITWriteBarrier.h \
    632635        Source/JavaScriptCore/jit/JSInterfaceJIT.h \
     
    784787        Source/JavaScriptCore/runtime/Executable.cpp \
    785788        Source/JavaScriptCore/runtime/Executable.h \
    786         Source/JavaScriptCore/runtime/ExecutionHarness.h \
    787789        Source/JavaScriptCore/runtime/Float32Array.h \
    788790        Source/JavaScriptCore/runtime/Float64Array.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r154638 r154804  
    303303    <ClCompile Include="..\bytecode\CodeOrigin.cpp" />
    304304    <ClCompile Include="..\bytecode\CodeType.cpp" />
     305    <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" />
    305306    <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />
    306307    <ClCompile Include="..\bytecode\ExitKind.cpp" />
     
    378379    <ClCompile Include="..\jit\JITStubs.cpp" />
    379380    <ClCompile Include="..\jit\JITThunks.cpp" />
     381    <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />
    380382    <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" />
    381383    <ClCompile Include="..\jit\ThunkGenerators.cpp" />
     
    624626    <ClInclude Include="..\bytecode\Comment.h" />
    625627    <ClInclude Include="..\bytecode\DataFormat.h" />
     628    <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" />
    626629    <ClInclude Include="..\bytecode\EvalCodeCache.h" />
    627630    <ClInclude Include="..\bytecode\ExecutionCounter.h" />
     
    741744    <ClInclude Include="..\jit\JITCompilationEffort.h" />
    742745    <ClInclude Include="..\jit\JITDisassembler.h" />
    743     <ClInclude Include="..\jit\JITDriver.h" />
    744746    <ClInclude Include="..\jit\JITExceptions.h" />
    745747    <ClInclude Include="..\jit\JITInlines.h" />
     
    751753    <ClInclude Include="..\jit\JITStubsX86_64.h" />
    752754    <ClInclude Include="..\jit\JITThunks.h" />
     755    <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" />
    753756    <ClInclude Include="..\jit\JITWriteBarrier.h" />
    754757    <ClInclude Include="..\jit\JSInterfaceJIT.h" />
     
    838841    <ClInclude Include="..\runtime\ExceptionHelpers.h" />
    839842    <ClInclude Include="..\runtime\Executable.h" />
    840     <ClInclude Include="..\runtime\ExecutionHarness.h" />
    841843    <ClInclude Include="..\runtime\Float32Array.h" />
    842844    <ClInclude Include="..\runtime\Float64Array.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r154629 r154804  
    8787                0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; };
    8888                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, ); }; };
    9189                0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
    9290                0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    348346                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
    349347                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, ); }; };
    350352                0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
    351353                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
     
    12441246                0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; };
    12451247                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>"; };
    12471248                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>"; };
    12491249                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
    12501250                0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; };
     
    15151515                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
    15161516                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>"; };
    15171521                0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
    15181522                0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
     
    26372641                                0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
    26382642                                0FAF7EFB165BA919000C8455 /* JITDisassembler.h */,
    2639                                 0F21C26614BE5F5E00ADC64B /* JITDriver.h */,
    26402643                                0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
    26412644                                0F46808014BA572700BFE272 /* JITExceptions.h */,
     
    26592662                                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
    26602663                                0F5EF91C16878F78003E5C25 /* JITThunks.h */,
     2664                                0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */,
     2665                                0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
    26612666                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
    26622667                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
     
    30413046                                86CA032D1038E8440028A609 /* Executable.cpp */,
    30423047                                86CAFEE21035DDE60028A609 /* Executable.h */,
    3043                                 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
    30443048                                A7A8AF2917ADB5F3005AB174 /* Float32Array.h */,
    30453049                                A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */,
     
    36493653                                0F0B83A514BCF50400885B4F /* CodeType.h */,
    36503654                                0F426A4A1460CD6B00131F8F /* DataFormat.h */,
     3655                                0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
     3656                                0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
    36513657                                0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
    36523658                                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
     
    37973803                                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
    37983804                                0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
     3805                                0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */,
    37993806                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
    38003807                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
     
    39383945                                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
    39393946                                0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
    3940                                 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
    39413947                                0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
    39423948                                0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
     
    40274033                                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
    40284034                                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
    4029                                 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
    40304035                                0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
    40314036                                86CC85A10EE79A4700288682 /* JITInlines.h in Headers */,
     
    40974102                                BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
    40984103                                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
     4104                                0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */,
    40994105                                A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
    41004106                                BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */,
     
    50105016                                148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
    50115017                                93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
     5018                                0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
    50125019                                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
    50135020                                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
     
    50885095                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
    50895096                                14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
     5097                                0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
    50905098                                0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */,
    50915099                                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
  • trunk/Source/JavaScriptCore/Target.pri

    r154629 r154804  
    6262    bytecode/CodeType.cpp \
    6363    bytecode/DFGExitProfile.cpp \
     64    bytecode/DeferredCompilationCallback.cpp \
    6465    bytecode/ExecutionCounter.cpp \
    6566    bytecode/ExitKind.cpp \
     
    222223    jit/JITStubs.cpp \
    223224    jit/JITThunks.cpp \
     225    jit/JITToDFGDeferredCompilationCallback.cpp \
    224226    jit/JumpReplacementWatchpoint.cpp \
    225227    jit/ThunkGenerators.cpp \
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r154162 r154804  
    3535#include "DFGCapabilities.h"
    3636#include "DFGCommon.h"
     37#include "DFGDriver.h"
    3738#include "DFGNode.h"
    3839#include "DFGRepatch.h"
     
    4647#include "JSFunction.h"
    4748#include "JSNameScope.h"
     49#include "LLIntEntrypoints.h"
    4850#include "LowLevelInterpreter.h"
    4951#include "Operations.h"
     
    25372539    m_incomingCalls.push(incoming);
    25382540}
     2541#endif // ENABLE(JIT)
    25392542
    25402543void CodeBlock::unlinkIncomingCalls()
     
    25432546    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
    25442547        m_incomingLLIntCalls.begin()->unlink();
    2545 #endif
     2548#endif // ENABLE(LLINT)
     2549#if ENABLE(JIT)
    25462550    if (m_incomingCalls.isEmpty())
    25472551        return;
     
    25492553    while (m_incomingCalls.begin() != m_incomingCalls.end())
    25502554        m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
    2551 }
    25522555#endif // ENABLE(JIT)
     2556}
    25532557
    25542558#if ENABLE(LLINT)
     
    26902694}
    26912695
     2696CompilationResult 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
     2740CompilationResult 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
     2750CompilationResult 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
     2763void CodeBlock::install()
     2764{
     2765    ownerExecutable()->installCode(this);
     2766}
     2767
     2768PassRefPtr<CodeBlock> CodeBlock::newReplacement()
     2769{
     2770    return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
     2771}
     2772
    26922773#if ENABLE(JIT)
    26932774void CodeBlock::reoptimize()
     
    27152796    return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
    27162797}
    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)
    27642798
    27652799DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
     
    28042838{
    28052839    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);
    28272840}
    28282841#endif
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r154245 r154804  
    4949#include "DFGOSRExit.h"
    5050#include "DFGVariableEventStream.h"
     51#include "DeferredCompilationCallback.h"
    5152#include "EvalCodeCache.h"
    5253#include "ExecutionCounter.h"
     
    203204    unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
    204205
     206    void unlinkIncomingCalls();
     207
    205208#if ENABLE(JIT)
    206209    unsigned bytecodeOffsetForCallAtIndex(unsigned index)
     
    232235#endif // ENABLE(LLINT)
    233236
    234     void unlinkIncomingCalls();
    235 
    236237#if ENABLE(DFG_JIT) || ENABLE(LLINT)
    237238    void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
     
    265266    int argumentIndexAfterCapture(size_t argument);
    266267
    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   
    268300    void setJITCode(PassRefPtr<JITCode> code, MacroAssemblerCodePtr codeWithArityCheck)
    269301    {
     
    287319        return result;
    288320    }
     321
     322#if ENABLE(JIT)
    289323    bool hasBaselineJITProfiling() const
    290324    {
    291325        return jitType() == JITCode::BaselineJIT;
    292326    }
    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)
    297327    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   
    306329    virtual CodeBlock* replacement() = 0;
    307330
     
    316339
    317340    bool hasOptimizedReplacement();
    318 #else
    319     JITCode::JITType jitType() const { return JITCode::InterpreterThunk; }
    320341#endif
    321342
     
    970991protected:
    971992#if ENABLE(JIT)
    972     virtual CompilationResult jitCompileImpl(ExecState*) = 0;
    973993    virtual void jettisonImpl() = 0;
    974994#endif
     
    9841004private:
    9851005    friend class DFGCodeBlocks;
     1006   
     1007    CompilationResult prepareForExecutionImpl(
     1008        ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex,
     1009        PassRefPtr<DeferredCompilationCallback>);
    9861010   
    9871011    void noticeIncomingCall(ExecState* callerFrame);
     
    10861110    SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
    10871111#endif
     1112    RefPtr<JITCode> m_jitCode;
     1113    MacroAssemblerCodePtr m_jitCodeWithArityCheck;
    10881114#if ENABLE(JIT)
    10891115    Vector<StructureStubInfo> m_structureStubInfos;
    10901116    Vector<ByValInfo> m_byValInfos;
    10911117    Vector<CallLinkInfo> m_callLinkInfos;
    1092     RefPtr<JITCode> m_jitCode;
    1093     MacroAssemblerCodePtr m_jitCodeWithArityCheck;
    10941118    SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
    10951119#endif
     
    11951219#if ENABLE(JIT)
    11961220protected:
    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 
    12021221    virtual void jettisonImpl();
    1203     virtual CompilationResult jitCompileImpl(ExecState*);
    12041222    virtual CodeBlock* replacement();
    12051223    virtual DFG::CapabilityLevel capabilityLevelInternal();
     
    12241242#if ENABLE(JIT)
    12251243protected:
    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 
    12311244    virtual void jettisonImpl();
    1232     virtual CompilationResult jitCompileImpl(ExecState*);
    12331245    virtual CodeBlock* replacement();
    12341246    virtual DFG::CapabilityLevel capabilityLevelInternal();
     
    12531265#if ENABLE(JIT)
    12541266protected:
    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 
    12601267    virtual void jettisonImpl();
    1261     virtual CompilationResult jitCompileImpl(ExecState*);
    12621268    virtual CodeBlock* replacement();
    12631269    virtual DFG::CapabilityLevel capabilityLevelInternal();
  • trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp

    r153778 r154804  
    5656}
    5757
    58 static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
     58CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
    5959{
    6060    SamplingRegion samplingRegion("DFG Compilation (Driver)");
     
    100100        numVarsWithValues = 0;
    101101    RefPtr<Plan> plan = adoptRef(
    102         new Plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
     102        new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
    103103    for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) {
    104104        int operand = plan->mustHandleValues.operandForIndex(i);
    105105        if (operandIsArgument(operand)
    106106            && !operandToArgument(operand)
    107             && compileMode == CompileFunction
     107            && codeBlock->codeType() == FunctionCode
    108108            && codeBlock->specializationKind() == CodeForConstruct) {
    109109            // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
     
    116116    }
    117117   
    118     if (enableConcurrentJIT()) {
     118    if (enableConcurrentJIT() && callback) {
     119        plan->callback = callback;
    119120        if (!vm.worklist)
    120121            vm.worklist = globalWorklist();
     
    126127   
    127128    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();
    144130}
    145131
  • trunk/Source/JavaScriptCore/dfg/DFGDriver.h

    r153216 r154804  
    4343
    4444#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);
     45CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>);
    4846#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 }
     47inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; }
    5648#endif
    5749
  • trunk/Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp

    r153161 r154804  
    4040}
    4141
    42 bool FailedFinalizer::finalize(RefPtr<JSC::JITCode>&)
     42bool FailedFinalizer::finalize()
    4343{
    4444    return false;
    4545}
    4646
    47 bool FailedFinalizer::finalizeFunction(RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&)
     47bool FailedFinalizer::finalizeFunction()
    4848{
    4949    return false;
  • trunk/Source/JavaScriptCore/dfg/DFGFailedFinalizer.h

    r153161 r154804  
    4040    virtual ~FailedFinalizer();
    4141   
    42     bool finalize(RefPtr<JSC::JITCode>& entry);
    43     bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
     42    bool finalize();
     43    bool finalizeFunction();
    4444};
    4545
  • trunk/Source/JavaScriptCore/dfg/DFGFinalizer.h

    r153161 r154804  
    4747    virtual ~Finalizer();
    4848   
    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;
    5151
    5252protected:
  • trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp

    r153165 r154804  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "CodeBlock.h"
    3132#include "DFGCommon.h"
    3233#include "DFGPlan.h"
     
    4647}
    4748
    48 bool JITFinalizer::finalize(RefPtr<JSC::JITCode>& entry)
     49bool JITFinalizer::finalize()
    4950{
    5051    finalizeCommon();
    5152   
    5253    m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
    53     entry = m_jitCode;
     54    m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr());
    5455   
    5556    return true;
    5657}
    5758
    58 bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
     59bool JITFinalizer::finalizeFunction()
    5960{
    6061    finalizeCommon();
    6162   
    62     withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
     63    MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
    6364    m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
    64     entry = m_jitCode;
     65    m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck);
    6566   
    6667    return true;
  • trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.h

    r153161 r154804  
    4343    virtual ~JITFinalizer();
    4444   
    45     bool finalize(RefPtr<JSC::JITCode>& entry);
    46     bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
     45    bool finalize();
     46    bool finalizeFunction();
    4747
    4848private:
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp

    r153123 r154804  
    3131#include "CodeBlock.h"
    3232#include "Executable.h"
     33#include "JITCode.h"
    3334#include "Operations.h"
    3435
     
    3738void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
    3839{
     40    DeferGC deferGC(exec->vm().heap);
     41   
    3942    for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
    4043        FunctionExecutable* executable =
     
    4346            codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
    4447       
    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();
    4655    }
    4756}
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r154797 r154804  
    12821282    else {
    12831283        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    1284         JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
     1284        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
    12851285        if (error) {
    12861286            vm->throwException(exec, createStackOverflowError(exec));
     
    13271327    if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
    13281328        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    1329         JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
     1329        JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind);
    13301330        if (error) {
    13311331            exec->vm().throwException(execCallee, error);
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r154468 r154804  
    8181
    8282Plan::Plan(
    83     CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
     83    PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
    8484    unsigned numVarsWithValues)
    85     : compileMode(compileMode)
    86     , vm(*passedCodeBlock->vm())
     85    : vm(*passedCodeBlock->vm())
    8786    , codeBlock(passedCodeBlock)
    8887    , osrEntryBytecodeIndex(osrEntryBytecodeIndex)
     
    209208#if ENABLE(FTL_JIT)
    210209    if (Options::useExperimentalFTL()
    211         && compileMode == CompileFunction
     210        && codeBlock->codeType() == FunctionCode
    212211        && FTL::canCompile(dfg)) {
    213212       
     
    256255
    257256    JITCompiler dataFlowJIT(dfg);
    258     if (compileMode == CompileFunction) {
     257    if (codeBlock->codeType() == FunctionCode) {
    259258        dataFlowJIT.compileFunction();
    260259        dataFlowJIT.linkFunction();
    261260    } else {
    262         ASSERT(compileMode == CompileOther);
    263        
    264261        dataFlowJIT.compile();
    265262        dataFlowJIT.link();
     
    284281}
    285282
    286 CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
     283void Plan::notifyReady()
     284{
     285    callback->compilationDidBecomeReadyAsynchronously(codeBlock.get());
     286    isCompiled = true;
     287}
     288
     289CompilationResult Plan::finalizeWithoutNotifyingCallback()
    287290{
    288291    if (!isStillValid())
     
    290293   
    291294    bool result;
    292     if (compileMode == CompileFunction)
    293         result = finalizer->finalizeFunction(jitCode, *jitCodeWithArityCheck);
     295    if (codeBlock->codeType() == FunctionCode)
     296        result = finalizer->finalizeFunction();
    294297    else
    295         result = finalizer->finalize(jitCode);
     298        result = finalizer->finalize();
    296299   
    297300    if (!result)
    298301        return CompilationFailed;
    299302   
    300     reallyAdd(jitCode->dfgCommon());
     303    reallyAdd(codeBlock->jitCode()->dfgCommon());
    301304   
    302305    return CompilationSuccessful;
    303306}
    304307
     308void Plan::finalizeAndNotifyCallback()
     309{
     310    callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback());
     311}
     312
    305313CodeBlock* Plan::key()
    306314{
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.h

    r154162 r154804  
    3737#include "DFGDesiredWriteBarriers.h"
    3838#include "DFGFinalizer.h"
     39#include "DeferredCompilationCallback.h"
    3940#include "Operands.h"
    4041#include "ProfilerCompilation.h"
     
    4950class LongLivedState;
    5051
    51 enum CompileMode { CompileFunction, CompileOther };
    52 
    5352#if ENABLE(DFG_JIT)
    5453
    5554struct Plan : public ThreadSafeRefCounted<Plan> {
    5655    Plan(
    57         CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock,
    58         unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
     56        PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
    5957    ~Plan();
    6058   
    6159    void compileInThread(LongLivedState&);
    6260   
    63     CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck);
     61    CompilationResult finalizeWithoutNotifyingCallback();
     62    void finalizeAndNotifyCallback();
     63   
     64    void notifyReady();
    6465   
    6566    CodeBlock* key();
    6667   
    67     const CompileMode compileMode;
    6868    VM& vm;
    6969    RefPtr<CodeBlock> codeBlock;
     
    8787    bool isCompiled;
    8888
     89    RefPtr<DeferredCompilationCallback> callback;
     90
    8991private:
    9092    enum CompilationPath { FailPath, DFGPath, FTLPath };
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r154403 r154804  
    38383838        }
    38393839       
    3840         if (isCellSpeculation(node->child1()->prediction())) {
     3840        switch (node->child1().useKind()) {
     3841        case CellUse: {
    38413842            SpeculateCellOperand base(this, node->child1());
    38423843            GPRTemporary resultTag(this, base);
     
    38553856        }
    38563857       
    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        }
    38733882        break;
    38743883    }
  • trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp

    r153321 r154804  
    166166        RELEASE_ASSERT(plan->isCompiled);
    167167       
    168         CompilationResult compilationResult =
    169             profiledBlock->replaceWithDeferredOptimizedCode(plan);
    170         RELEASE_ASSERT(compilationResult != CompilationDeferred);
    171         profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult);
     168        plan->finalizeAndNotifyCallback();
    172169       
    173170        if (profiledBlock == requestedProfiledBlock)
     
    244241        {
    245242            MutexLocker locker(m_lock);
    246             plan->key()->forceOptimizationSlowPathConcurrently();
    247             plan->isCompiled = true;
     243            plan->notifyReady();
    248244           
    249245            if (Options::verboseCompilationQueue()) {
  • trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp

    r153172 r154804  
    4545}
    4646
    47 bool JITFinalizer::finalize(RefPtr<JSC::JITCode>&)
     47bool JITFinalizer::finalize()
    4848{
    4949    RELEASE_ASSERT_NOT_REACHED();
     
    5151}
    5252
    53 bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
     53bool JITFinalizer::finalizeFunction()
    5454{
    5555    for (unsigned i = m_jitCode->handles().size(); i--;) {
     
    6565    } // else this function had no OSR exits, so no exit thunks.
    6666   
    67     withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
     67    MacroAssemblerCodePtr withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
    6868    m_jitCode->initializeCode(
    6969        FINALIZE_DFG_CODE(
    7070            *m_entrypointLinkBuffer,
    7171            ("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);
    7374   
    7475    return true;
  • trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h

    r153256 r154804  
    6666    }
    6767   
    68     bool finalize(RefPtr<JSC::JITCode>& entry);
    69     bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
     68    bool finalize();
     69    bool finalizeFunction();
    7070
    7171private:
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r154471 r154804  
    185185       
    186186        void addReference(JSCell*, ArrayBuffer*);
     187       
     188        bool isDeferred() const { return !!m_deferralDepth; }
    187189
    188190    private:
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r154797 r154804  
    735735        return checkedReturn(callFrame->vm().throwException(callFrame, error));
    736736
    737     if (JSObject* error = program->compile(callFrame, scope))
     737    if (JSObject* error = program->prepareForExecution(callFrame, scope, CodeForCall))
    738738        return checkedReturn(callFrame->vm().throwException(callFrame, error));
    739739
     
    804804    if (isJSCall) {
    805805        // Compile the callee:
    806         JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope);
     806        JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
    807807        if (UNLIKELY(!!compileError)) {
    808808            return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
     
    883883    if (isJSConstruct) {
    884884        // Compile the callee:
    885         JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope);
     885        JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct);
    886886        if (UNLIKELY(!!compileError)) {
    887887            return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
     
    957957
    958958    // Compile the callee:
    959     JSObject* error = functionExecutable->compileForCall(callFrame, scope);
     959    JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
    960960    if (error) {
    961961        callFrame->vm().throwException(callFrame, error);
     
    10731073    }
    10741074
    1075     JSObject* compileError = eval->compile(callFrame, scope);
     1075    JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall);
    10761076    if (UNLIKELY(!!compileError))
    10771077        return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r154797 r154804  
    5252#include "JIT.h"
    5353#include "JITExceptions.h"
     54#include "JITToDFGDeferredCompilationCallback.h"
    5455#include "JSActivation.h"
    5556#include "JSArray.h"
     
    9991000            dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
    10001001        // If we have an optimized replacement, then it must be the case that we entered
    1001         // cti_optimize from a loop. That's because is there's an optimized replacement,
     1002        // cti_optimize from a loop. That's because if there's an optimized replacement,
    10021003        // then all calls to this function will be relinked to the replacement and so
    10031004        // the prologue OSR will never fire.
     
    10331034            dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
    10341035       
    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);
    10431041       
    1044         codeBlock->setOptimizationThresholdBasedOnCompilationResult(result);
    10451042        if (result != CompilationSuccessful)
    10461043            return;
     
    11691166    FunctionExecutable* executable = function->jsExecutable();
    11701167    JSScope* callDataScopeChain = function->scope();
    1171     JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
     1168    JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind);
    11721169    if (!error)
    11731170        return function;
     
    12681265    else {
    12691266        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)) {
    12711268            callFrame->vm().throwException(callFrame, error);
    12721269            return 0;
     
    13451342        FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
    13461343        JSScope* scopeChain = callee->scope();
    1347         JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
     1344        JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall);
    13481345        if (error) {
    13491346            callFrame->vm().throwException(callFrame, error);
  • trunk/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp

    r153113 r154804  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if ENABLE(LLINT)
    3030
     31#include "CodeBlock.h"
    3132#include "JITCode.h"
    32 #include "VM.h"
    3333#include "JSObject.h"
    3434#include "LLIntThunks.h"
    3535#include "LowLevelInterpreter.h"
     36#include "VM.h"
    3637
    3738
    3839namespace JSC { namespace LLInt {
    3940
    40 void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck)
     41void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
    4142{
     43    CodeSpecializationKind kind = codeBlock->specializationKind();
     44   
    4245    if (!vm.canUseJIT()) {
    4346        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));
    4650            return;
    4751        }
    4852
    4953        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));
    5257        return;
    5358    }
     
    5560#if ENABLE(JIT)
    5661    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());
    5965        return;
    6066    }
    6167
    6268    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());
    6572#endif // ENABLE(JIT)
    6673}
    6774
    68 void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
     75void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
    6976{
    7077    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());
    7281        return;
    7382    }
    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());
    7687#endif
    7788}
    7889
    79 void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
     90void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
    8091{
    8192    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());
    8396        return;
    8497    }
    8598#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());
    87102#endif
    88103}
  • trunk/Source/JavaScriptCore/llint/LLIntEntrypoints.h

    r153113 r154804  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838
    3939class EvalCodeBlock;
     40class FunctionCodeBlock;
    4041class VM;
    4142class MacroAssemblerCodePtr;
     
    4546namespace LLInt {
    4647
    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 }
     48void setFunctionEntrypoint(VM&, FunctionCodeBlock*);
     49void setEvalEntrypoint(VM&, EvalCodeBlock*);
     50void setProgramEntrypoint(VM&, ProgramCodeBlock*);
    6051
    6152} } // namespace JSC::LLInt
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r154797 r154804  
    3838#include "Interpreter.h"
    3939#include "JIT.h"
    40 #include "JITDriver.h"
    4140#include "JSActivation.h"
    4241#include "JSCJSValue.h"
     
    281280inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
    282281{
     282    DeferGC deferGC(exec->vm().heap);
     283   
    283284    codeBlock->updateAllValueProfilePredictions();
    284285   
     
    289290    }
    290291   
    291     CompilationResult result = codeBlock->jitCompile(exec);
    292     switch (result) {
    293     case CompilationNotNeeded:
     292    switch (codeBlock->jitType()) {
     293    case JITCode::BaselineJIT: {
    294294        if (Options::verboseOSR())
    295295            dataLogF("    Code was already compiled.\n");
    296296        codeBlock->jitSoon();
    297297        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    }
    308319    default:
    309320        RELEASE_ASSERT_NOT_REACHED();
     
    10051016    else {
    10061017        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    1007         JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
     1018        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
    10081019        if (error)
    10091020            LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r154373 r154804  
    7979    FunctionExecutable* executable = callData.js.functionExecutable;
    8080
    81     JSObject* error = executable->compileForCall(exec, callData.js.scope);
     81    JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall);
    8282    if (error)
    8383        return false;
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r154797 r154804  
    3838#include "Interpreter.h"
    3939#include "JIT.h"
    40 #include "JITDriver.h"
    4140#include "JITStubs.h"
    4241#include "JSActivation.h"
  • trunk/Source/JavaScriptCore/runtime/CompilationResult.cpp

    r153165 r154804  
    4343        out.print("CompilationSuccessful");
    4444        return;
    45     case CompilationNotNeeded:
    46         out.print("CompilationNotNeeded");
    47         return;
    4845    case CompilationDeferred:
    4946        out.print("CompilationDeferred");
  • trunk/Source/JavaScriptCore/runtime/CompilationResult.h

    r153165 r154804  
    3131namespace JSC {
    3232
    33 enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred };
     33enum 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};
    3461
    3562} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r154797 r154804  
    11/*
    2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "CodeBlock.h"
    3232#include "DFGDriver.h"
    33 #include "ExecutionHarness.h"
    3433#include "JIT.h"
    35 #include "JITDriver.h"
    3634#include "Operations.h"
    3735#include "Parser.h"
     
    115113#endif
    116114
     115void 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
     195PassRefPtr<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
     245PassRefPtr<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
     274JSObject* 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
    117299const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
    118300
     
    176358    static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
    177359}
    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     else
    188         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 #endif
    200360
    201361inline const char* samplingDescription(JITCode::JITType jitType)
     
    216376}
    217377
    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 
    251378#if ENABLE(JIT)
    252379void EvalExecutable::jettisonOptimizedCode(VM& vm)
     
    299426}
    300427
    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     else
    310         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 #endif
    322 
    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 
    355428#if ENABLE(JIT)
    356429void ProgramExecutable::jettisonOptimizedCode(VM& vm)
     
    444517    return result;
    445518}
    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     else
    456         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     else
    469         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 #endif
    486 
    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)
    581519
    582520#if ENABLE(JIT)
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r154632 r154804  
    162162    }
    163163       
     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
    164181    bool hasJITCodeForCall() const
    165182    {
     
    179196        return hasJITCodeForConstruct();
    180197    }
    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)
    198198
    199199    // Intrinsics are only for calls, currently.
     
    245245#endif
    246246    }
     247   
    247248#endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
    248249
     
    403404    }
    404405
     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
     417private:
     418    JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind);
     419
    405420protected:
    406421    void finishCreation(VM& vm)
     
    431446    static void destroy(JSCell*);
    432447
    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        
    448448#if ENABLE(JIT)
    449449    void jettisonOptimizedCode(VM&);
    450     CompilationResult jitCompile(ExecState*);
    451450#endif
    452451
     
    482481
    483482private:
     483    friend class ScriptExecutable;
    484484    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
    485485    EvalExecutable(ExecState*, const SourceCode&, bool);
    486486
    487     JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
    488487    static void visitChildren(JSCell*, SlotVisitor&);
    489488
     
    509508    static void destroy(JSCell*);
    510509
    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        
    526510#if ENABLE(JIT)
    527511    void jettisonOptimizedCode(VM&);
    528     CompilationResult jitCompile(ExecState*);
    529512#endif
    530513
     
    558541
    559542private:
     543    friend class ScriptExecutable;
     544   
    560545    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
    561546
    562547    ProgramExecutable(ExecState*, const SourceCode&);
    563548
    564     JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
    565549    static void visitChildren(JSCell*, SlotVisitor&);
    566550
     
    601585    }
    602586       
    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        
    620587#if ENABLE(JIT)
    621588    void jettisonOptimizedCodeForCall(VM&);
    622     CompilationResult jitCompileForCall(ExecState*);
    623589#endif
    624590
     
    634600    }
    635601
    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        
    651602#if ENABLE(JIT)
    652603    void jettisonOptimizedCodeForConstruct(VM&);
    653     CompilationResult jitCompileForConstruct(ExecState*);
    654604#endif
    655605
     
    665615    }
    666616       
    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 
    700617#if ENABLE(JIT)
    701618    void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
     
    708625        }
    709626    }
    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     }
    718627#endif
    719628       
     
    765674    FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
    766675
    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        
    770676    RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
    771677    {
     
    786692        return false;
    787693    }
     694
     695    friend class ScriptExecutable;
    788696
    789697    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
Note: See TracChangeset for help on using the changeset viewer.