CodeBlock compilation and installation should be simplified and rationalized
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Aug 2013 04:03:05 +0000 (04:03 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Aug 2013 04:03:05 +0000 (04:03 +0000)
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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@154804 268f45cc-cd09-0410-ab3c-d52691b4dbfc

41 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp [new file with mode: 0644]
Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h [new file with mode: 0644]
Source/JavaScriptCore/dfg/DFGDriver.cpp
Source/JavaScriptCore/dfg/DFGDriver.h
Source/JavaScriptCore/dfg/DFGFailedFinalizer.cpp
Source/JavaScriptCore/dfg/DFGFailedFinalizer.h
Source/JavaScriptCore/dfg/DFGFinalizer.h
Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp
Source/JavaScriptCore/dfg/DFGJITFinalizer.h
Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/dfg/DFGPlan.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGWorklist.cpp
Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp
Source/JavaScriptCore/ftl/FTLJITFinalizer.h
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITDriver.h [deleted file]
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp [new file with mode: 0644]
Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h [new file with mode: 0644]
Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
Source/JavaScriptCore/llint/LLIntEntrypoints.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CompilationResult.cpp
Source/JavaScriptCore/runtime/CompilationResult.h
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/ExecutionHarness.h [deleted file]

index 9979c17..178db81 100644 (file)
@@ -53,6 +53,7 @@ set(JavaScriptCore_SOURCES
     bytecode/CodeOrigin.cpp
     bytecode/CodeType.cpp
     bytecode/DFGExitProfile.cpp
     bytecode/CodeOrigin.cpp
     bytecode/CodeType.cpp
     bytecode/DFGExitProfile.cpp
+    bytecode/DeferredCompilationCallback.cpp
     bytecode/ExecutionCounter.cpp
     bytecode/ExitKind.cpp
     bytecode/GetByIdStatus.cpp
     bytecode/ExecutionCounter.cpp
     bytecode/ExitKind.cpp
     bytecode/GetByIdStatus.cpp
@@ -243,6 +244,7 @@ set(JavaScriptCore_SOURCES
     jit/JITStubRoutine.cpp
     jit/JITStubs.cpp
     jit/JITThunks.cpp
     jit/JITStubRoutine.cpp
     jit/JITStubs.cpp
     jit/JITThunks.cpp
+    jit/JITToDFGDeferredCompilationCallback.cpp
     jit/JumpReplacementWatchpoint.cpp
     jit/ThunkGenerators.cpp
 
     jit/JumpReplacementWatchpoint.cpp
     jit/ThunkGenerators.cpp
 
index cea0ab6..5baee7e 100644 (file)
@@ -1,3 +1,180 @@
+2013-08-28  Filip Pizlo  <fpizlo@apple.com>
+
+        CodeBlock compilation and installation should be simplified and rationalized
+        https://bugs.webkit.org/show_bug.cgi?id=120326
+
+        Reviewed by 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.
+
 2013-08-28  Chris Curtis  <chris_curtis@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=119548
 2013-08-28  Chris Curtis  <chris_curtis@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=119548
index d4a8edc..2aeddb1 100644 (file)
@@ -113,9 +113,11 @@ javascriptcore_sources += \
        Source/JavaScriptCore/bytecode/CodeBlockWithJITType.h \
        Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
        Source/JavaScriptCore/bytecode/CodeOrigin.h \
        Source/JavaScriptCore/bytecode/CodeBlockWithJITType.h \
        Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
        Source/JavaScriptCore/bytecode/CodeOrigin.h \
-       Source/JavaScriptCore/bytecode/DataFormat.h \
        Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \
        Source/JavaScriptCore/bytecode/DFGExitProfile.h \
        Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \
        Source/JavaScriptCore/bytecode/DFGExitProfile.h \
+       Source/JavaScriptCore/bytecode/DataFormat.h \
+       Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp \
+       Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h \
        Source/JavaScriptCore/bytecode/EvalCodeCache.h \
        Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
        Source/JavaScriptCore/bytecode/ExecutionCounter.h \
        Source/JavaScriptCore/bytecode/EvalCodeCache.h \
        Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
        Source/JavaScriptCore/bytecode/ExecutionCounter.h \
@@ -604,7 +606,6 @@ javascriptcore_sources += \
        Source/JavaScriptCore/jit/JITCompilationEffort.h \
        Source/JavaScriptCore/jit/JITDisassembler.cpp \
        Source/JavaScriptCore/jit/JITDisassembler.h \
        Source/JavaScriptCore/jit/JITCompilationEffort.h \
        Source/JavaScriptCore/jit/JITDisassembler.cpp \
        Source/JavaScriptCore/jit/JITDisassembler.h \
-       Source/JavaScriptCore/jit/JITDriver.h \
        Source/JavaScriptCore/jit/JIT.cpp \
        Source/JavaScriptCore/jit/JIT.h \
        Source/JavaScriptCore/jit/JITExceptions.cpp \
        Source/JavaScriptCore/jit/JIT.cpp \
        Source/JavaScriptCore/jit/JIT.h \
        Source/JavaScriptCore/jit/JITExceptions.cpp \
@@ -628,6 +629,8 @@ javascriptcore_sources += \
        Source/JavaScriptCore/jit/JITStubsX86Common.h \
        Source/JavaScriptCore/jit/JITThunks.cpp \
        Source/JavaScriptCore/jit/JITThunks.h \
        Source/JavaScriptCore/jit/JITStubsX86Common.h \
        Source/JavaScriptCore/jit/JITThunks.cpp \
        Source/JavaScriptCore/jit/JITThunks.h \
+       Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp \
+       Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h \
        Source/JavaScriptCore/jit/JITWriteBarrier.h \
        Source/JavaScriptCore/jit/JSInterfaceJIT.h \
        Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp \
        Source/JavaScriptCore/jit/JITWriteBarrier.h \
        Source/JavaScriptCore/jit/JSInterfaceJIT.h \
        Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp \
@@ -783,7 +786,6 @@ javascriptcore_sources += \
        Source/JavaScriptCore/runtime/ExceptionHelpers.h \
        Source/JavaScriptCore/runtime/Executable.cpp \
        Source/JavaScriptCore/runtime/Executable.h \
        Source/JavaScriptCore/runtime/ExceptionHelpers.h \
        Source/JavaScriptCore/runtime/Executable.cpp \
        Source/JavaScriptCore/runtime/Executable.h \
-       Source/JavaScriptCore/runtime/ExecutionHarness.h \
        Source/JavaScriptCore/runtime/Float32Array.h \
        Source/JavaScriptCore/runtime/Float64Array.h \
        Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
        Source/JavaScriptCore/runtime/Float32Array.h \
        Source/JavaScriptCore/runtime/Float64Array.h \
        Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
index 5eddb98..9f1d9ef 100644 (file)
     <ClCompile Include="..\bytecode\CodeBlockHash.cpp" />\r
     <ClCompile Include="..\bytecode\CodeOrigin.cpp" />\r
     <ClCompile Include="..\bytecode\CodeType.cpp" />\r
     <ClCompile Include="..\bytecode\CodeBlockHash.cpp" />\r
     <ClCompile Include="..\bytecode\CodeOrigin.cpp" />\r
     <ClCompile Include="..\bytecode\CodeType.cpp" />\r
+    <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" />\r
     <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />\r
     <ClCompile Include="..\bytecode\ExitKind.cpp" />\r
     <ClCompile Include="..\bytecode\GetByIdStatus.cpp" />\r
     <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />\r
     <ClCompile Include="..\bytecode\ExitKind.cpp" />\r
     <ClCompile Include="..\bytecode\GetByIdStatus.cpp" />\r
     <ClCompile Include="..\jit\JITStubRoutine.cpp" />\r
     <ClCompile Include="..\jit\JITStubs.cpp" />\r
     <ClCompile Include="..\jit\JITThunks.cpp" />\r
     <ClCompile Include="..\jit\JITStubRoutine.cpp" />\r
     <ClCompile Include="..\jit\JITStubs.cpp" />\r
     <ClCompile Include="..\jit\JITThunks.cpp" />\r
+    <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />\r
     <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" />\r
     <ClCompile Include="..\jit\ThunkGenerators.cpp" />\r
     <ClCompile Include="..\llint\LLIntCLoop.cpp" />\r
     <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" />\r
     <ClCompile Include="..\jit\ThunkGenerators.cpp" />\r
     <ClCompile Include="..\llint\LLIntCLoop.cpp" />\r
     <ClInclude Include="..\bytecode\CodeType.h" />\r
     <ClInclude Include="..\bytecode\Comment.h" />\r
     <ClInclude Include="..\bytecode\DataFormat.h" />\r
     <ClInclude Include="..\bytecode\CodeType.h" />\r
     <ClInclude Include="..\bytecode\Comment.h" />\r
     <ClInclude Include="..\bytecode\DataFormat.h" />\r
+    <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" />\r
     <ClInclude Include="..\bytecode\EvalCodeCache.h" />\r
     <ClInclude Include="..\bytecode\ExecutionCounter.h" />\r
     <ClInclude Include="..\bytecode\ExitKind.h" />\r
     <ClInclude Include="..\bytecode\EvalCodeCache.h" />\r
     <ClInclude Include="..\bytecode\ExecutionCounter.h" />\r
     <ClInclude Include="..\bytecode\ExitKind.h" />\r
     <ClInclude Include="..\jit\JITCode.h" />\r
     <ClInclude Include="..\jit\JITCompilationEffort.h" />\r
     <ClInclude Include="..\jit\JITDisassembler.h" />\r
     <ClInclude Include="..\jit\JITCode.h" />\r
     <ClInclude Include="..\jit\JITCompilationEffort.h" />\r
     <ClInclude Include="..\jit\JITDisassembler.h" />\r
-    <ClInclude Include="..\jit\JITDriver.h" />\r
     <ClInclude Include="..\jit\JITExceptions.h" />\r
     <ClInclude Include="..\jit\JITInlines.h" />\r
     <ClInclude Include="..\jit\JITStubCall.h" />\r
     <ClInclude Include="..\jit\JITExceptions.h" />\r
     <ClInclude Include="..\jit\JITInlines.h" />\r
     <ClInclude Include="..\jit\JITStubCall.h" />\r
     <ClInclude Include="..\jit\JITStubsX86Common.h" />\r
     <ClInclude Include="..\jit\JITStubsX86_64.h" />\r
     <ClInclude Include="..\jit\JITThunks.h" />\r
     <ClInclude Include="..\jit\JITStubsX86Common.h" />\r
     <ClInclude Include="..\jit\JITStubsX86_64.h" />\r
     <ClInclude Include="..\jit\JITThunks.h" />\r
+    <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" />\r
     <ClInclude Include="..\jit\JITWriteBarrier.h" />\r
     <ClInclude Include="..\jit\JSInterfaceJIT.h" />\r
     <ClInclude Include="..\jit\JumpReplacementWatchpoint.h" />\r
     <ClInclude Include="..\jit\JITWriteBarrier.h" />\r
     <ClInclude Include="..\jit\JSInterfaceJIT.h" />\r
     <ClInclude Include="..\jit\JumpReplacementWatchpoint.h" />\r
     <ClInclude Include="..\runtime\ErrorPrototype.h" />\r
     <ClInclude Include="..\runtime\ExceptionHelpers.h" />\r
     <ClInclude Include="..\runtime\Executable.h" />\r
     <ClInclude Include="..\runtime\ErrorPrototype.h" />\r
     <ClInclude Include="..\runtime\ExceptionHelpers.h" />\r
     <ClInclude Include="..\runtime\Executable.h" />\r
-    <ClInclude Include="..\runtime\ExecutionHarness.h" />\r
     <ClInclude Include="..\runtime\Float32Array.h" />\r
     <ClInclude Include="..\runtime\Float64Array.h" />\r
     <ClInclude Include="..\runtime\FunctionConstructor.h" />\r
     <ClInclude Include="..\runtime\Float32Array.h" />\r
     <ClInclude Include="..\runtime\Float64Array.h" />\r
     <ClInclude Include="..\runtime\FunctionConstructor.h" />\r
index 2b6ea3e..9f7112b 100644 (file)
@@ -86,8 +86,6 @@
                0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F235BD117178E1C00690C7F /* FTLCArgumentGetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */; };
                0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F235BD117178E1C00690C7F /* FTLCArgumentGetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */; };
                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */; };
                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
                0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */; };
                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
                0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; };
+               0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; };
+               0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
                0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
                0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoubleFormatState.h; path = dfg/DFGDoubleFormatState.h; sourceTree = "<group>"; };
                0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; };
                0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSilentRegisterSavePlan.h; path = dfg/DFGSilentRegisterSavePlan.h; sourceTree = "<group>"; };
                0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoubleFormatState.h; path = dfg/DFGDoubleFormatState.h; sourceTree = "<group>"; };
                0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; };
                0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSilentRegisterSavePlan.h; path = dfg/DFGSilentRegisterSavePlan.h; sourceTree = "<group>"; };
-               0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
                0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
                0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
-               0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
                0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; };
                0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLCArgumentGetter.h; path = ftl/FTLCArgumentGetter.h; sourceTree = "<group>"; };
                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
                0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; };
                0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLCArgumentGetter.h; path = ftl/FTLCArgumentGetter.h; sourceTree = "<group>"; };
                0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler.cpp; path = dfg/DFGOSRExitCompiler.cpp; sourceTree = "<group>"; };
                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
                0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
                0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler.cpp; path = dfg/DFGOSRExitCompiler.cpp; sourceTree = "<group>"; };
                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
                0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
+               0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; };
+               0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; };
+               0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; };
+               0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JITToDFGDeferredCompilationCallback.h; sourceTree = "<group>"; };
                0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
                0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
                0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; };
                0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
                0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
                0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; };
                                0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
                                0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
                                0FAF7EFB165BA919000C8455 /* JITDisassembler.h */,
                                0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
                                0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
                                0FAF7EFB165BA919000C8455 /* JITDisassembler.h */,
-                               0F21C26614BE5F5E00ADC64B /* JITDriver.h */,
                                0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
                                0F46808014BA572700BFE272 /* JITExceptions.h */,
                                86CC85A00EE79A4700288682 /* JITInlines.h */,
                                0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
                                0F46808014BA572700BFE272 /* JITExceptions.h */,
                                86CC85A00EE79A4700288682 /* JITInlines.h */,
                                A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */,
                                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
                                0F5EF91C16878F78003E5C25 /* JITThunks.h */,
                                A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */,
                                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
                                0F5EF91C16878F78003E5C25 /* JITThunks.h */,
+                               0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */,
+                               0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
                                0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */,
                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
                                0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */,
                                A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
                                86CA032D1038E8440028A609 /* Executable.cpp */,
                                86CAFEE21035DDE60028A609 /* Executable.h */,
                                A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
                                86CA032D1038E8440028A609 /* Executable.cpp */,
                                86CAFEE21035DDE60028A609 /* Executable.h */,
-                               0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
                                A7A8AF2917ADB5F3005AB174 /* Float32Array.h */,
                                A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */,
                                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
                                A7A8AF2917ADB5F3005AB174 /* Float32Array.h */,
                                A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */,
                                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
                                0F8F943F1667632D00D61971 /* CodeType.cpp */,
                                0F0B83A514BCF50400885B4F /* CodeType.h */,
                                0F426A4A1460CD6B00131F8F /* DataFormat.h */,
                                0F8F943F1667632D00D61971 /* CodeType.cpp */,
                                0F0B83A514BCF50400885B4F /* CodeType.h */,
                                0F426A4A1460CD6B00131F8F /* DataFormat.h */,
+                               0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
+                               0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
                                0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
                                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
                                969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
                                0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
                                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
                                969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
                                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
                                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
                                0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
                                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
                                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
                                0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
+                               0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */,
                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
                                BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
                                BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
                                86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
                                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
                                0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
                                86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
                                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
                                0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
-                               0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
                                0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
                                0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
                                A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
                                0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
                                0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
                                A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
                                86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
                                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
                                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
                                86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
                                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
                                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
-                               0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
                                0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
                                86CC85A10EE79A4700288682 /* JITInlines.h in Headers */,
                                960626960FB8EC02009798AB /* JITStubCall.h in Headers */,
                                0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
                                86CC85A10EE79A4700288682 /* JITInlines.h in Headers */,
                                960626960FB8EC02009798AB /* JITStubCall.h in Headers */,
                                BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
                                BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
                                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
                                BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
                                BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
                                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
+                               0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */,
                                A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
                                BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */,
                                9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
                                A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
                                BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */,
                                9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
                                0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
                                148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
                                93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
                                0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
                                148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
                                93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
+                               0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
                                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
                                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
                                95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
                                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
                                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
                                95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
                                14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
                                14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
+                               0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
                                0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */,
                                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
                                A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
                                0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */,
                                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
                                A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
index 71a2f9e..143f038 100644 (file)
@@ -61,6 +61,7 @@ SOURCES += \
     bytecode/CodeOrigin.cpp \
     bytecode/CodeType.cpp \
     bytecode/DFGExitProfile.cpp \
     bytecode/CodeOrigin.cpp \
     bytecode/CodeType.cpp \
     bytecode/DFGExitProfile.cpp \
+    bytecode/DeferredCompilationCallback.cpp \
     bytecode/ExecutionCounter.cpp \
     bytecode/ExitKind.cpp \
     bytecode/GetByIdStatus.cpp \
     bytecode/ExecutionCounter.cpp \
     bytecode/ExitKind.cpp \
     bytecode/GetByIdStatus.cpp \
@@ -221,6 +222,7 @@ SOURCES += \
     jit/JITStubRoutine.cpp \
     jit/JITStubs.cpp \
     jit/JITThunks.cpp \
     jit/JITStubRoutine.cpp \
     jit/JITStubs.cpp \
     jit/JITThunks.cpp \
+    jit/JITToDFGDeferredCompilationCallback.cpp \
     jit/JumpReplacementWatchpoint.cpp \
     jit/ThunkGenerators.cpp \
     llint/LLIntCLoop.cpp \
     jit/JumpReplacementWatchpoint.cpp \
     jit/ThunkGenerators.cpp \
     llint/LLIntCLoop.cpp \
index 7925fab..3f457ae 100644 (file)
@@ -34,6 +34,7 @@
 #include "CallLinkStatus.h"
 #include "DFGCapabilities.h"
 #include "DFGCommon.h"
 #include "CallLinkStatus.h"
 #include "DFGCapabilities.h"
 #include "DFGCommon.h"
+#include "DFGDriver.h"
 #include "DFGNode.h"
 #include "DFGRepatch.h"
 #include "DFGWorklist.h"
 #include "DFGNode.h"
 #include "DFGRepatch.h"
 #include "DFGWorklist.h"
@@ -45,6 +46,7 @@
 #include "JSCJSValue.h"
 #include "JSFunction.h"
 #include "JSNameScope.h"
 #include "JSCJSValue.h"
 #include "JSFunction.h"
 #include "JSNameScope.h"
+#include "LLIntEntrypoints.h"
 #include "LowLevelInterpreter.h"
 #include "Operations.h"
 #include "PolymorphicPutByIdList.h"
 #include "LowLevelInterpreter.h"
 #include "Operations.h"
 #include "PolymorphicPutByIdList.h"
@@ -2536,20 +2538,22 @@ void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming)
     noticeIncomingCall(callerFrame);
     m_incomingCalls.push(incoming);
 }
     noticeIncomingCall(callerFrame);
     m_incomingCalls.push(incoming);
 }
+#endif // ENABLE(JIT)
 
 void CodeBlock::unlinkIncomingCalls()
 {
 #if ENABLE(LLINT)
     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
         m_incomingLLIntCalls.begin()->unlink();
 
 void CodeBlock::unlinkIncomingCalls()
 {
 #if ENABLE(LLINT)
     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
         m_incomingLLIntCalls.begin()->unlink();
-#endif
+#endif // ENABLE(LLINT)
+#if ENABLE(JIT)
     if (m_incomingCalls.isEmpty())
         return;
     RepatchBuffer repatchBuffer(this);
     while (m_incomingCalls.begin() != m_incomingCalls.end())
         m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
     if (m_incomingCalls.isEmpty())
         return;
     RepatchBuffer repatchBuffer(this);
     while (m_incomingCalls.begin() != m_incomingCalls.end())
         m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
-}
 #endif // ENABLE(JIT)
 #endif // ENABLE(JIT)
+}
 
 #if ENABLE(LLINT)
 void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
 
 #if ENABLE(LLINT)
 void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
@@ -2689,78 +2693,108 @@ void CodeBlock::copyPostParseDataFromAlternative()
     copyPostParseDataFrom(m_alternative.get());
 }
 
     copyPostParseDataFrom(m_alternative.get());
 }
 
-#if ENABLE(JIT)
-void CodeBlock::reoptimize()
-{
-    ASSERT(replacement() != this);
-    ASSERT(replacement()->alternative() == this);
-    if (DFG::shouldShowDisassembly())
-        dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
-    replacement()->jettison();
-    countReoptimization();
-}
-
-CodeBlock* ProgramCodeBlock::replacement()
+CompilationResult CodeBlock::prepareForExecutionImpl(
+    ExecState* exec, JITCode::JITType jitType, JITCompilationEffort effort,
+    unsigned bytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
 {
 {
-    return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
+    VM& vm = exec->vm();
+    
+    if (jitType == JITCode::InterpreterThunk) {
+        switch (codeType()) {
+        case GlobalCode:
+            LLInt::setProgramEntrypoint(vm, static_cast<ProgramCodeBlock*>(this));
+            break;
+        case EvalCode:
+            LLInt::setEvalEntrypoint(vm, static_cast<EvalCodeBlock*>(this));
+            break;
+        case FunctionCode:
+            LLInt::setFunctionEntrypoint(vm, static_cast<FunctionCodeBlock*>(this));
+            break;
+        }
+        return CompilationSuccessful;
+    }
+    
+#if ENABLE(JIT)
+    if (JITCode::isOptimizingJIT(jitType)) {
+        ASSERT(effort == JITCompilationCanFail);
+        bool hadCallback = !!callback;
+        CompilationResult result = DFG::tryCompile(exec, this, bytecodeIndex, callback);
+        ASSERT_UNUSED(hadCallback, result != CompilationDeferred || hadCallback);
+        return result;
+    }
+    
+    MacroAssemblerCodePtr jitCodeWithArityCheck;
+    RefPtr<JITCode> jitCode = JIT::compile(&vm, this, effort, &jitCodeWithArityCheck);
+    if (!jitCode)
+        return CompilationFailed;
+    setJITCode(jitCode, jitCodeWithArityCheck);
+    return CompilationSuccessful;
+#else
+    UNUSED_PARAM(effort);
+    UNUSED_PARAM(bytecodeIndex);
+    UNUSED_PARAM(callback);
+    return CompilationFailed;
+#endif // ENABLE(JIT)
 }
 
 }
 
-CodeBlock* EvalCodeBlock::replacement()
+CompilationResult CodeBlock::prepareForExecution(
+    ExecState* exec, JITCode::JITType jitType,
+    JITCompilationEffort effort, unsigned bytecodeIndex)
 {
 {
-    return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode();
+    CompilationResult result =
+        prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, 0);
+    ASSERT(result != CompilationDeferred);
+    return result;
 }
 
 }
 
-CodeBlock* FunctionCodeBlock::replacement()
+CompilationResult CodeBlock::prepareForExecutionAsynchronously(
+    ExecState* exec, JITCode::JITType jitType,
+    PassRefPtr<DeferredCompilationCallback> passedCallback,
+    JITCompilationEffort effort, unsigned bytecodeIndex)
 {
 {
-    return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
+    RefPtr<DeferredCompilationCallback> callback = passedCallback;
+    CompilationResult result =
+        prepareForExecutionImpl(exec, jitType, effort, bytecodeIndex, callback);
+    if (result != CompilationDeferred)
+        callback->compilationDidComplete(this, result);
+    return result;
 }
 
 }
 
-#if ENABLE(DFG_JIT)
-JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+void CodeBlock::install()
 {
 {
-    if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
-        result = CompilationNotNeeded;
-        return 0;
-    }
-    JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
-    return error;
+    ownerExecutable()->installCode(this);
 }
 
 }
 
-CompilationResult ProgramCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
+PassRefPtr<CodeBlock> CodeBlock::newReplacement()
 {
 {
-    return static_cast<ProgramExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);
+    return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
 }
 
 }
 
-JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+#if ENABLE(JIT)
+void CodeBlock::reoptimize()
 {
 {
-    if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
-        result = CompilationNotNeeded;
-        return 0;
-    }
-    JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
-    return error;
+    ASSERT(replacement() != this);
+    ASSERT(replacement()->alternative() == this);
+    if (DFG::shouldShowDisassembly())
+        dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
+    replacement()->jettison();
+    countReoptimization();
 }
 
 }
 
-CompilationResult EvalCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
+CodeBlock* ProgramCodeBlock::replacement()
 {
 {
-    return static_cast<EvalExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan);
+    return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
 }
 
 }
 
-JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
+CodeBlock* EvalCodeBlock::replacement()
 {
 {
-    if (JITCode::isHigherTier(replacement()->jitType(), jitType())) {
-        result = CompilationNotNeeded;
-        return 0;
-    }
-    JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, result, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall);
-    return error;
+    return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode();
 }
 
 }
 
-CompilationResult FunctionCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
+CodeBlock* FunctionCodeBlock::replacement()
 {
 {
-    return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall);
+    return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
 }
 }
-#endif // ENABLE(DFG_JIT)
 
 DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
 {
 
 DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
 {
@@ -2804,27 +2838,6 @@ void FunctionCodeBlock::jettisonImpl()
 {
     static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
 }
 {
     static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
 }
-
-CompilationResult ProgramCodeBlock::jitCompileImpl(ExecState* exec)
-{
-    ASSERT(jitType() == JITCode::InterpreterThunk);
-    ASSERT(this == replacement());
-    return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);
-}
-
-CompilationResult EvalCodeBlock::jitCompileImpl(ExecState* exec)
-{
-    ASSERT(jitType() == JITCode::InterpreterThunk);
-    ASSERT(this == replacement());
-    return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);
-}
-
-CompilationResult FunctionCodeBlock::jitCompileImpl(ExecState* exec)
-{
-    ASSERT(jitType() == JITCode::InterpreterThunk);
-    ASSERT(this == replacement());
-    return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall);
-}
 #endif
 
 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
 #endif
 
 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
index 3662579..20a9814 100644 (file)
@@ -48,6 +48,7 @@
 #include "DFGOSREntry.h"
 #include "DFGOSRExit.h"
 #include "DFGVariableEventStream.h"
 #include "DFGOSREntry.h"
 #include "DFGOSRExit.h"
 #include "DFGVariableEventStream.h"
+#include "DeferredCompilationCallback.h"
 #include "EvalCodeCache.h"
 #include "ExecutionCounter.h"
 #include "ExpressionRangeInfo.h"
 #include "EvalCodeCache.h"
 #include "ExecutionCounter.h"
 #include "ExpressionRangeInfo.h"
@@ -202,6 +203,8 @@ public:
 
     unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
 
 
     unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
 
+    void unlinkIncomingCalls();
+
 #if ENABLE(JIT)
     unsigned bytecodeOffsetForCallAtIndex(unsigned index)
     {
 #if ENABLE(JIT)
     unsigned bytecodeOffsetForCallAtIndex(unsigned index)
     {
@@ -231,8 +234,6 @@ public:
     void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
 #endif // ENABLE(LLINT)
 
     void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
 #endif // ENABLE(LLINT)
 
-    void unlinkIncomingCalls();
-
 #if ENABLE(DFG_JIT) || ENABLE(LLINT)
     void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
     {
 #if ENABLE(DFG_JIT) || ENABLE(LLINT)
     void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
     {
@@ -264,7 +265,38 @@ public:
 
     int argumentIndexAfterCapture(size_t argument);
 
 
     int argumentIndexAfterCapture(size_t argument);
 
-#if ENABLE(JIT)
+    // Prepares this code block for execution. This is synchronous. This compile
+    // may fail, if you passed JITCompilationCanFail.
+    CompilationResult prepareForExecution(
+        ExecState*, JITCode::JITType,
+        JITCompilationEffort = JITCompilationMustSucceed,
+        unsigned bytecodeIndex = UINT_MAX);
+    
+    // Use this method for asynchronous compiles. This will do a compile at some
+    // point in time between when you called into this method and some point in the
+    // future. If you're lucky then it might complete before this method returns.
+    // Once it completes, the callback is called with the result. If the compile
+    // did happen to complete before the method returns, the result of the compile
+    // may be returned. If the compile didn't happen to complete yet, or if we
+    // didn't happen to notice that the compile already completed, we return
+    // CompilationDeferred.
+    //
+    // Note that asynchronous compiles don't actually complete unless you call into
+    // DFG::Worklist::completeAllReadyPlansForVM(). You usually force a call to
+    // this on the main thread by listening to the callback's
+    // compilationDidBecomeReadyAsynchronously() notification. Note that this call
+    // happens on another thread.
+    CompilationResult prepareForExecutionAsynchronously(
+        ExecState*, JITCode::JITType, PassRefPtr<DeferredCompilationCallback>,
+        JITCompilationEffort = JITCompilationMustSucceed,
+        unsigned bytecodeIndex = UINT_MAX);
+    
+    // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock);
+    void install();
+    
+    // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind())
+    PassRefPtr<CodeBlock> newReplacement();
+    
     void setJITCode(PassRefPtr<JITCode> code, MacroAssemblerCodePtr codeWithArityCheck)
     {
         ConcurrentJITLocker locker(m_lock);
     void setJITCode(PassRefPtr<JITCode> code, MacroAssemblerCodePtr codeWithArityCheck)
     {
         ConcurrentJITLocker locker(m_lock);
@@ -286,23 +318,14 @@ public:
         WTF::loadLoadFence(); // This probably isn't needed. Oh well, paranoia is good.
         return result;
     }
         WTF::loadLoadFence(); // This probably isn't needed. Oh well, paranoia is good.
         return result;
     }
+
+#if ENABLE(JIT)
     bool hasBaselineJITProfiling() const
     {
         return jitType() == JITCode::BaselineJIT;
     }
     bool hasBaselineJITProfiling() const
     {
         return jitType() == JITCode::BaselineJIT;
     }
-#if ENABLE(DFG_JIT)
-    virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0;
-    virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0;
-#endif // ENABLE(DFG_JIT)
     void jettison();
     void jettison();
-    CompilationResult jitCompile(ExecState* exec)
-    {
-        if (jitType() != JITCode::InterpreterThunk) {
-            ASSERT(jitType() == JITCode::BaselineJIT);
-            return CompilationNotNeeded;
-        }
-        return jitCompileImpl(exec);
-    }
+    
     virtual CodeBlock* replacement() = 0;
 
     virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
     virtual CodeBlock* replacement() = 0;
 
     virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
@@ -315,8 +338,6 @@ public:
     DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
 
     bool hasOptimizedReplacement();
     DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
 
     bool hasOptimizedReplacement();
-#else
-    JITCode::JITType jitType() const { return JITCode::InterpreterThunk; }
 #endif
 
     ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
 #endif
 
     ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
@@ -969,7 +990,6 @@ public:
     
 protected:
 #if ENABLE(JIT)
     
 protected:
 #if ENABLE(JIT)
-    virtual CompilationResult jitCompileImpl(ExecState*) = 0;
     virtual void jettisonImpl() = 0;
 #endif
     virtual void visitWeakReferences(SlotVisitor&);
     virtual void jettisonImpl() = 0;
 #endif
     virtual void visitWeakReferences(SlotVisitor&);
@@ -984,6 +1004,10 @@ protected:
 private:
     friend class DFGCodeBlocks;
     
 private:
     friend class DFGCodeBlocks;
     
+    CompilationResult prepareForExecutionImpl(
+        ExecState*, JITCode::JITType, JITCompilationEffort, unsigned bytecodeIndex,
+        PassRefPtr<DeferredCompilationCallback>);
+    
     void noticeIncomingCall(ExecState* callerFrame);
     
     double optimizationThresholdScalingFactor();
     void noticeIncomingCall(ExecState* callerFrame);
     
     double optimizationThresholdScalingFactor();
@@ -1085,12 +1109,12 @@ private:
     SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
     SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
 #endif
     SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
     SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
 #endif
+    RefPtr<JITCode> m_jitCode;
+    MacroAssemblerCodePtr m_jitCodeWithArityCheck;
 #if ENABLE(JIT)
     Vector<StructureStubInfo> m_structureStubInfos;
     Vector<ByValInfo> m_byValInfos;
     Vector<CallLinkInfo> m_callLinkInfos;
 #if ENABLE(JIT)
     Vector<StructureStubInfo> m_structureStubInfos;
     Vector<ByValInfo> m_byValInfos;
     Vector<CallLinkInfo> m_callLinkInfos;
-    RefPtr<JITCode> m_jitCode;
-    MacroAssemblerCodePtr m_jitCodeWithArityCheck;
     SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
 #endif
 #if ENABLE(DFG_JIT) || ENABLE(LLINT)
     SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
 #endif
 #if ENABLE(DFG_JIT) || ENABLE(LLINT)
@@ -1194,13 +1218,7 @@ public:
 
 #if ENABLE(JIT)
 protected:
 
 #if ENABLE(JIT)
 protected:
-#if ENABLE(DFG_JIT)
-    virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-
     virtual void jettisonImpl();
     virtual void jettisonImpl();
-    virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
@@ -1223,13 +1241,7 @@ public:
     
 #if ENABLE(JIT)
 protected:
     
 #if ENABLE(JIT)
 protected:
-#if ENABLE(DFG_JIT)
-    virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-
     virtual void jettisonImpl();
     virtual void jettisonImpl();
-    virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
@@ -1252,13 +1264,7 @@ public:
     
 #if ENABLE(JIT)
 protected:
     
 #if ENABLE(JIT)
 protected:
-#if ENABLE(DFG_JIT)
-    virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-
     virtual void jettisonImpl();
     virtual void jettisonImpl();
-    virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
     virtual CodeBlock* replacement();
     virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
diff --git a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp
new file mode 100644 (file)
index 0000000..35af7c7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DeferredCompilationCallback.h"
+
+namespace JSC {
+
+DeferredCompilationCallback::DeferredCompilationCallback() { }
+DeferredCompilationCallback::~DeferredCompilationCallback() { }
+
+} // JSC
+
diff --git a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h
new file mode 100644 (file)
index 0000000..6421e3e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DeferredCompilationCallback_h
+#define DeferredCompilationCallback_h
+
+#include "CompilationResult.h"
+#include <wtf/RefCounted.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+class DeferredCompilationCallback : public RefCounted<DeferredCompilationCallback> {
+protected:
+    DeferredCompilationCallback();
+
+public:
+    virtual ~DeferredCompilationCallback();
+
+    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) = 0;
+    virtual void compilationDidComplete(CodeBlock*, CompilationResult) = 0;
+};
+
+} // namespace JSC
+
+#endif // DeferredCompilationCallback_h
+
index 1713f2f..4de636f 100644 (file)
@@ -55,7 +55,7 @@ unsigned getNumCompilations()
     return numCompilations;
 }
 
     return numCompilations;
 }
 
-static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
+CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback)
 {
     SamplingRegion samplingRegion("DFG Compilation (Driver)");
     
 {
     SamplingRegion samplingRegion("DFG Compilation (Driver)");
     
@@ -99,12 +99,12 @@ static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeB
     else
         numVarsWithValues = 0;
     RefPtr<Plan> plan = adoptRef(
     else
         numVarsWithValues = 0;
     RefPtr<Plan> plan = adoptRef(
-        new Plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
+        new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
     for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) {
         int operand = plan->mustHandleValues.operandForIndex(i);
         if (operandIsArgument(operand)
             && !operandToArgument(operand)
     for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) {
         int operand = plan->mustHandleValues.operandForIndex(i);
         if (operandIsArgument(operand)
             && !operandToArgument(operand)
-            && compileMode == CompileFunction
+            && codeBlock->codeType() == FunctionCode
             && codeBlock->specializationKind() == CodeForConstruct) {
             // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
             // also never be used. It doesn't matter what we put into the value for this,
             && codeBlock->specializationKind() == CodeForConstruct) {
             // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
             // also never be used. It doesn't matter what we put into the value for this,
@@ -115,7 +115,8 @@ static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeB
             plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
     }
     
             plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
     }
     
-    if (enableConcurrentJIT()) {
+    if (enableConcurrentJIT() && callback) {
+        plan->callback = callback;
         if (!vm.worklist)
             vm.worklist = globalWorklist();
         if (logCompilationChanges())
         if (!vm.worklist)
             vm.worklist = globalWorklist();
         if (logCompilationChanges())
@@ -125,22 +126,7 @@ static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeB
     }
     
     plan->compileInThread(*vm.dfgState);
     }
     
     plan->compileInThread(*vm.dfgState);
-    return plan->finalize(jitCode, jitCodeWithArityCheck);
-}
-
-CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex)
-{
-    return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex);
-}
-
-CompilationResult tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex)
-{
-    return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck, bytecodeIndex);
-}
-
-CompilationResult tryFinalizePlan(PassRefPtr<Plan> plan, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
-{
-    return plan->finalize(jitCode, jitCodeWithArityCheck);
+    return plan->finalizeWithoutNotifyingCallback();
 }
 
 } } // namespace JSC::DFG
 }
 
 } } // namespace JSC::DFG
index cc7a92d..397fdc9 100644 (file)
@@ -42,17 +42,9 @@ namespace DFG {
 JS_EXPORT_PRIVATE unsigned getNumCompilations();
 
 #if ENABLE(DFG_JIT)
 JS_EXPORT_PRIVATE unsigned getNumCompilations();
 
 #if ENABLE(DFG_JIT)
-CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned bytecodeIndex);
-CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex);
-CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr* jitCodeWithArityCheck);
+CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>);
 #else
 #else
-inline CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return CompilationFailed; }
-inline CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return CompilationFailed; }
-inline CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr*)
-{
-    UNREACHABLE_FOR_PLATFORM();
-    return CompilationFailed;
-}
+inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; }
 #endif
 
 } } // namespace JSC::DFG
 #endif
 
 } } // namespace JSC::DFG
index 0936b55..fb00e20 100644 (file)
@@ -39,12 +39,12 @@ FailedFinalizer::~FailedFinalizer()
 {
 }
 
 {
 }
 
-bool FailedFinalizer::finalize(RefPtr<JSC::JITCode>&)
+bool FailedFinalizer::finalize()
 {
     return false;
 }
 
 {
     return false;
 }
 
-bool FailedFinalizer::finalizeFunction(RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&)
+bool FailedFinalizer::finalizeFunction()
 {
     return false;
 }
 {
     return false;
 }
index beca127..ad3982e 100644 (file)
@@ -39,8 +39,8 @@ public:
     FailedFinalizer(Plan&);
     virtual ~FailedFinalizer();
     
     FailedFinalizer(Plan&);
     virtual ~FailedFinalizer();
     
-    bool finalize(RefPtr<JSC::JITCode>& entry);
-    bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
+    bool finalize();
+    bool finalizeFunction();
 };
 
 } } // namespace JSC::DFG
 };
 
 } } // namespace JSC::DFG
index e598865..0b92adb 100644 (file)
@@ -46,8 +46,8 @@ public:
     Finalizer(Plan&);
     virtual ~Finalizer();
     
     Finalizer(Plan&);
     virtual ~Finalizer();
     
-    virtual bool finalize(RefPtr<JSC::JITCode>& entry) = 0;
-    virtual bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) = 0;
+    virtual bool finalize() = 0;
+    virtual bool finalizeFunction() = 0;
 
 protected:
     Plan& m_plan;
 
 protected:
     Plan& m_plan;
index 283cb1b..150eea6 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
 
 #if ENABLE(DFG_JIT)
 
+#include "CodeBlock.h"
 #include "DFGCommon.h"
 #include "DFGPlan.h"
 
 #include "DFGCommon.h"
 #include "DFGPlan.h"
 
@@ -45,23 +46,23 @@ JITFinalizer::~JITFinalizer()
 {
 }
 
 {
 }
 
-bool JITFinalizer::finalize(RefPtr<JSC::JITCode>& entry)
+bool JITFinalizer::finalize()
 {
     finalizeCommon();
     
     m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
 {
     finalizeCommon();
     
     m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
-    entry = m_jitCode;
+    m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr());
     
     return true;
 }
 
     
     return true;
 }
 
-bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
+bool JITFinalizer::finalizeFunction()
 {
     finalizeCommon();
     
 {
     finalizeCommon();
     
-    withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
+    MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck);
     m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
     m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
-    entry = m_jitCode;
+    m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck);
     
     return true;
 }
     
     return true;
 }
index 114afae..2dba8d3 100644 (file)
@@ -42,8 +42,8 @@ public:
     JITFinalizer(Plan&, PassRefPtr<JITCode>, PassOwnPtr<LinkBuffer>, MacroAssembler::Label arityCheck = MacroAssembler::Label());
     virtual ~JITFinalizer();
     
     JITFinalizer(Plan&, PassRefPtr<JITCode>, PassOwnPtr<LinkBuffer>, MacroAssembler::Label arityCheck = MacroAssembler::Label());
     virtual ~JITFinalizer();
     
-    bool finalize(RefPtr<JSC::JITCode>& entry);
-    bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
+    bool finalize();
+    bool finalizeFunction();
 
 private:
     void finalizeCommon();
 
 private:
     void finalizeCommon();
index 44db0f1..64fb9dd 100644 (file)
 
 #include "CodeBlock.h"
 #include "Executable.h"
 
 #include "CodeBlock.h"
 #include "Executable.h"
+#include "JITCode.h"
 #include "Operations.h"
 
 namespace JSC { namespace DFG {
 
 void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
 {
 #include "Operations.h"
 
 namespace JSC { namespace DFG {
 
 void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
 {
+    DeferGC deferGC(exec->vm().heap);
+    
     for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
         FunctionExecutable* executable =
             static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get());
         CodeBlock* codeBlock = executable->baselineCodeBlockFor(
             codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
         
     for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
         FunctionExecutable* executable =
             static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get());
         CodeBlock* codeBlock = executable->baselineCodeBlockFor(
             codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
         
-        codeBlock->jitCompile(exec);
+        if (codeBlock->jitType() == JSC::JITCode::BaselineJIT)
+            continue;
+        ASSERT(codeBlock->jitType() == JSC::JITCode::InterpreterThunk);
+        CompilationResult result = codeBlock->prepareForExecution(
+            exec, JSC::JITCode::BaselineJIT, JITCompilationMustSucceed);
+        ASSERT_UNUSED(result, result == CompilationSuccessful);
+        codeBlock->install();
     }
 }
 
     }
 }
 
index 3312ba1..cc8e7af 100644 (file)
@@ -1281,7 +1281,7 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
         if (error) {
             vm->throwException(exec, createStackOverflowError(exec));
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
         if (error) {
             vm->throwException(exec, createStackOverflowError(exec));
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
@@ -1326,7 +1326,7 @@ inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKin
     ExecutableBase* executable = function->executable();
     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
     ExecutableBase* executable = function->executable();
     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind);
         if (error) {
             exec->vm().throwException(execCallee, error);
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
         if (error) {
             exec->vm().throwException(execCallee, error);
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
index 59f3790..f5a7434 100644 (file)
@@ -80,10 +80,9 @@ static void dumpAndVerifyGraph(Graph& graph, const char* text)
 }
 
 Plan::Plan(
 }
 
 Plan::Plan(
-    CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
+    PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
     unsigned numVarsWithValues)
     unsigned numVarsWithValues)
-    : compileMode(compileMode)
-    , vm(*passedCodeBlock->vm())
+    : vm(*passedCodeBlock->vm())
     , codeBlock(passedCodeBlock)
     , osrEntryBytecodeIndex(osrEntryBytecodeIndex)
     , numVarsWithValues(numVarsWithValues)
     , codeBlock(passedCodeBlock)
     , osrEntryBytecodeIndex(osrEntryBytecodeIndex)
     , numVarsWithValues(numVarsWithValues)
@@ -208,7 +207,7 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
 
 #if ENABLE(FTL_JIT)
     if (Options::useExperimentalFTL()
 
 #if ENABLE(FTL_JIT)
     if (Options::useExperimentalFTL()
-        && compileMode == CompileFunction
+        && codeBlock->codeType() == FunctionCode
         && FTL::canCompile(dfg)) {
         
         performCriticalEdgeBreaking(dfg);
         && FTL::canCompile(dfg)) {
         
         performCriticalEdgeBreaking(dfg);
@@ -255,12 +254,10 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     dumpAndVerifyGraph(dfg, "Graph after optimization:");
 
     JITCompiler dataFlowJIT(dfg);
     dumpAndVerifyGraph(dfg, "Graph after optimization:");
 
     JITCompiler dataFlowJIT(dfg);
-    if (compileMode == CompileFunction) {
+    if (codeBlock->codeType() == FunctionCode) {
         dataFlowJIT.compileFunction();
         dataFlowJIT.linkFunction();
     } else {
         dataFlowJIT.compileFunction();
         dataFlowJIT.linkFunction();
     } else {
-        ASSERT(compileMode == CompileOther);
-        
         dataFlowJIT.compile();
         dataFlowJIT.link();
     }
         dataFlowJIT.compile();
         dataFlowJIT.link();
     }
@@ -283,25 +280,36 @@ void Plan::reallyAdd(CommonData* commonData)
     writeBarriers.trigger(vm);
 }
 
     writeBarriers.trigger(vm);
 }
 
-CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
+void Plan::notifyReady()
+{
+    callback->compilationDidBecomeReadyAsynchronously(codeBlock.get());
+    isCompiled = true;
+}
+
+CompilationResult Plan::finalizeWithoutNotifyingCallback()
 {
     if (!isStillValid())
         return CompilationInvalidated;
     
     bool result;
 {
     if (!isStillValid())
         return CompilationInvalidated;
     
     bool result;
-    if (compileMode == CompileFunction)
-        result = finalizer->finalizeFunction(jitCode, *jitCodeWithArityCheck);
+    if (codeBlock->codeType() == FunctionCode)
+        result = finalizer->finalizeFunction();
     else
     else
-        result = finalizer->finalize(jitCode);
+        result = finalizer->finalize();
     
     if (!result)
         return CompilationFailed;
     
     
     if (!result)
         return CompilationFailed;
     
-    reallyAdd(jitCode->dfgCommon());
+    reallyAdd(codeBlock->jitCode()->dfgCommon());
     
     return CompilationSuccessful;
 }
 
     
     return CompilationSuccessful;
 }
 
+void Plan::finalizeAndNotifyCallback()
+{
+    callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback());
+}
+
 CodeBlock* Plan::key()
 {
     return codeBlock->alternative();
 CodeBlock* Plan::key()
 {
     return codeBlock->alternative();
index 7d56d3e..59868d0 100644 (file)
@@ -36,6 +36,7 @@
 #include "DFGDesiredWeakReferences.h"
 #include "DFGDesiredWriteBarriers.h"
 #include "DFGFinalizer.h"
 #include "DFGDesiredWeakReferences.h"
 #include "DFGDesiredWriteBarriers.h"
 #include "DFGFinalizer.h"
+#include "DeferredCompilationCallback.h"
 #include "Operands.h"
 #include "ProfilerCompilation.h"
 #include <wtf/ThreadSafeRefCounted.h>
 #include "Operands.h"
 #include "ProfilerCompilation.h"
 #include <wtf/ThreadSafeRefCounted.h>
@@ -48,23 +49,22 @@ namespace DFG {
 
 class LongLivedState;
 
 
 class LongLivedState;
 
-enum CompileMode { CompileFunction, CompileOther };
-
 #if ENABLE(DFG_JIT)
 
 struct Plan : public ThreadSafeRefCounted<Plan> {
     Plan(
 #if ENABLE(DFG_JIT)
 
 struct Plan : public ThreadSafeRefCounted<Plan> {
     Plan(
-        CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock,
-        unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
+        PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
     ~Plan();
     
     void compileInThread(LongLivedState&);
     
     ~Plan();
     
     void compileInThread(LongLivedState&);
     
-    CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck);
+    CompilationResult finalizeWithoutNotifyingCallback();
+    void finalizeAndNotifyCallback();
+    
+    void notifyReady();
     
     CodeBlock* key();
     
     
     CodeBlock* key();
     
-    const CompileMode compileMode;
     VM& vm;
     RefPtr<CodeBlock> codeBlock;
     const unsigned osrEntryBytecodeIndex;
     VM& vm;
     RefPtr<CodeBlock> codeBlock;
     const unsigned osrEntryBytecodeIndex;
@@ -86,6 +86,8 @@ struct Plan : public ThreadSafeRefCounted<Plan> {
     
     bool isCompiled;
 
     
     bool isCompiled;
 
+    RefPtr<DeferredCompilationCallback> callback;
+
 private:
     enum CompilationPath { FailPath, DFGPath, FTLPath };
     CompilationPath compileInThreadImpl(LongLivedState&);
 private:
     enum CompilationPath { FailPath, DFGPath, FTLPath };
     CompilationPath compileInThreadImpl(LongLivedState&);
index 957c180..8e47021 100644 (file)
@@ -3837,7 +3837,8 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
         
             break;
         }
         
-        if (isCellSpeculation(node->child1()->prediction())) {
+        switch (node->child1().useKind()) {
+        case CellUse: {
             SpeculateCellOperand base(this, node->child1());
             GPRTemporary resultTag(this, base);
             GPRTemporary resultPayload(this);
             SpeculateCellOperand base(this, node->child1());
             GPRTemporary resultTag(this, base);
             GPRTemporary resultPayload(this);
@@ -3854,22 +3855,30 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
         
             break;
         }
         
-        JSValueOperand base(this, node->child1());
-        GPRTemporary resultTag(this, base);
-        GPRTemporary resultPayload(this);
+        case UntypedUse: {
+            JSValueOperand base(this, node->child1());
+            GPRTemporary resultTag(this, base);
+            GPRTemporary resultPayload(this);
         
         
-        GPRReg baseTagGPR = base.tagGPR();
-        GPRReg basePayloadGPR = base.payloadGPR();
-        GPRReg resultTagGPR = resultTag.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
+            GPRReg baseTagGPR = base.tagGPR();
+            GPRReg basePayloadGPR = base.payloadGPR();
+            GPRReg resultTagGPR = resultTag.gpr();
+            GPRReg resultPayloadGPR = resultPayload.gpr();
         
         
-        base.use();
+            base.use();
         
         
-        JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
+            JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
         
         
-        cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
+            cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
         
         
-        jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+            jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+            break;
+        }
+            
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
         break;
     }
 
         break;
     }
 
index a73e56d..051641d 100644 (file)
@@ -165,10 +165,7 @@ Worklist::State Worklist::completeAllReadyPlansForVM(VM& vm, CodeBlock* requeste
         
         RELEASE_ASSERT(plan->isCompiled);
         
         
         RELEASE_ASSERT(plan->isCompiled);
         
-        CompilationResult compilationResult =
-            profiledBlock->replaceWithDeferredOptimizedCode(plan);
-        RELEASE_ASSERT(compilationResult != CompilationDeferred);
-        profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult);
+        plan->finalizeAndNotifyCallback();
         
         if (profiledBlock == requestedProfiledBlock)
             resultingState = Compiled;
         
         if (profiledBlock == requestedProfiledBlock)
             resultingState = Compiled;
@@ -243,8 +240,7 @@ void Worklist::runThread()
         
         {
             MutexLocker locker(m_lock);
         
         {
             MutexLocker locker(m_lock);
-            plan->key()->forceOptimizationSlowPathConcurrently();
-            plan->isCompiled = true;
+            plan->notifyReady();
             
             if (Options::verboseCompilationQueue()) {
                 dump(locker, WTF::dataFile());
             
             if (Options::verboseCompilationQueue()) {
                 dump(locker, WTF::dataFile());
index a9aff7b..077e08a 100644 (file)
@@ -44,13 +44,13 @@ JITFinalizer::~JITFinalizer()
 {
 }
 
 {
 }
 
-bool JITFinalizer::finalize(RefPtr<JSC::JITCode>&)
+bool JITFinalizer::finalize()
 {
     RELEASE_ASSERT_NOT_REACHED();
     return false;
 }
 
 {
     RELEASE_ASSERT_NOT_REACHED();
     return false;
 }
 
-bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck)
+bool JITFinalizer::finalizeFunction()
 {
     for (unsigned i = m_jitCode->handles().size(); i--;) {
         MacroAssembler::cacheFlush(
 {
     for (unsigned i = m_jitCode->handles().size(); i--;) {
         MacroAssembler::cacheFlush(
@@ -64,12 +64,13 @@ bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerC
                 ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data())));
     } // else this function had no OSR exits, so no exit thunks.
     
                 ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data())));
     } // else this function had no OSR exits, so no exit thunks.
     
-    withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
+    MacroAssemblerCodePtr withArityCheck = m_entrypointLinkBuffer->locationOf(m_arityCheck);
     m_jitCode->initializeCode(
         FINALIZE_DFG_CODE(
             *m_entrypointLinkBuffer,
             ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), m_function)));
     m_jitCode->initializeCode(
         FINALIZE_DFG_CODE(
             *m_entrypointLinkBuffer,
             ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), m_function)));
-    entry = m_jitCode;
+    
+    m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck);
     
     return true;
 }
     
     return true;
 }
index 3dc00f8..886bd2d 100644 (file)
@@ -65,8 +65,8 @@ public:
         m_jitCode = jitCode;
     }
     
         m_jitCode = jitCode;
     }
     
-    bool finalize(RefPtr<JSC::JITCode>& entry);
-    bool finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck);
+    bool finalize();
+    bool finalizeFunction();
 
 private:
     OwnPtr<LinkBuffer> m_exitThunksLinkBuffer;
 
 private:
     OwnPtr<LinkBuffer> m_exitThunksLinkBuffer;
index 2812393..e422fb6 100644 (file)
@@ -184,6 +184,8 @@ namespace JSC {
         const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
         
         void addReference(JSCell*, ArrayBuffer*);
         const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
         
         void addReference(JSCell*, ArrayBuffer*);
+        
+        bool isDeferred() const { return !!m_deferralDepth; }
 
     private:
         friend class CodeBlock;
 
     private:
         friend class CodeBlock;
index 59f8e50..5005725 100644 (file)
@@ -734,7 +734,7 @@ failedJSONP:
     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
-    if (JSObject* error = program->compile(callFrame, scope))
+    if (JSObject* error = program->prepareForExecution(callFrame, scope, CodeForCall))
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
     ProgramCodeBlock* codeBlock = &program->generatedBytecode();
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
     ProgramCodeBlock* codeBlock = &program->generatedBytecode();
@@ -803,7 +803,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
 
     if (isJSCall) {
         // Compile the callee:
 
     if (isJSCall) {
         // Compile the callee:
-        JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope);
+        JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
@@ -882,7 +882,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
 
     if (isJSConstruct) {
         // Compile the callee:
 
     if (isJSConstruct) {
         // Compile the callee:
-        JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope);
+        JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct);
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
@@ -956,7 +956,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
     }
 
     // Compile the callee:
     }
 
     // Compile the callee:
-    JSObject* error = functionExecutable->compileForCall(callFrame, scope);
+    JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
     if (error) {
         callFrame->vm().throwException(callFrame, error);
         return CallFrameClosure();
     if (error) {
         callFrame->vm().throwException(callFrame, error);
         return CallFrameClosure();
@@ -1072,7 +1072,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
         }
     }
 
         }
     }
 
-    JSObject* compileError = eval->compile(callFrame, scope);
+    JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall);
     if (UNLIKELY(!!compileError))
         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
     EvalCodeBlock* codeBlock = &eval->generatedBytecode();
     if (UNLIKELY(!!compileError))
         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
     EvalCodeBlock* codeBlock = &eval->generatedBytecode();
diff --git a/Source/JavaScriptCore/jit/JITDriver.h b/Source/JavaScriptCore/jit/JITDriver.h
deleted file mode 100644 (file)
index ad80022..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef JITDriver_h
-#define JITDriver_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(JIT)
-
-#include "BytecodeGenerator.h"
-#include "CompilationResult.h"
-#include "DFGDriver.h"
-#include "JIT.h"
-#include "LLIntEntrypoints.h"
-
-namespace JSC {
-
-template<typename CodeBlockType>
-inline CompilationResult jitCompileIfAppropriateImpl(
-    ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
-    JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
-{
-    VM& vm = exec->vm();
-    
-    if (jitType == codeBlock->jitType())
-        return CompilationNotNeeded;
-    
-    if (!vm.canUseJIT())
-        return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
-    
-    codeBlock->unlinkIncomingCalls();
-    
-    RefPtr<JITCode> oldJITCode = jitCode;
-    
-    if (JITCode::isOptimizingJIT(jitType)) {
-        CompilationResult result =
-            DFG::tryCompile(exec, codeBlock, jitCode, bytecodeIndex);
-        if (result == CompilationSuccessful)
-            codeBlock->alternative()->unlinkIncomingCalls();
-        else {
-            ASSERT(oldJITCode == jitCode);
-            return result;
-        }
-    } else {
-        RefPtr<JITCode> result = JIT::compile(&vm, codeBlock, effort);
-        if (result)
-            jitCode = result;
-        else
-            return CompilationFailed;
-    }
-    
-    return CompilationSuccessful;
-}
-
-inline CompilationResult jitCompileFunctionIfAppropriateImpl(
-    ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
-    MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
-    unsigned bytecodeIndex, JITCompilationEffort effort)
-{
-    VM& vm = exec->vm();
-    
-    if (jitType == codeBlock->jitType())
-        return CompilationNotNeeded;
-    
-    if (!vm.canUseJIT())
-        return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
-    
-    codeBlock->unlinkIncomingCalls();
-    
-    RefPtr<JITCode> oldJITCode = jitCode;
-    MacroAssemblerCodePtr oldJITCodeWithArityCheck = jitCodeWithArityCheck;
-    
-    if (JITCode::isOptimizingJIT(jitType)) {
-        CompilationResult result = DFG::tryCompileFunction(
-            exec, codeBlock, jitCode, jitCodeWithArityCheck, bytecodeIndex);
-        if (result == CompilationSuccessful)
-            codeBlock->alternative()->unlinkIncomingCalls();
-        else {
-            ASSERT(oldJITCode == jitCode);
-            ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
-            return result;
-        }
-    } else {
-        RefPtr<JITCode> result =
-            JIT::compile(&vm, codeBlock, effort, &jitCodeWithArityCheck);
-        if (result)
-            jitCode = result;
-        else {
-            ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
-            return CompilationFailed;
-        }
-    }
-
-    return CompilationSuccessful;
-}
-
-template<typename CodeBlockType>
-inline CompilationResult jitCompileIfAppropriate(
-    ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
-    JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
-{
-    CompilationResult result = jitCompileIfAppropriateImpl(
-        exec, codeBlock, jitCode, jitType, bytecodeIndex, effort);
-    if (result == CompilationSuccessful) {
-        codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
-        codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
-    }
-    return result;
-}    
-
-inline CompilationResult jitCompileFunctionIfAppropriate(
-    ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
-    MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
-    unsigned bytecodeIndex, JITCompilationEffort effort)
-{
-    CompilationResult result = jitCompileFunctionIfAppropriateImpl(
-        exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, effort);
-    if (result == CompilationSuccessful) {
-        codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
-        codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
-    }
-    return result;
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // JITDriver_h
-
index 9f94163..883b211 100644 (file)
@@ -51,6 +51,7 @@
 #include <wtf/InlineASM.h>
 #include "JIT.h"
 #include "JITExceptions.h"
 #include <wtf/InlineASM.h>
 #include "JIT.h"
 #include "JITExceptions.h"
+#include "JITToDFGDeferredCompilationCallback.h"
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "JSFunction.h"
@@ -998,7 +999,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
         if (Options::verboseOSR())
             dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
         // If we have an optimized replacement, then it must be the case that we entered
         if (Options::verboseOSR())
             dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
         // If we have an optimized replacement, then it must be the case that we entered
-        // cti_optimize from a loop. That's because is there's an optimized replacement,
+        // cti_optimize from a loop. That's because if there's an optimized replacement,
         // then all calls to this function will be relinked to the replacement and so
         // the prologue OSR will never fire.
         
         // then all calls to this function will be relinked to the replacement and so
         // the prologue OSR will never fire.
         
@@ -1032,16 +1033,12 @@ DEFINE_STUB_FUNCTION(void, optimize)
         if (Options::verboseOSR())
             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
         
         if (Options::verboseOSR())
             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
         
-        JSScope* scope = callFrame->scope();
-        CompilationResult result;
-        JSObject* error = codeBlock->compileOptimized(callFrame, scope, result, bytecodeIndex);
-        if (Options::verboseOSR()) {
-            dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n");
-            if (error)
-                dataLog("WARNING: optimized compilation failed with a JS error.\n");
-        }
+        RefPtr<DeferredCompilationCallback> callback =
+            JITToDFGDeferredCompilationCallback::create();
+        RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement();
+        CompilationResult result = newCodeBlock->prepareForExecutionAsynchronously(
+            callFrame, JITCode::DFGJIT, callback, JITCompilationCanFail, bytecodeIndex);
         
         
-        codeBlock->setOptimizationThresholdBasedOnCompilationResult(result);
         if (result != CompilationSuccessful)
             return;
     }
         if (result != CompilationSuccessful)
             return;
     }
@@ -1168,7 +1165,7 @@ inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
     ASSERT(!function->isHostFunction());
     FunctionExecutable* executable = function->jsExecutable();
     JSScope* callDataScopeChain = function->scope();
     ASSERT(!function->isHostFunction());
     FunctionExecutable* executable = function->jsExecutable();
     JSScope* callDataScopeChain = function->scope();
-    JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
+    JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind);
     if (!error)
         return function;
     callFrame->vm().throwException(callFrame, error);
     if (!error)
         return function;
     callFrame->vm().throwException(callFrame, error);
@@ -1267,7 +1264,7 @@ inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
+        if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) {
             callFrame->vm().throwException(callFrame, error);
             return 0;
         }
             callFrame->vm().throwException(callFrame, error);
             return 0;
         }
@@ -1344,7 +1341,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
         
         FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
         JSScope* scopeChain = callee->scope();
         
         FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
         JSScope* scopeChain = callee->scope();
-        JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
+        JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall);
         if (error) {
             callFrame->vm().throwException(callFrame, error);
             return 0;
         if (error) {
             callFrame->vm().throwException(callFrame, error);
             return 0;
diff --git a/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp b/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp
new file mode 100644 (file)
index 0000000..c83125d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JITToDFGDeferredCompilationCallback.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "CodeBlock.h"
+#include "Executable.h"
+
+namespace JSC {
+
+JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback() { }
+JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback() { }
+
+PassRefPtr<JITToDFGDeferredCompilationCallback> JITToDFGDeferredCompilationCallback::create()
+{
+    return adoptRef(new JITToDFGDeferredCompilationCallback());
+}
+
+void JITToDFGDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
+    CodeBlock* codeBlock)
+{
+    ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
+    
+    if (Options::verboseOSR())
+        dataLog("Optimizing compilation of ", *codeBlock, " did become ready.\n");
+    
+    codeBlock->alternative()->forceOptimizationSlowPathConcurrently();
+}
+
+void JITToDFGDeferredCompilationCallback::compilationDidComplete(
+    CodeBlock* codeBlock, CompilationResult result)
+{
+    ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
+    
+    if (Options::verboseOSR())
+        dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n");
+    
+    if (result == CompilationSuccessful)
+        codeBlock->install();
+    
+    codeBlock->alternative()->setOptimizationThresholdBasedOnCompilationResult(result);
+}
+
+} // JSC
+
+#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h b/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h
new file mode 100644 (file)
index 0000000..0041245
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JITToDFGDeferredCompilationCallback_h
+#define JITToDFGDeferredCompilationCallback_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DeferredCompilationCallback.h"
+#include <wtf/PassRefPtr.h>
+
+namespace JSC {
+
+class ScriptExecutable;
+
+class JITToDFGDeferredCompilationCallback : public DeferredCompilationCallback {
+protected:
+    JITToDFGDeferredCompilationCallback();
+
+public:
+    virtual ~JITToDFGDeferredCompilationCallback();
+
+    static PassRefPtr<JITToDFGDeferredCompilationCallback> create();
+    
+    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
+    virtual void compilationDidComplete(CodeBlock*, CompilationResult);
+};
+
+} // namespace JSC
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // JITToDFGDeferredCompilationCallback_h
+
index c9b17da..d99e74e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(LLINT)
 
 
 #if ENABLE(LLINT)
 
+#include "CodeBlock.h"
 #include "JITCode.h"
 #include "JITCode.h"
-#include "VM.h"
 #include "JSObject.h"
 #include "LLIntThunks.h"
 #include "LowLevelInterpreter.h"
 #include "JSObject.h"
 #include "LLIntThunks.h"
 #include "LowLevelInterpreter.h"
+#include "VM.h"
 
 
 namespace JSC { namespace LLInt {
 
 
 
 namespace JSC { namespace LLInt {
 
-void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck)
+void setFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock)
 {
 {
+    CodeSpecializationKind kind = codeBlock->specializationKind();
+    
     if (!vm.canUseJIT()) {
         if (kind == CodeForCall) {
     if (!vm.canUseJIT()) {
         if (kind == CodeForCall) {
-            jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk));
-            arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check);
+            codeBlock->setJITCode(
+                adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)),
+                MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check));
             return;
         }
 
         ASSERT(kind == CodeForConstruct);
             return;
         }
 
         ASSERT(kind == CodeForConstruct);
-        jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk));
-        arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check);
+        codeBlock->setJITCode(
+            adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)),
+            MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check));
         return;
     }
     
 #if ENABLE(JIT)
     if (kind == CodeForCall) {
         return;
     }
     
 #if ENABLE(JIT)
     if (kind == CodeForCall) {
-        jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk));
-        arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code();
+        codeBlock->setJITCode(
+            adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)),
+            vm.getCTIStub(functionForCallArityCheckThunkGenerator).code());
         return;
     }
 
     ASSERT(kind == CodeForConstruct);
         return;
     }
 
     ASSERT(kind == CodeForConstruct);
-    jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk));
-    arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
+    codeBlock->setJITCode(
+        adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)),
+        vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code());
 #endif // ENABLE(JIT)
 }
 
 #endif // ENABLE(JIT)
 }
 
-void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
+void setEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock)
 {
     if (!vm.canUseJIT()) {
 {
     if (!vm.canUseJIT()) {
-        jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk));
+        codeBlock->setJITCode(
+            adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)),
+            MacroAssemblerCodePtr());
         return;
     }
         return;
     }
-#if ENABLE(JIT)    
-    jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk));
+#if ENABLE(JIT)
+    codeBlock->setJITCode(
+        adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)),
+        MacroAssemblerCodePtr());
 #endif
 }
 
 #endif
 }
 
-void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode)
+void setProgramEntrypoint(VM& vm, ProgramCodeBlock* codeBlock)
 {
     if (!vm.canUseJIT()) {
 {
     if (!vm.canUseJIT()) {
-        jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk));
+        codeBlock->setJITCode(
+            adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)),
+            MacroAssemblerCodePtr());
         return;
     }
 #if ENABLE(JIT)
         return;
     }
 #if ENABLE(JIT)
-    jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk));
+    codeBlock->setJITCode(
+        adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)),
+        MacroAssemblerCodePtr());
 #endif
 }
 
 #endif
 }
 
index ed6d0db..0b7af06 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
 namespace JSC {
 
 class EvalCodeBlock;
 namespace JSC {
 
 class EvalCodeBlock;
+class FunctionCodeBlock;
 class VM;
 class MacroAssemblerCodePtr;
 class MacroAssemblerCodeRef;
 class VM;
 class MacroAssemblerCodePtr;
 class MacroAssemblerCodeRef;
@@ -44,19 +45,9 @@ class ProgramCodeBlock;
 
 namespace LLInt {
 
 
 namespace LLInt {
 
-void getFunctionEntrypoint(VM&, CodeSpecializationKind, RefPtr<JITCode>&, MacroAssemblerCodePtr& arityCheck);
-void getEvalEntrypoint(VM&, RefPtr<JITCode>&);
-void getProgramEntrypoint(VM&, RefPtr<JITCode>&);
-
-inline void getEntrypoint(VM& vm, EvalCodeBlock*, RefPtr<JITCode>& jitCode)
-{
-    getEvalEntrypoint(vm, jitCode);
-}
-
-inline void getEntrypoint(VM& vm, ProgramCodeBlock*, RefPtr<JITCode>& jitCode)
-{
-    getProgramEntrypoint(vm, jitCode);
-}
+void setFunctionEntrypoint(VM&, FunctionCodeBlock*);
+void setEvalEntrypoint(VM&, EvalCodeBlock*);
+void setProgramEntrypoint(VM&, ProgramCodeBlock*);
 
 } } // namespace JSC::LLInt
 
 
 } } // namespace JSC::LLInt
 
index 0fd3054..8561c67 100644 (file)
@@ -37,7 +37,6 @@
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
-#include "JITDriver.h"
 #include "JSActivation.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSActivation.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
@@ -280,6 +279,8 @@ inline bool shouldJIT(ExecState* exec)
 // Returns true if we should try to OSR.
 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
 {
 // Returns true if we should try to OSR.
 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
 {
+    DeferGC deferGC(exec->vm().heap);
+    
     codeBlock->updateAllValueProfilePredictions();
     
     if (!codeBlock->checkIfJITThresholdReached()) {
     codeBlock->updateAllValueProfilePredictions();
     
     if (!codeBlock->checkIfJITThresholdReached()) {
@@ -288,23 +289,33 @@ inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
         return false;
     }
     
         return false;
     }
     
-    CompilationResult result = codeBlock->jitCompile(exec);
-    switch (result) {
-    case CompilationNotNeeded:
+    switch (codeBlock->jitType()) {
+    case JITCode::BaselineJIT: {
         if (Options::verboseOSR())
             dataLogF("    Code was already compiled.\n");
         codeBlock->jitSoon();
         return true;
         if (Options::verboseOSR())
             dataLogF("    Code was already compiled.\n");
         codeBlock->jitSoon();
         return true;
-    case CompilationFailed:
-        if (Options::verboseOSR())
-            dataLogF("    JIT compilation failed.\n");
-        codeBlock->dontJITAnytimeSoon();
-        return false;
-    case CompilationSuccessful:
-        if (Options::verboseOSR())
-            dataLogF("    JIT compilation successful.\n");
-        codeBlock->jitSoon();
-        return true;
+    }
+    case JITCode::InterpreterThunk: {
+        CompilationResult result = codeBlock->prepareForExecution(
+            exec, JITCode::BaselineJIT, JITCompilationCanFail);
+        switch (result) {
+        case CompilationFailed:
+            if (Options::verboseOSR())
+                dataLogF("    JIT compilation failed.\n");
+            codeBlock->dontJITAnytimeSoon();
+            return false;
+        case CompilationSuccessful:
+            if (Options::verboseOSR())
+                dataLogF("    JIT compilation successful.\n");
+            codeBlock->install();
+            codeBlock->jitSoon();
+            return true;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return false;
+        }
+    }
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return false;
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return false;
@@ -1004,7 +1015,7 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         codePtr = executable->hostCodeEntryFor(kind);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
         codePtr = executable->hostCodeEntryFor(kind);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
         if (error)
             LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
         if (error)
             LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
index db21c4b..4582c99 100644 (file)
@@ -78,7 +78,7 @@ static inline bool isNumericCompareFunction(ExecState* exec, CallType callType,
 
     FunctionExecutable* executable = callData.js.functionExecutable;
 
 
     FunctionExecutable* executable = callData.js.functionExecutable;
 
-    JSObject* error = executable->compileForCall(exec, callData.js.scope);
+    JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall);
     if (error)
         return false;
 
     if (error)
         return false;
 
index 90e7619..eb4a8bf 100644 (file)
@@ -37,7 +37,6 @@
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
-#include "JITDriver.h"
 #include "JITStubs.h"
 #include "JSActivation.h"
 #include "JSCJSValue.h"
 #include "JITStubs.h"
 #include "JSActivation.h"
 #include "JSCJSValue.h"
index 2d4ba97..878892f 100644 (file)
@@ -42,9 +42,6 @@ void printInternal(PrintStream& out, CompilationResult result)
     case CompilationSuccessful:
         out.print("CompilationSuccessful");
         return;
     case CompilationSuccessful:
         out.print("CompilationSuccessful");
         return;
-    case CompilationNotNeeded:
-        out.print("CompilationNotNeeded");
-        return;
     case CompilationDeferred:
         out.print("CompilationDeferred");
         return;
     case CompilationDeferred:
         out.print("CompilationDeferred");
         return;
index 6ae0b7d..db6a0c4 100644 (file)
 
 namespace JSC {
 
 
 namespace JSC {
 
-enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred };
+enum CompilationResult {
+    // We tried to compile the code, but we couldn't compile it. This could be
+    // because we ran out of memory, or because the compiler encountered an
+    // internal error and decided to bail out gracefully. Either way, this implies
+    // that we shouldn't try to compile this code block again.
+    CompilationFailed,
+    
+    // The profiling assumptions that were fed into the compiler were invalidated
+    // even before we finished compiling. This means we should try again: in such
+    // cases the profiling will now be updated and the next compilation won't
+    // encounter the same problem. But it does mean that we should exercise
+    // exponential back-off, to get even more profiling so that new profiling
+    // pathologies aren't encountered.
+    CompilationInvalidated,
+    
+    // The compilation succeeded and the code block now has JITCode for the newly
+    // compiled code. However, compilation success doesn't mean that the CodeBlock
+    // will execute yet; you typically have to install it first, unless you plan
+    // on invoking it manually (something that *could* be done for some kinds of
+    // OSR entry).
+    CompilationSuccessful,
+    
+    // We decided to do the compilation asynchronously. This means that we haven't
+    // yet compiled the code. This only happens when you pass a
+    // DeferredCompilationCallback. That callback will get called with some
+    // interesting result, once compilation completes.
+    CompilationDeferred
+};
 
 } // namespace JSC
 
 
 } // namespace JSC
 
index 46e48e6..9f2f90e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,9 +30,7 @@
 #include "BytecodeGenerator.h"
 #include "CodeBlock.h"
 #include "DFGDriver.h"
 #include "BytecodeGenerator.h"
 #include "CodeBlock.h"
 #include "DFGDriver.h"
-#include "ExecutionHarness.h"
 #include "JIT.h"
 #include "JIT.h"
-#include "JITDriver.h"
 #include "Operations.h"
 #include "Parser.h"
 #include <wtf/Vector.h>
 #include "Operations.h"
 #include "Parser.h"
 #include <wtf/Vector.h>
@@ -114,6 +112,190 @@ void ScriptExecutable::destroy(JSCell* cell)
 }
 #endif
 
 }
 #endif
 
+void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
+{
+    RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
+    
+    VM& vm = *genericCodeBlock->vm();
+    
+    if (vm.m_perBytecodeProfiler)
+        vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock);
+    
+    ASSERT(vm.heap.isDeferred());
+    
+    if (JITCode::isJIT(genericCodeBlock->jitType())) {
+        vm.heap.reportExtraMemoryCost(
+            sizeof(CodeBlock) + genericCodeBlock->jitCode()->size());
+    } else
+        vm.heap.reportExtraMemoryCost(sizeof(CodeBlock));
+    
+    CodeSpecializationKind kind = genericCodeBlock->specializationKind();
+    
+    RefPtr<CodeBlock> oldCodeBlock;
+    
+    switch (kind) {
+    case CodeForCall:
+        m_jitCodeForCall = genericCodeBlock->jitCode();
+        m_jitCodeForCallWithArityCheck = genericCodeBlock->jitCodeWithArityCheck();
+        m_numParametersForCall = genericCodeBlock->numParameters();
+        break;
+    case CodeForConstruct:
+        m_jitCodeForConstruct = genericCodeBlock->jitCode();
+        m_jitCodeForConstructWithArityCheck = genericCodeBlock->jitCodeWithArityCheck();
+        m_numParametersForConstruct = genericCodeBlock->numParameters();
+        break;
+    }
+    
+    switch (genericCodeBlock->codeType()) {
+    case GlobalCode: {
+        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
+        ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock);
+        
+        ASSERT(!codeBlock->jitCodeWithArityCheck());
+        ASSERT(kind == CodeForCall);
+        
+        oldCodeBlock = executable->m_programCodeBlock;
+        executable->m_programCodeBlock = codeBlock;
+        break;
+    }
+        
+    case EvalCode: {
+        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
+        EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock);
+        
+        ASSERT(!codeBlock->jitCodeWithArityCheck());
+        ASSERT(kind == CodeForCall);
+        
+        oldCodeBlock = executable->m_evalCodeBlock;
+        executable->m_evalCodeBlock = codeBlock;
+        break;
+    }
+        
+    case FunctionCode: {
+        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
+        FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock);
+        
+        switch (kind) {
+        case CodeForCall:
+            oldCodeBlock = executable->m_codeBlockForCall;
+            executable->m_codeBlockForCall = codeBlock;
+            break;
+        case CodeForConstruct:
+            oldCodeBlock = executable->m_codeBlockForConstruct;
+            executable->m_codeBlockForConstruct = codeBlock;
+            break;
+        }
+        break;
+    } }
+
+    if (oldCodeBlock)
+        oldCodeBlock->unlinkIncomingCalls();
+}
+
+PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
+    CodeSpecializationKind kind, JSScope* scope, JSObject*& exception)
+{
+    VM* vm = scope->vm();
+
+    ASSERT(vm->heap.isDeferred());
+    
+    if (classInfo() == EvalExecutable::info()) {
+        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
+        RELEASE_ASSERT(kind == CodeForCall);
+        RELEASE_ASSERT(!executable->m_evalCodeBlock);
+        return adoptRef(new EvalCodeBlock(
+            executable, executable->m_unlinkedEvalCodeBlock.get(), scope,
+            executable->source().provider()));
+    }
+    
+    if (classInfo() == ProgramExecutable::info()) {
+        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
+        RELEASE_ASSERT(kind == CodeForCall);
+        RELEASE_ASSERT(!executable->m_programCodeBlock);
+        return adoptRef(new ProgramCodeBlock(
+            executable, executable->m_unlinkedProgramCodeBlock.get(), scope,
+            executable->source().provider(), executable->source().startColumn()));
+    }
+    
+    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
+    FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
+    RELEASE_ASSERT(!executable->codeBlockFor(kind));
+    JSGlobalObject* globalObject = scope->globalObject();
+    ParserError error;
+    DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
+    ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
+    UnlinkedFunctionCodeBlock* unlinkedCodeBlock =
+        executable->m_unlinkedExecutable->codeBlockFor(
+            *vm, executable->m_source, kind, debuggerMode, profilerMode, error);
+    if (!unlinkedCodeBlock) {
+        exception = vm->throwException(
+            globalObject->globalExec(),
+            error.toErrorObject(globalObject, executable->m_source));
+        return 0;
+    }
+    
+    SourceProvider* provider = executable->source().provider();
+    unsigned sourceOffset = executable->source().startOffset();
+    unsigned startColumn = executable->source().startColumn();
+
+    return adoptRef(new FunctionCodeBlock(
+        executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
+}
+
+PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor(
+    CodeSpecializationKind kind)
+{
+    if (classInfo() == EvalExecutable::info()) {
+        RELEASE_ASSERT(kind == CodeForCall);
+        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
+        RefPtr<EvalCodeBlock> result = adoptRef(new EvalCodeBlock(
+            CodeBlock::CopyParsedBlock, *executable->m_evalCodeBlock));
+        result->setAlternative(executable->m_evalCodeBlock);
+        return result;
+    }
+    
+    if (classInfo() == ProgramExecutable::info()) {
+        RELEASE_ASSERT(kind == CodeForCall);
+        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
+        RefPtr<ProgramCodeBlock> result = adoptRef(new ProgramCodeBlock(
+            CodeBlock::CopyParsedBlock, *executable->m_programCodeBlock));
+        result->setAlternative(executable->m_programCodeBlock);
+        return result;
+    }
+
+    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
+    FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
+    RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(
+        CodeBlock::CopyParsedBlock, *executable->codeBlockFor(kind)));
+    result->setAlternative(executable->codeBlockFor(kind));
+    return result;
+}
+
+JSObject* ScriptExecutable::prepareForExecutionImpl(
+    ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
+{
+    VM& vm = exec->vm();
+    DeferGC deferGC(vm.heap);
+    
+    JSObject* exception = 0;
+    RefPtr<CodeBlock> codeBlock = newCodeBlockFor(kind, scope, exception);
+    if (!codeBlock) {
+        RELEASE_ASSERT(exception);
+        return exception;
+    }
+    
+    JITCode::JITType jitType;
+#if ENABLE(LLINT)
+    jitType = JITCode::InterpreterThunk;
+#else
+    jitType = JITCode::BaselineJIT;
+#endif
+    codeBlock->prepareForExecution(exec, jitType);
+
+    installCode(codeBlock.get());
+    return 0;
+}
+
 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
 
 EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext) 
 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
 
 EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext) 
@@ -176,28 +358,6 @@ void FunctionExecutable::destroy(JSCell* cell)
     static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
 }
 
     static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
 }
 
-#if ENABLE(DFG_JIT)
-JSObject* EvalExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
-{
-    ASSERT(exec->vm().dynamicGlobalObject);
-    ASSERT(!!m_evalCodeBlock);
-    JSObject* error = 0;
-    if (!JITCode::isOptimizingJIT(m_evalCodeBlock->jitType()))
-        error = compileInternal(exec, scope, JITCode::nextTierJIT(m_evalCodeBlock->jitType()), &result, bytecodeIndex);
-    else
-        result = CompilationNotNeeded;
-    ASSERT(!!m_evalCodeBlock);
-    return error;
-}
-#endif // ENABLE(DFG_JIT)
-
-#if ENABLE(JIT)
-CompilationResult EvalExecutable::jitCompile(ExecState* exec)
-{
-    return jitCompileIfAppropriate(exec, m_evalCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
-}
-#endif
-
 inline const char* samplingDescription(JITCode::JITType jitType)
 {
     switch (jitType) {
 inline const char* samplingDescription(JITCode::JITType jitType)
 {
     switch (jitType) {
@@ -215,39 +375,6 @@ inline const char* samplingDescription(JITCode::JITType jitType)
     }
 }
 
     }
 }
 
-JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
-{
-    SamplingRegion samplingRegion(samplingDescription(jitType));
-    
-    if (result)
-        *result = CompilationFailed;
-    
-    RefPtr<EvalCodeBlock> newCodeBlock;
-    
-    if (!!m_evalCodeBlock) {
-        newCodeBlock = adoptRef(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
-        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock));
-    } else {
-        newCodeBlock = adoptRef(new EvalCodeBlock(this, m_unlinkedEvalCodeBlock.get(), scope, source().provider()));
-        ASSERT((jitType == JITCode::bottomTierJIT()) == !m_evalCodeBlock);
-    }
-
-    CompilationResult theResult = prepareForExecution(
-        exec, m_evalCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);
-    if (result)
-        *result = theResult;
-
-    return 0;
-}
-
-#if ENABLE(DFG_JIT)
-CompilationResult EvalExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
-{
-    return JSC::replaceWithDeferredOptimizedCode(
-        plan, m_evalCodeBlock, m_jitCodeForCall, 0, 0);
-}
-#endif // ENABLE(DFG_JIT)
-
 #if ENABLE(JIT)
 void EvalExecutable::jettisonOptimizedCode(VM& vm)
 {
 #if ENABLE(JIT)
 void EvalExecutable::jettisonOptimizedCode(VM& vm)
 {
@@ -298,60 +425,6 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
     return error.toErrorObject(lexicalGlobalObject, m_source);
 }
 
     return error.toErrorObject(lexicalGlobalObject, m_source);
 }
 
-#if ENABLE(DFG_JIT)
-JSObject* ProgramExecutable::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
-{
-    RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-    ASSERT(!!m_programCodeBlock);
-    JSObject* error = 0;
-    if (!JITCode::isOptimizingJIT(m_programCodeBlock->jitType()))
-        error = compileInternal(exec, scope, JITCode::nextTierJIT(m_programCodeBlock->jitType()), &result, bytecodeIndex);
-    else
-        result = CompilationNotNeeded;
-    ASSERT(!!m_programCodeBlock);
-    return error;
-}
-#endif // ENABLE(DFG_JIT)
-
-#if ENABLE(JIT)
-CompilationResult ProgramExecutable::jitCompile(ExecState* exec)
-{
-    return jitCompileIfAppropriate(exec, m_programCodeBlock.get(), m_jitCodeForCall, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
-}
-#endif
-
-JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
-{
-    SamplingRegion samplingRegion(samplingDescription(jitType));
-    
-    if (result)
-        *result = CompilationFailed;
-    
-    RefPtr<ProgramCodeBlock> newCodeBlock;
-    
-    if (!!m_programCodeBlock) {
-        newCodeBlock = adoptRef(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));
-        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock));
-    } else {
-        newCodeBlock = adoptRef(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), scope, source().provider(), source().startColumn()));
-    }
-
-    CompilationResult theResult = prepareForExecution(
-        exec, m_programCodeBlock, newCodeBlock.get(), m_jitCodeForCall, jitType, bytecodeIndex);
-    if (result)
-        *result = theResult;
-
-    return 0;
-}
-
-#if ENABLE(DFG_JIT)
-CompilationResult ProgramExecutable::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan)
-{
-    return JSC::replaceWithDeferredOptimizedCode(
-        plan, m_programCodeBlock, m_jitCodeForCall, 0, 0);
-}
-#endif // ENABLE(DFG_JIT)
-
 #if ENABLE(JIT)
 void ProgramExecutable::jettisonOptimizedCode(VM& vm)
 {
 #if ENABLE(JIT)
 void ProgramExecutable::jettisonOptimizedCode(VM& vm)
 {
@@ -444,141 +517,6 @@ FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKi
     return result;
 }
 
     return result;
 }
 
-#if ENABLE(DFG_JIT)
-JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
-{
-    RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-    ASSERT(!!m_codeBlockForCall);
-    JSObject* error = 0;
-    if (!JITCode::isOptimizingJIT(m_codeBlockForCall->jitType()))
-        error = compileForCallInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForCall->jitType()), &result, bytecodeIndex);
-    else
-        result = CompilationNotNeeded;
-    ASSERT(!!m_codeBlockForCall);
-    return error;
-}
-
-JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
-{
-    RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-    ASSERT(!!m_codeBlockForConstruct);
-    JSObject* error = 0;
-    if (!JITCode::isOptimizingJIT(m_codeBlockForConstruct->jitType()))
-        error = compileForConstructInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForConstruct->jitType()), &result, bytecodeIndex);
-    else
-        result = CompilationNotNeeded;
-    ASSERT(!!m_codeBlockForConstruct);
-    return error;
-}
-#endif // ENABLE(DFG_JIT)
-
-#if ENABLE(JIT)
-CompilationResult FunctionExecutable::jitCompileForCall(ExecState* exec)
-{
-    return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
-}
-
-CompilationResult FunctionExecutable::jitCompileForConstruct(ExecState* exec)
-{
-    return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);
-}
-#endif
-
-PassRefPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)
-{
-    RefPtr<FunctionCodeBlock> alternative = codeBlockFor(specializationKind);
-    
-    if (!!alternative) {
-        RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
-        result->setAlternative(alternative);
-        return result.release();
-    }
-
-    VM* vm = scope->vm();
-    JSGlobalObject* globalObject = scope->globalObject();
-    ParserError error;
-    DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
-    ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
-    UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, m_source, specializationKind, debuggerMode, profilerMode, error);
-    recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());
-
-    if (!unlinkedCodeBlock) {
-        exception = vm->throwException(globalObject->globalExec(), error.toErrorObject(globalObject, m_source));
-        return 0;
-    }
-
-    SourceProvider* provider = source().provider();
-    unsigned sourceOffset = source().startOffset();
-    unsigned startColumn = source().startColumn();
-
-    return adoptRef(new FunctionCodeBlock(this, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
-}
-
-
-JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
-{
-    SamplingRegion samplingRegion(samplingDescription(jitType));
-    
-    if (result)
-        *result = CompilationFailed;
-    
-    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);
-    JSObject* exception = 0;
-    
-    RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception);
-    if (!newCodeBlock)
-        return exception;
-    
-    CompilationResult theResult = prepareFunctionForExecution(
-        exec, m_codeBlockForCall, newCodeBlock.get(), m_jitCodeForCall,
-        m_jitCodeForCallWithArityCheck, m_numParametersForCall, jitType,
-        bytecodeIndex, CodeForCall);
-    if (result)
-        *result = theResult;
-    return 0;
-}
-
-#if ENABLE(DFG_JIT)
-CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan> plan)
-{
-    return JSC::replaceWithDeferredOptimizedCode(
-        plan, m_codeBlockForCall, m_jitCodeForCall, &m_jitCodeForCallWithArityCheck,
-        &m_numParametersForCall);
-}
-#endif // ENABLE(DFG_JIT)
-
-JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, CompilationResult* result, unsigned bytecodeIndex)
-{
-    SamplingRegion samplingRegion(samplingDescription(jitType));
-    
-    if (result)
-        *result = CompilationFailed;
-    
-    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);
-    JSObject* exception = 0;
-    RefPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception);
-    if (!newCodeBlock)
-        return exception;
-
-    CompilationResult theResult = prepareFunctionForExecution(
-        exec, m_codeBlockForConstruct, newCodeBlock.get(), m_jitCodeForConstruct,
-        m_jitCodeForConstructWithArityCheck, m_numParametersForConstruct, jitType,
-        bytecodeIndex, CodeForConstruct);
-    if (result)
-        *result = theResult;
-
-    return 0;
-}
-
-#if ENABLE(DFG_JIT)
-CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan> plan)
-{
-    return JSC::replaceWithDeferredOptimizedCode(
-        plan, m_codeBlockForConstruct, m_jitCodeForConstruct,
-        &m_jitCodeForConstructWithArityCheck, &m_numParametersForConstruct);
-}
-#endif // ENABLE(DFG_JIT)
-
 #if ENABLE(JIT)
 void FunctionExecutable::jettisonOptimizedCodeForCall(VM& vm)
 {
 #if ENABLE(JIT)
 void FunctionExecutable::jettisonOptimizedCodeForCall(VM& vm)
 {
index 5d306aa..a031bb4 100644 (file)
@@ -161,6 +161,23 @@ public:
         return generatedJITCodeForConstructWithArityCheck();
     }
         
         return generatedJITCodeForConstructWithArityCheck();
     }
         
+    static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
+    {
+        if (kind == CodeForCall)
+            return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
+        ASSERT(kind == CodeForConstruct);
+        return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
+    }
+        
+    static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
+    {
+        if (kind == CodeForCall)
+            return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
+        ASSERT(kind == CodeForConstruct);
+        return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
+    }
+#endif // ENABLE(JIT)
+
     bool hasJITCodeForCall() const
     {
         return m_numParametersForCall >= 0;
     bool hasJITCodeForCall() const
     {
         return m_numParametersForCall >= 0;
@@ -179,23 +196,6 @@ public:
         return hasJITCodeForConstruct();
     }
 
         return hasJITCodeForConstruct();
     }
 
-    static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
-    {
-        if (kind == CodeForCall)
-            return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
-        ASSERT(kind == CodeForConstruct);
-        return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
-    }
-        
-    static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
-    {
-        if (kind == CodeForCall)
-            return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
-        ASSERT(kind == CodeForConstruct);
-        return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
-    }
-#endif // ENABLE(JIT)
-
     // Intrinsics are only for calls, currently.
     Intrinsic intrinsic() const;
         
     // Intrinsics are only for calls, currently.
     Intrinsic intrinsic() const;
         
@@ -244,6 +244,7 @@ public:
         return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter);
 #endif
     }
         return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter);
 #endif
     }
+    
 #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
 
 protected:
 #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
 
 protected:
@@ -402,6 +403,20 @@ public:
         m_startColumn = startColumn;
     }
 
         m_startColumn = startColumn;
     }
 
+    void installCode(CodeBlock*);
+    PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception);
+    PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
+    
+    JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
+    {
+        if (hasJITCodeFor(kind))
+            return 0;
+        return prepareForExecutionImpl(exec, scope, kind);
+    }
+
+private:
+    JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind);
+
 protected:
     void finishCreation(VM& vm)
     {
 protected:
     void finishCreation(VM& vm)
     {
@@ -430,24 +445,8 @@ public:
 
     static void destroy(JSCell*);
 
 
     static void destroy(JSCell*);
 
-    JSObject* compile(ExecState* exec, JSScope* scope)
-    {
-        RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-        JSObject* error = 0;
-        if (!m_evalCodeBlock)
-            error = compileInternal(exec, scope, JITCode::bottomTierJIT());
-        ASSERT(!error == !!m_evalCodeBlock);
-        return error;
-    }
-        
-#if ENABLE(DFG_JIT)
-    JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-        
 #if ENABLE(JIT)
     void jettisonOptimizedCode(VM&);
 #if ENABLE(JIT)
     void jettisonOptimizedCode(VM&);
-    CompilationResult jitCompile(ExecState*);
 #endif
 
     EvalCodeBlock& generatedBytecode()
 #endif
 
     EvalCodeBlock& generatedBytecode()
@@ -481,10 +480,10 @@ public:
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
 
 private:
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
 
 private:
+    friend class ScriptExecutable;
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     EvalExecutable(ExecState*, const SourceCode&, bool);
 
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     EvalExecutable(ExecState*, const SourceCode&, bool);
 
-    JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
     static void visitChildren(JSCell*, SlotVisitor&);
 
     RefPtr<EvalCodeBlock> m_evalCodeBlock;
     static void visitChildren(JSCell*, SlotVisitor&);
 
     RefPtr<EvalCodeBlock> m_evalCodeBlock;
@@ -508,24 +507,8 @@ public:
 
     static void destroy(JSCell*);
 
 
     static void destroy(JSCell*);
 
-    JSObject* compile(ExecState* exec, JSScope* scope)
-    {
-        RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-        JSObject* error = 0;
-        if (!m_programCodeBlock)
-            error = compileInternal(exec, scope, JITCode::bottomTierJIT());
-        ASSERT(!error == !!m_programCodeBlock);
-        return error;
-    }
-
-#if ENABLE(DFG_JIT)
-    JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-        
 #if ENABLE(JIT)
     void jettisonOptimizedCode(VM&);
 #if ENABLE(JIT)
     void jettisonOptimizedCode(VM&);
-    CompilationResult jitCompile(ExecState*);
 #endif
 
     ProgramCodeBlock& generatedBytecode()
 #endif
 
     ProgramCodeBlock& generatedBytecode()
@@ -557,11 +540,12 @@ public:
     ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
 
 private:
     ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
 
 private:
+    friend class ScriptExecutable;
+    
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
 
     ProgramExecutable(ExecState*, const SourceCode&);
 
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
 
     ProgramExecutable(ExecState*, const SourceCode&);
 
-    JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
     static void visitChildren(JSCell*, SlotVisitor&);
 
     WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
     static void visitChildren(JSCell*, SlotVisitor&);
 
     WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
@@ -600,26 +584,8 @@ public:
         return *m_codeBlockForConstruct;
     }
         
         return *m_codeBlockForConstruct;
     }
         
-    PassRefPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);
-
-    JSObject* compileForCall(ExecState* exec, JSScope* scope)
-    {
-        RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-        JSObject* error = 0;
-        if (!m_codeBlockForCall)
-            error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT());
-        ASSERT(!error == !!m_codeBlockForCall);
-        return error;
-    }
-
-#if ENABLE(DFG_JIT)
-    JSObject* compileOptimizedForCall(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    CompilationResult replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-        
 #if ENABLE(JIT)
     void jettisonOptimizedCodeForCall(VM&);
 #if ENABLE(JIT)
     void jettisonOptimizedCodeForCall(VM&);
-    CompilationResult jitCompileForCall(ExecState*);
 #endif
 
     bool isGeneratedForCall() const
 #endif
 
     bool isGeneratedForCall() const
@@ -633,24 +599,8 @@ public:
         return *m_codeBlockForCall;
     }
 
         return *m_codeBlockForCall;
     }
 
-    JSObject* compileForConstruct(ExecState* exec, JSScope* scope)
-    {
-        RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
-        JSObject* error = 0;
-        if (!m_codeBlockForConstruct)
-            error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT());
-        ASSERT(!error == !!m_codeBlockForConstruct);
-        return error;
-    }
-
-#if ENABLE(DFG_JIT)
-    JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
-    CompilationResult replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan>);
-#endif // ENABLE(DFG_JIT)
-        
 #if ENABLE(JIT)
     void jettisonOptimizedCodeForConstruct(VM&);
 #if ENABLE(JIT)
     void jettisonOptimizedCodeForConstruct(VM&);
-    CompilationResult jitCompileForConstruct(ExecState*);
 #endif
 
     bool isGeneratedForConstruct() const
 #endif
 
     bool isGeneratedForConstruct() const
@@ -664,39 +614,6 @@ public:
         return *m_codeBlockForConstruct;
     }
         
         return *m_codeBlockForConstruct;
     }
         
-    JSObject* compileFor(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
-    {
-        ASSERT(exec->callee());
-        ASSERT(exec->callee()->inherits(JSFunction::info()));
-        ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
-
-        if (kind == CodeForCall)
-            return compileForCall(exec, scope);
-        ASSERT(kind == CodeForConstruct);
-        return compileForConstruct(exec, scope);
-    }
-        
-#if ENABLE(DFG_JIT)
-    JSObject* compileOptimizedFor(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex, CodeSpecializationKind kind)
-    {
-        ASSERT(exec->callee());
-        ASSERT(exec->callee()->inherits(JSFunction::info()));
-        ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
-            
-        if (kind == CodeForCall)
-            return compileOptimizedForCall(exec, scope, result, bytecodeIndex);
-        ASSERT(kind == CodeForConstruct);
-        return compileOptimizedForConstruct(exec, scope, result, bytecodeIndex);
-    }
-        
-    CompilationResult replaceWithDeferredOptimizedCodeFor(PassRefPtr<DFG::Plan> plan, CodeSpecializationKind kind)
-    {
-        if (kind == CodeForCall)
-            return replaceWithDeferredOptimizedCodeForCall(plan);
-        return replaceWithDeferredOptimizedCodeForConstruct(plan);
-    }
-#endif // ENABLE(DFG_JIT)
-
 #if ENABLE(JIT)
     void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
     {
 #if ENABLE(JIT)
     void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
     {
@@ -707,14 +624,6 @@ public:
             jettisonOptimizedCodeForConstruct(vm);
         }
     }
             jettisonOptimizedCodeForConstruct(vm);
         }
     }
-        
-    CompilationResult jitCompileFor(ExecState* exec, CodeSpecializationKind kind)
-    {
-        if (kind == CodeForCall)
-            return jitCompileForCall(exec);
-        ASSERT(kind == CodeForConstruct);
-        return jitCompileForConstruct(exec);
-    }
 #endif
         
     bool isGeneratedFor(CodeSpecializationKind kind)
 #endif
         
     bool isGeneratedFor(CodeSpecializationKind kind)
@@ -764,9 +673,6 @@ public:
 private:
     FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
 
 private:
     FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
 
-    JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
-    JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX);
-        
     RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
     {
         if (kind == CodeForCall)
     RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
     {
         if (kind == CodeForCall)
@@ -786,6 +692,8 @@ private:
         return false;
     }
 
         return false;
     }
 
+    friend class ScriptExecutable;
+
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
     RefPtr<FunctionCodeBlock> m_codeBlockForCall;
     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
     RefPtr<FunctionCodeBlock> m_codeBlockForCall;
diff --git a/Source/JavaScriptCore/runtime/ExecutionHarness.h b/Source/JavaScriptCore/runtime/ExecutionHarness.h
deleted file mode 100644 (file)
index 22d77e5..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ExecutionHarness_h
-#define ExecutionHarness_h
-
-#include <wtf/Platform.h>
-
-#include "CompilationResult.h"
-#include "DFGDriver.h"
-#include "DFGPlan.h"
-#include "JITDriver.h"
-#include "LLIntEntrypoints.h"
-
-namespace JSC {
-
-template<typename CodeBlockType>
-inline CompilationResult prepareForExecutionImpl(
-    ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
-    JITCode::JITType jitType, unsigned bytecodeIndex)
-{
-    UNUSED_PARAM(bytecodeIndex);
-#if ENABLE(LLINT)
-    if (JITCode::isBaselineCode(jitType)) {
-        // Start off in the low level interpreter.
-        LLInt::getEntrypoint(exec->vm(), codeBlock, jitCode);
-        if (exec->vm().m_perBytecodeProfiler)
-            exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock);
-        return CompilationSuccessful;
-    }
-#endif // ENABLE(LLINT)
-#if ENABLE(JIT)
-    return jitCompileIfAppropriateImpl(
-        exec, codeBlock, jitCode, jitType, bytecodeIndex,
-        JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
-#endif
-    RELEASE_ASSERT_NOT_REACHED();
-    return CompilationFailed;
-}
-
-inline CompilationResult prepareFunctionForExecutionImpl(
-    ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
-    MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
-    unsigned bytecodeIndex, CodeSpecializationKind kind)
-{
-    UNUSED_PARAM(bytecodeIndex);
-    UNUSED_PARAM(jitCodeWithArityCheck);
-#if ENABLE(LLINT)
-    if (JITCode::isBaselineCode(jitType)) {
-        // Start off in the low level interpreter.
-        LLInt::getFunctionEntrypoint(exec->vm(), kind, jitCode, jitCodeWithArityCheck);
-        if (exec->vm().m_perBytecodeProfiler)
-            exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock);
-        return CompilationSuccessful;
-    }
-#else
-    UNUSED_PARAM(kind);
-#endif // ENABLE(LLINT)
-#if ENABLE(JIT)
-    return jitCompileFunctionIfAppropriateImpl(
-        exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex,
-        JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
-#endif
-    RELEASE_ASSERT_NOT_REACHED();
-    return CompilationFailed;
-}
-
-template<typename CodeBlockType>
-inline CompilationResult installOptimizedCode(
-    CompilationResult result, RefPtr<CodeBlockType>& sink, CodeBlockType* codeBlock,
-    PassRefPtr<JITCode> jitCode, MacroAssemblerCodePtr jitCodeWithArityCheck,
-    int* numParameters)
-{
-    UNUSED_PARAM(jitCodeWithArityCheck);
-    if (result != CompilationSuccessful)
-        return result;
-    
-#if ENABLE(JIT)
-    codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
-#endif
-
-    sink = codeBlock;
-    
-    if (numParameters)
-        *numParameters = codeBlock->numParameters();
-    
-    if (jitCode)
-        codeBlock->vm()->heap.reportExtraMemoryCost(sizeof(*codeBlock) + jitCode->size());
-    else
-        codeBlock->vm()->heap.reportExtraMemoryCost(sizeof(*codeBlock));
-    
-    if (sink != codeBlock) {
-        // This can happen if we GC and decide that the code is invalid.
-        return CompilationInvalidated;
-    }
-    
-    return result;
-}
-
-template<typename CodeBlockType>
-inline CompilationResult prepareForExecution(
-    ExecState* exec, RefPtr<CodeBlockType>& sink, CodeBlockType* codeBlock,
-    RefPtr<JITCode>& jitCode, JITCode::JITType jitType, unsigned bytecodeIndex)
-{
-    CompilationResult result = prepareForExecutionImpl(exec, codeBlock, jitCode, jitType, bytecodeIndex);
-    return installOptimizedCode(result, sink, codeBlock, jitCode, MacroAssemblerCodePtr(), 0);
-}
-
-inline CompilationResult prepareFunctionForExecution(
-    ExecState* exec, RefPtr<FunctionCodeBlock>& sink, FunctionCodeBlock* codeBlock,
-    RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck,
-    int& numParameters, JITCode::JITType jitType, unsigned bytecodeIndex,
-    CodeSpecializationKind kind)
-{
-    CompilationResult result = prepareFunctionForExecutionImpl(exec, codeBlock,
-        jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, kind);
-    return installOptimizedCode(result, sink, codeBlock, jitCode, jitCodeWithArityCheck, &numParameters);
-}
-
-#if ENABLE(DFG_JIT)
-template<typename CodeBlockType>
-inline CompilationResult replaceWithDeferredOptimizedCode(
-    PassRefPtr<DFG::Plan> passedPlan, RefPtr<CodeBlockType>& sink, RefPtr<JITCode>& jitCode,
-    MacroAssemblerCodePtr* jitCodeWithArityCheck, int* numParameters)
-{
-    RefPtr<DFG::Plan> plan = passedPlan;
-    CompilationResult result = DFG::tryFinalizePlan(plan, jitCode, jitCodeWithArityCheck);
-    if (Options::verboseOSR()) {
-        dataLog(
-            "Deferred optimizing compilation ", *plan->key(), " -> ", *plan->codeBlock,
-            " result: ", result, "\n");
-    }
-    if (result == CompilationSuccessful)
-        plan->codeBlock->alternative()->unlinkIncomingCalls();
-    return installOptimizedCode(
-        result, sink, static_cast<CodeBlockType*>(plan->codeBlock.get()), jitCode,
-        jitCodeWithArityCheck ? *jitCodeWithArityCheck : MacroAssemblerCodePtr(),
-        numParameters);
-}
-#endif // ENABLE(DFG_JIT)
-
-} // namespace JSC
-
-#endif // ExecutionHarness_h
-