Unreviewed, rolling out r154804.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Aug 2013 16:41:07 +0000 (16:41 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Aug 2013 16:41:07 +0000 (16:41 +0000)
http://trac.webkit.org/changeset/154804
https://bugs.webkit.org/show_bug.cgi?id=120477

Broke Windows build (assumes LLInt features not enabled on
this build) (Requested by bfulgham on #webkit).

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::linkIncomingCall):
(JSC::CodeBlock::unlinkIncomingCalls):
(JSC::CodeBlock::reoptimize):
(JSC::ProgramCodeBlock::replacement):
(JSC::EvalCodeBlock::replacement):
(JSC::FunctionCodeBlock::replacement):
(JSC::ProgramCodeBlock::compileOptimized):
(JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::EvalCodeBlock::compileOptimized):
(JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::FunctionCodeBlock::compileOptimized):
(JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::ProgramCodeBlock::jitCompileImpl):
(JSC::EvalCodeBlock::jitCompileImpl):
(JSC::FunctionCodeBlock::jitCompileImpl):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::jitType):
(JSC::CodeBlock::jitCompile):
* bytecode/DeferredCompilationCallback.cpp: Removed.
* bytecode/DeferredCompilationCallback.h: Removed.
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
* dfg/DFGDriver.h:
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
* dfg/DFGFailedFinalizer.cpp:
(JSC::DFG::FailedFinalizer::finalize):
(JSC::DFG::FailedFinalizer::finalizeFunction):
* dfg/DFGFailedFinalizer.h:
* dfg/DFGFinalizer.h:
* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalize):
(JSC::DFG::JITFinalizer::finalizeFunction):
* dfg/DFGJITFinalizer.h:
* dfg/DFGOSRExitPreparation.cpp:
(JSC::DFG::prepareCodeOriginForOSRExit):
* dfg/DFGOperations.cpp:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::compileInThreadImpl):
(JSC::DFG::Plan::finalize):
* dfg/DFGPlan.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::completeAllReadyPlansForVM):
(JSC::DFG::Worklist::runThread):
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalize):
(JSC::FTL::JITFinalizer::finalizeFunction):
* ftl/FTLJITFinalizer.h:
* heap/Heap.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* jit/JITDriver.h: Added.
(JSC::jitCompileIfAppropriateImpl):
(JSC::jitCompileFunctionIfAppropriateImpl):
(JSC::jitCompileIfAppropriate):
(JSC::jitCompileFunctionIfAppropriate):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
(JSC::jitCompileFor):
(JSC::lazyLinkFor):
* jit/JITToDFGDeferredCompilationCallback.cpp: Removed.
* jit/JITToDFGDeferredCompilationCallback.h: Removed.
* llint/LLIntEntrypoints.cpp:
(JSC::LLInt::getFunctionEntrypoint):
(JSC::LLInt::getEvalEntrypoint):
(JSC::LLInt::getProgramEntrypoint):
* llint/LLIntEntrypoints.h:
(JSC::LLInt::getEntrypoint):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::setUpCall):
* runtime/ArrayPrototype.cpp:
(JSC::isNumericCompareFunction):
* runtime/CommonSlowPaths.cpp:
* runtime/CompilationResult.cpp:
(WTF::printInternal):
* runtime/CompilationResult.h:
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileOptimized):
(JSC::EvalExecutable::jitCompile):
(JSC::EvalExecutable::compileInternal):
(JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
(JSC::ProgramExecutable::compileOptimized):
(JSC::ProgramExecutable::jitCompile):
(JSC::ProgramExecutable::compileInternal):
(JSC::ProgramExecutable::replaceWithDeferredOptimizedCode):
(JSC::FunctionExecutable::compileOptimizedForCall):
(JSC::FunctionExecutable::compileOptimizedForConstruct):
(JSC::FunctionExecutable::jitCompileForCall):
(JSC::FunctionExecutable::jitCompileForConstruct):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
* runtime/Executable.h:
(JSC::ExecutableBase::offsetOfJITCodeWithArityCheckFor):
(JSC::ExecutableBase::offsetOfNumParametersFor):
(JSC::ExecutableBase::catchRoutineFor):
(JSC::EvalExecutable::compile):
(JSC::ProgramExecutable::compile):
(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileForConstruct):
(JSC::FunctionExecutable::compileFor):
(JSC::FunctionExecutable::compileOptimizedFor):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
(JSC::FunctionExecutable::jitCompileFor):
* runtime/ExecutionHarness.h: Added.
(JSC::prepareForExecutionImpl):
(JSC::prepareFunctionForExecutionImpl):
(JSC::installOptimizedCode):
(JSC::prepareForExecution):
(JSC::prepareFunctionForExecution):
(JSC::replaceWithDeferredOptimizedCode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@154814 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 [deleted file]
Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h [deleted file]
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 [new file with mode: 0644]
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp [deleted file]
Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h [deleted file]
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 [new file with mode: 0644]

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