WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
almost there
blah.patch (text/plain), 58.68 KB, created by
Filip Pizlo
on 2013-08-27 13:48:09 PDT
(
hide
)
Description:
almost there
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-08-27 13:48:09 PDT
Size:
58.68 KB
patch
obsolete
>Index: Source/JavaScriptCore/bytecode/CodeBlock.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.cpp (revision 154632) >+++ Source/JavaScriptCore/bytecode/CodeBlock.cpp (working copy) >@@ -2689,6 +2689,54 @@ void CodeBlock::copyPostParseDataFromAlt > copyPostParseDataFrom(m_alternative.get()); > } > >+CompilationResult CodeBlock::prepareForExecution( >+ ExecState* exec, JITCode::JITType jitType, JITCompilationEffort effort, >+ unsigned bytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback) >+{ >+ VM& vm = exec->vm(); >+ >+ if (jitType == JITCode::InterpreterThunk) { >+ switch (codeType()) { >+ case GlobalCode: >+ LLInt::getEntrypoint(vm, static_cast<GlobalCodeBlock*>(this)); >+ break; >+ case EvalCode: >+ LLInt::getEntrypoint(vm, static_cast<EvalCodeBlock*>(this)); >+ break; >+ case FunctionCode: >+ LLInt::getFunctionEntrypoint(vm, static_cast<FunctionCodeBlock*>(this)); >+ break; >+ } >+ return CompilationSuccessful; >+ } >+ >+#if ENABLE(JIT) >+ if (JITCode::isOptimizingJIT(jitType)) { >+ ASSERT(effort == JITCompilationCanFail); >+ CompilationResult result = DFG::tryCompile(exec, this, bytecodeIndex, callback); >+ ASSERT(result != CompilationDeferred || callback); >+ return result; >+ } >+ >+ MacroAssemblerCodePtr jitCodeWithArityCheck; >+ RefPtr<JITCode> jitCode = JIT::compile(&vm, this, effort, &jitCodeWithArityCheck); >+ if (!jitCode) >+ return CompilationFailed; >+ codeBlock->setJITCode(jitCode, jitCodeWithArityCheck); >+ return CompilationSuccessful; >+#else >+ UNUSED_PARAM(effort); >+ UNUSED_PARAM(bytecodeIndex); >+ UNUSED_PARAM(callback); >+ return CompilationFailed; >+#endif // ENABLE(JIT) >+} >+ >+void CodeBlock::install() >+{ >+ ownerExecutable()->installCode(this); >+} >+ > #if ENABLE(JIT) > void CodeBlock::reoptimize() > { >@@ -2726,11 +2774,6 @@ JSObject* ProgramCodeBlock::compileOptim > return error; > } > >-CompilationResult ProgramCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<ProgramExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan); >-} >- > JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex) > { > if (JITCode::isHigherTier(replacement()->jitType(), jitType())) { >@@ -2741,11 +2784,6 @@ JSObject* EvalCodeBlock::compileOptimize > return error; > } > >-CompilationResult EvalCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<EvalExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCode(plan); >-} >- > JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex) > { > if (JITCode::isHigherTier(replacement()->jitType(), jitType())) { >@@ -2755,11 +2793,6 @@ JSObject* FunctionCodeBlock::compileOpti > JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, result, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall); > return error; > } >- >-CompilationResult FunctionCodeBlock::replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan> plan) >-{ >- return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall); >-} > #endif // ENABLE(DFG_JIT) > > DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal() >@@ -2804,27 +2837,6 @@ void FunctionCodeBlock::jettisonImpl() > { > static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall); > } >- >-CompilationResult ProgramCodeBlock::jitCompileImpl(ExecState* exec) >-{ >- ASSERT(jitType() == JITCode::InterpreterThunk); >- ASSERT(this == replacement()); >- return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec); >-} >- >-CompilationResult EvalCodeBlock::jitCompileImpl(ExecState* exec) >-{ >- ASSERT(jitType() == JITCode::InterpreterThunk); >- ASSERT(this == replacement()); >- return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec); >-} >- >-CompilationResult FunctionCodeBlock::jitCompileImpl(ExecState* exec) >-{ >- ASSERT(jitType() == JITCode::InterpreterThunk); >- ASSERT(this == replacement()); >- return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall); >-} > #endif > > JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin) >Index: Source/JavaScriptCore/bytecode/CodeBlock.h >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.h (revision 154632) >+++ Source/JavaScriptCore/bytecode/CodeBlock.h (working copy) >@@ -48,6 +48,7 @@ > #include "DFGOSREntry.h" > #include "DFGOSRExit.h" > #include "DFGVariableEventStream.h" >+#include "DeferredCompilationCallback.h" > #include "EvalCodeCache.h" > #include "ExecutionCounter.h" > #include "ExpressionRangeInfo.h" >@@ -292,17 +293,15 @@ public: > } > #if ENABLE(DFG_JIT) > virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0; >- virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0; > #endif // ENABLE(DFG_JIT) > void jettison(); >- CompilationResult jitCompile(ExecState* exec) >- { >- if (jitType() != JITCode::InterpreterThunk) { >- ASSERT(jitType() == JITCode::BaselineJIT); >- return CompilationNotNeeded; >- } >- return jitCompileImpl(exec); >- } >+ CompilationResult prepareForExecution( >+ ExecState*, JITCode::JITType, >+ JITCompilationEffort = JITCompilationMustSucceed, >+ unsigned bytecodeIndex = UINT_MAX, >+ PassRefPtr<DeferredCompilationCallback> = 0); >+ void install(); >+ > virtual CodeBlock* replacement() = 0; > > virtual DFG::CapabilityLevel capabilityLevelInternal() = 0; >@@ -969,7 +968,6 @@ public: > > protected: > #if ENABLE(JIT) >- virtual CompilationResult jitCompileImpl(ExecState*) = 0; > virtual void jettisonImpl() = 0; > #endif > virtual void visitWeakReferences(SlotVisitor&); >@@ -1196,11 +1194,9 @@ public: > 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 >@@ -1225,11 +1221,9 @@ public: > 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 >@@ -1254,11 +1248,9 @@ public: > protected: > #if ENABLE(DFG_JIT) > virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex); >- virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>); > #endif // ENABLE(DFG_JIT) > > virtual void jettisonImpl(); >- virtual CompilationResult jitCompileImpl(ExecState*); > virtual CodeBlock* replacement(); > virtual DFG::CapabilityLevel capabilityLevelInternal(); > #endif >Index: Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp (working copy) >@@ -0,0 +1,35 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "DeferredCompilationCallback.h" >+ >+namespace JSC { >+ >+DeferredCompilationCallback::DeferredCompilationCallback() { } >+DeferredCompilationCallback::~DeferredCompilationCallback() { } >+ >+} // JSC >+ >Index: Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h >=================================================================== >--- Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h (revision 0) >+++ Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h (working copy) >@@ -0,0 +1,47 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef DeferredCompilationCallback_h >+#define DeferredCompilationCallback_h >+ >+#include "CompilationResult.h" >+#include <wtf/RefCounted.h> >+ >+namespace JSC { >+ >+class CodeBlock; >+ >+class DeferredCompilationCallback : public RefCounted<DeferredCompilationCallback> { >+public: >+ DeferredCompilationCallback(); >+ virtual ~DeferredCompilationCallback(); >+ >+ virtual void compilationDidComplete(CodeBlock*, CompilationResult) = 0; >+}; >+ >+} // namespace JSC >+ >+#endif // DeferredCompilationCallback_h >+ >Index: Source/JavaScriptCore/dfg/DFGDriver.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDriver.cpp (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGDriver.cpp (working copy) >@@ -55,7 +55,7 @@ unsigned getNumCompilations() > return numCompilations; > } > >-static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex) >+CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback) > { > SamplingRegion samplingRegion("DFG Compilation (Driver)"); > >@@ -99,7 +99,7 @@ static CompilationResult compile(Compile > else > numVarsWithValues = 0; > RefPtr<Plan> plan = adoptRef( >- new Plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues)); >+ new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues)); > for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) { > int operand = plan->mustHandleValues.operandForIndex(i); > if (operandIsArgument(operand) >@@ -115,7 +115,8 @@ static CompilationResult compile(Compile > plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue(); > } > >- if (enableConcurrentJIT()) { >+ if (enableConcurrentJIT() && callback) { >+ plan->callback = callback; > if (!vm.worklist) > vm.worklist = globalWorklist(); > if (logCompilationChanges()) >@@ -125,22 +126,7 @@ static CompilationResult compile(Compile > } > > plan->compileInThread(*vm.dfgState); >- return plan->finalize(jitCode, jitCodeWithArityCheck); >-} >- >-CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex) >-{ >- return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex); >-} >- >-CompilationResult tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex) >-{ >- return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck, bytecodeIndex); >-} >- >-CompilationResult tryFinalizePlan(PassRefPtr<Plan> plan, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck) >-{ >- return plan->finalize(jitCode, jitCodeWithArityCheck); >+ return plan->finalizeWithoutNotifyingCallback(); > } > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGDriver.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDriver.h (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGDriver.h (working copy) >@@ -42,17 +42,9 @@ namespace DFG { > JS_EXPORT_PRIVATE unsigned getNumCompilations(); > > #if ENABLE(DFG_JIT) >-CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned bytecodeIndex); >-CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex); >-CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr* jitCodeWithArityCheck); >+CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>); > #else >-inline CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return CompilationFailed; } >-inline CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return CompilationFailed; } >-inline CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr*) >-{ >- UNREACHABLE_FOR_PLATFORM(); >- return CompilationFailed; >-} >+inline CompilationResult tryCompile(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>) { return CompilationFailed; } > #endif > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (working copy) >@@ -45,23 +45,23 @@ JITFinalizer::~JITFinalizer() > { > } > >-bool JITFinalizer::finalize(RefPtr<JSC::JITCode>& entry) >+bool JITFinalizer::finalize() > { > finalizeCommon(); > > m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); >- entry = m_jitCode; >+ m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr()); > > return true; > } > >-bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerCodePtr& withArityCheck) >+bool JITFinalizer::finalizeFunction() > { > finalizeCommon(); > >- withArityCheck = m_linkBuffer->locationOf(m_arityCheck); >+ MacroAssemblerCodePtr withArityCheck = m_linkBuffer->locationOf(m_arityCheck); > m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly()); >- entry = m_jitCode; >+ m_plan.codeBlock->setJITCode(m_jitCode, withArityCheck); > > return true; > } >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -80,10 +80,9 @@ static void dumpAndVerifyGraph(Graph& gr > } > > Plan::Plan( >- CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex, >+ PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex, > unsigned numVarsWithValues) >- : compileMode(compileMode) >- , vm(*passedCodeBlock->vm()) >+ : vm(*passedCodeBlock->vm()) > , codeBlock(passedCodeBlock) > , osrEntryBytecodeIndex(osrEntryBytecodeIndex) > , numVarsWithValues(numVarsWithValues) >@@ -208,7 +207,7 @@ Plan::CompilationPath Plan::compileInThr > > #if ENABLE(FTL_JIT) > if (Options::useExperimentalFTL() >- && compileMode == CompileFunction >+ && codeBlock->codeType() == FunctionCode > && FTL::canCompile(dfg)) { > > performCriticalEdgeBreaking(dfg); >@@ -255,12 +254,10 @@ Plan::CompilationPath Plan::compileInThr > dumpAndVerifyGraph(dfg, "Graph after optimization:"); > > JITCompiler dataFlowJIT(dfg); >- if (compileMode == CompileFunction) { >+ if (codeBlock->codeType() == FunctionCode) { > dataFlowJIT.compileFunction(); > dataFlowJIT.linkFunction(); > } else { >- ASSERT(compileMode == CompileOther); >- > dataFlowJIT.compile(); > dataFlowJIT.link(); > } >@@ -283,16 +280,16 @@ void Plan::reallyAdd(CommonData* commonD > writeBarriers.trigger(vm); > } > >-CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck) >+CompilationResult Plan::finalizeWithoutNotifyingCallback() > { > if (!isStillValid()) > return CompilationInvalidated; > > bool result; >- if (compileMode == CompileFunction) >- result = finalizer->finalizeFunction(jitCode, *jitCodeWithArityCheck); >+ if (codeBlock->codeType() == FunctionCode) >+ result = finalizer->finalizeFunction(); > else >- result = finalizer->finalize(jitCode); >+ result = finalizer->finalize(); > > if (!result) > return CompilationFailed; >@@ -302,6 +299,11 @@ CompilationResult Plan::finalize(RefPtr< > return CompilationSuccessful; > } > >+void Plan::finalizeAndNotifyCallback() >+{ >+ callback->compilationDidComplete(codeBlock, finalizeWithoutNotifyingCallback()); >+} >+ > CodeBlock* Plan::key() > { > return codeBlock->alternative(); >Index: Source/JavaScriptCore/dfg/DFGPlan.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.h (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGPlan.h (working copy) >@@ -48,23 +48,21 @@ namespace DFG { > > class LongLivedState; > >-enum CompileMode { CompileFunction, CompileOther }; >- > #if ENABLE(DFG_JIT) > > struct Plan : public ThreadSafeRefCounted<Plan> { > Plan( >- CompileMode compileMode, PassRefPtr<CodeBlock> codeBlock, >- unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues); >+ PassRefPtr<CodeBlock> codeBlock, unsigned osrEntryBytecodeIndex, >+ unsigned numVarsWithValues); > ~Plan(); > > void compileInThread(LongLivedState&); > >- CompilationResult finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck); >+ CompilationResult finalizeWithoutNotifyingCallback(); >+ void finalizeAndNotifyCallback(); > > CodeBlock* key(); > >- const CompileMode compileMode; > VM& vm; > RefPtr<CodeBlock> codeBlock; > const unsigned osrEntryBytecodeIndex; >@@ -86,6 +84,8 @@ struct Plan : public ThreadSafeRefCounte > > bool isCompiled; > >+ RefPtr<DeferredCompilationCallback> callback; >+ > private: > enum CompilationPath { FailPath, DFGPath, FTLPath }; > CompilationPath compileInThreadImpl(LongLivedState&); >Index: Source/JavaScriptCore/dfg/DFGWorklist.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGWorklist.cpp (revision 154632) >+++ Source/JavaScriptCore/dfg/DFGWorklist.cpp (working copy) >@@ -165,10 +165,7 @@ Worklist::State Worklist::completeAllRea > > RELEASE_ASSERT(plan->isCompiled); > >- CompilationResult compilationResult = >- profiledBlock->replaceWithDeferredOptimizedCode(plan); >- RELEASE_ASSERT(compilationResult != CompilationDeferred); >- profiledBlock->setOptimizationThresholdBasedOnCompilationResult(compilationResult); >+ plan->finalizeAndNotifyCallback(); > > if (profiledBlock == requestedProfiledBlock) > resultingState = Compiled; >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 154632) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -184,6 +184,8 @@ namespace JSC { > const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; } > > void addReference(JSCell*, ArrayBuffer*); >+ >+ bool isDeferred() const { return !!m_deferralDepth; } > > private: > friend class CodeBlock; >Index: Source/JavaScriptCore/jit/JITStubs.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITStubs.cpp (revision 154632) >+++ Source/JavaScriptCore/jit/JITStubs.cpp (working copy) >@@ -1019,7 +1019,7 @@ DEFINE_STUB_FUNCTION(void, optimize) > if (Options::verboseOSR()) > dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n"); > // If we have an optimized replacement, then it must be the case that we entered >- // cti_optimize from a loop. That's because is there's an optimized replacement, >+ // cti_optimize from a loop. That's because if there's an optimized replacement, > // then all calls to this function will be relinked to the replacement and so > // the prologue OSR will never fire. > >@@ -1054,13 +1054,12 @@ DEFINE_STUB_FUNCTION(void, optimize) > dataLog("Triggering optimized compilation of ", *codeBlock, "\n"); > > JSScope* scope = callFrame->scope(); >- CompilationResult result; >- JSObject* error = codeBlock->compileOptimized(callFrame, scope, result, bytecodeIndex); >- if (Options::verboseOSR()) { >+ RefPtr<DeferredCompilationCallback> callback = adoptRef( >+ new JITToDFGDeferredCompilationCallback()); >+ CompilationResult result = codeBlock->compileOptimized( >+ callFrame, JITCode::DFGJIT, JITCompilationCanFail, bytecodeIndex, callback); >+ if (Options::verboseOSR()) > dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n"); >- if (error) >- dataLog("WARNING: optimized compilation failed with a JS error.\n"); >- } > > codeBlock->setOptimizationThresholdBasedOnCompilationResult(result); > if (result != CompilationSuccessful) >Index: Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp (revision 0) >+++ Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp (working copy) >@@ -0,0 +1,49 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JITToDFGDeferredCompilationCallback.h" >+ >+#include "CodeBlock.h" >+#include "Executable.h" >+ >+namespace JSC { >+ >+JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback() { } >+JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback() { } >+ >+void JITToDFGDeferredCompilationCallback::compilationDidComplete( >+ CodeBlock* codeBlock, CompilationResult result) >+{ >+ ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT); >+ >+ if (result == CompilationSuccessful) >+ codeBlock->install(); >+ >+ codeBlock->alternative()->setOptimizationThresholdBaseOnCompilationResult(result); >+} >+ >+} // JSC >+ >Index: Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h >=================================================================== >--- Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h (revision 0) >+++ Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h (working copy) >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef JITToDFGDeferredCompilationCallback_h >+#define JITToDFGDeferredCompilationCallback_h >+ >+#include "DeferredCompilationCallback.h" >+ >+namespace JSC { >+ >+class ScriptExecutable; >+ >+class JITToDFGDeferredCompilationCallback : public DeferredCompilationCallback { >+public: >+ JITToDFGDeferredCompilationCallback(); >+ virtual ~JITToDFGDeferredCompilationCallback(); >+ >+ virtual void compilationDidComplete(CodeBlock*, CompilationResult); >+}; >+ >+} // namespace JSC >+ >+#endif // JITToDFGDeferredCompilationCallback_h >+ >Index: Source/JavaScriptCore/llint/LLIntEntrypoints.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntEntrypoints.cpp (revision 154632) >+++ Source/JavaScriptCore/llint/LLIntEntrypoints.cpp (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012 Apple Inc. All rights reserved. >+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -37,53 +37,67 @@ > > namespace JSC { namespace LLInt { > >-void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, RefPtr<JITCode>& jitCode, MacroAssemblerCodePtr& arityCheck) >+void getFunctionEntrypoint(VM& vm, FunctionCodeBlock* codeBlock) > { >+ CodeSpecializationKind kind = codeBlock->specializationKind(); >+ > if (!vm.canUseJIT()) { > if (kind == CodeForCall) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)); >- arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check)); > return; > } > > ASSERT(kind == CodeForConstruct); >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)); >- arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_construct_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_construct_arity_check)); > return; > } > > #if ENABLE(JIT) > if (kind == CodeForCall) { >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)); >- arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code(); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk)), >+ vm.getCTIStub(functionForCallArityCheckThunkGenerator).code()); > return; > } > > ASSERT(kind == CodeForConstruct); >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)); >- arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code(); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk)), >+ vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code()); > #endif // ENABLE(JIT) > } > >-void getEvalEntrypoint(VM& vm, RefPtr<JITCode>& jitCode) >+void getEvalEntrypoint(VM& vm, EvalCodeBlock* codeBlock) > { > if (!vm.canUseJIT()) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > return; > } >-#if ENABLE(JIT) >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)); >+#if ENABLE(JIT) >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > #endif > } > > void getProgramEntrypoint(VM& vm, RefPtr<JITCode>& jitCode) > { > if (!vm.canUseJIT()) { >- jitCode = adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > return; > } > #if ENABLE(JIT) >- jitCode = adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)), >+ MacroAssemblerCodePtr()); > #endif > } > >Index: Source/JavaScriptCore/llint/LLIntEntrypoints.h >=================================================================== >--- Source/JavaScriptCore/llint/LLIntEntrypoints.h (revision 154632) >+++ Source/JavaScriptCore/llint/LLIntEntrypoints.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012 Apple Inc. All rights reserved. >+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -44,18 +44,18 @@ class ProgramCodeBlock; > > namespace LLInt { > >-void getFunctionEntrypoint(VM&, CodeSpecializationKind, RefPtr<JITCode>&, MacroAssemblerCodePtr& arityCheck); >-void getEvalEntrypoint(VM&, RefPtr<JITCode>&); >-void getProgramEntrypoint(VM&, RefPtr<JITCode>&); >+void getFunctionEntrypoint(VM&, FunctionCodeBlock*); >+void getEvalEntrypoint(VM&, EvalCodeBlock*); >+void getProgramEntrypoint(VM&, ProgramCodeBlock*); > >-inline void getEntrypoint(VM& vm, EvalCodeBlock*, RefPtr<JITCode>& jitCode) >+inline void getEntrypoint(VM& vm, EvalCodeBlock* codeBlock) > { >- getEvalEntrypoint(vm, jitCode); >+ getEvalEntrypoint(vm, codeBlock); > } > >-inline void getEntrypoint(VM& vm, ProgramCodeBlock*, RefPtr<JITCode>& jitCode) >+inline void getEntrypoint(VM& vm, ProgramCodeBlock* codeBlock) > { >- getProgramEntrypoint(vm, jitCode); >+ getProgramEntrypoint(vm, codeBlock); > } > > } } // namespace JSC::LLInt >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (revision 154632) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (working copy) >@@ -288,23 +288,33 @@ inline bool jitCompileAndSetHeuristics(C > return false; > } > >- CompilationResult result = codeBlock->jitCompile(exec); >- switch (result) { >- case CompilationNotNeeded: >+ switch (codeBlock->jitType()) { >+ case JITCode::BaselineJIT: { > if (Options::verboseOSR()) > dataLogF(" Code was already compiled.\n"); > codeBlock->jitSoon(); > return true; >- case CompilationFailed: >- if (Options::verboseOSR()) >- dataLogF(" JIT compilation failed.\n"); >- codeBlock->dontJITAnytimeSoon(); >- return false; >- case CompilationSuccessful: >- if (Options::verboseOSR()) >- dataLogF(" JIT compilation successful.\n"); >- codeBlock->jitSoon(); >- return true; >+ } >+ case JITCode::InterpreterThunk: { >+ CompilationResult result = codeBlock->prepareForExecution( >+ exec, JITCode::BaselineJIT, JITCompilationCanFail); >+ switch (result) { >+ case CompilationFailed: >+ if (Options::verboseOSR()) >+ dataLogF(" JIT compilation failed.\n"); >+ codeBlock->dontJITAnytimeSoon(); >+ return false; >+ case CompilationSuccessful: >+ if (Options::verboseOSR()) >+ dataLogF(" JIT compilation successful.\n"); >+ codeBlock->install(); >+ codeBlock->jitSoon(); >+ return true; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ return false; >+ } >+ } > default: > RELEASE_ASSERT_NOT_REACHED(); > return false; >Index: Source/JavaScriptCore/runtime/CompilationResult.h >=================================================================== >--- Source/JavaScriptCore/runtime/CompilationResult.h (revision 154632) >+++ Source/JavaScriptCore/runtime/CompilationResult.h (working copy) >@@ -30,7 +30,29 @@ > > namespace JSC { > >-enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful, CompilationNotNeeded, CompilationDeferred }; >+enum CompilationResult { >+ // We tried to compile the code, but we couldn't compile it. This could be >+ // because we ran out of memory, or because the compiler encountered an >+ // internal error and decided to bail out gracefully. Either way, this implies >+ // that we shouldn't try to compile this code block again. >+ CompilationFailed, >+ >+ // The profiling assumptions that were fed into the compiler were invalidated >+ // even before we finished compiling. This means we should try again: in such >+ // cases the profiling will now be updated and the next compilation won't >+ // encounter the same problem. But it does mean that we should exercise >+ // exponential back-off, to get even more profiling so that new profiling >+ // pathologies aren't encountered. >+ CompilationInvalidated, >+ >+ // The compilation succeeded and the code block now has JITCode for the newly >+ // compiled code. >+ CompilationSuccessful, >+ >+ // We decided to do the compilation asynchronously. This means that we haven't >+ // yet compiled the code. >+ CompilationDeferred >+}; > > } // namespace JSC > >Index: Source/JavaScriptCore/runtime/Executable.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/Executable.cpp (revision 154632) >+++ Source/JavaScriptCore/runtime/Executable.cpp (working copy) >@@ -114,6 +114,182 @@ void ScriptExecutable::destroy(JSCell* c > } > #endif > >+void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) >+{ >+ VM& vm = *genericCodeBlock->vm(); >+ >+ if (vm.m_perBytecodeProfiler) >+ vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock); >+ >+ ASSERT(vm.heap.isDeferred()); >+ >+ if (jitCode) >+ vm.heap.reportExtraMemoryCost(sizeof(CodeBlock) + jitCode->size()); >+ else >+ vm.heap.reportExtraMemoryCost(sizeof(CodeBlock)); >+ >+ CodeSpecializationKind kind = genericCodeBlock->specializationKind(); >+ >+ RefPtr<CodeBlock> oldCodeBlock; >+ >+ switch (kind) { >+ case CodeForCall: >+ m_jitCodeForCall = codeBlock->jitCode(); >+ m_jitCodeForCallWithArityCheck = codeBlock->jitCodeWithArityCheck(); >+ m_numParametersForCall = codeBlock->numParameters(); >+ break; >+ case CodeForConstruct: >+ m_jitCodeForConstruct = codeBlock->jitCode(); >+ m_jitCodeForConstructWithArityCheck = codeBlock->jitCodeWithArityCheck(); >+ m_numParametersForConstruct = codeBlock->numParameters(); >+ break; >+ } >+ >+ switch (genericCodeBlock->codeType()) { >+ case GlobalCode: { >+ ProgramExecutable* executabe = jsCast<ProgramExecutable*>(this); >+ ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock); >+ >+ ASSERT(!codeBlock->jitCodeWithArityCheck()); >+ ASSERT(!codeBlock->numParameters()); >+ 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(!jitCodeWithArityCheck); >+ ASSERT(!codeBlock->numParameters()); >+ 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) >+{ >+ if (classInfo() == EvalExecutable::info()) { >+ RELEASE_ASSERT(kind == CodeForCall); >+ RELEASE_ASSERT(!executable->m_evalCodeBlock); >+ EvalExecutable* executable = jsCast<EvalExecutable*>(this); >+ return adoptRef(new EvalCodeBlock( >+ executable, executable->m_unlinkedEvalCodeBlock.get(), scope, >+ executable->source().provider())); >+ } >+ >+ if (classInfo() == ProgramExecutable::info()) { >+ RELEASE_ASSERT(kind == CodeForCall); >+ RELEASE_ASSERT(!executable->m_programCodeBlock); >+ ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); >+ 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)); >+ VM* vm = scope->vm(); >+ JSGlobalObject* globalObject = scope->globalObject(); >+ ParseError error; >+ DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff; >+ ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff; >+ UnlinkedFunctionCodeBlock* unlinkedCodeBlock = >+ executable->m_unlinkedExecutable->codeBlockFor( >+ *vm, executable->m_source, kind, debuggerMode, profilerMode, error); >+ if (!unlinkedCodeBlock) { >+ exception = error.toErrorObject(globalObject, executable->m_source); >+ return 0; >+ } >+ >+ SourceProvider* provider = executable->source().provider(); >+ unsigned sourceOffset = executable->source().startOffset(); >+ unsigned startColumn = executable->source().startColumn(); >+ >+ return adoptRef(new FunctionCodeBlock( >+ executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn)); >+} >+ >+PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor( >+ CodeSpecializationKind kind) >+{ >+ if (classInfo() == EvalExecutable::info()) { >+ RELEASE_ASSERT(kind == CodeForCall); >+ EvalExecutable* executable = jsCast<EvalExecutable*>(this); >+ RefPtr<EvalCodeBlock> result = adoptRef(new EvalCodeBlock( >+ CodeBlock::CopyParsedBlock, *executable->m_evalCodeBlock)); >+ result->setAlternative(executable->m_evalCodeBlock); >+ return result; >+ } >+ >+ if (classInfo() == ProgramExecutable::info()) { >+ RELEASE_ASSERT(kind == CodeForCall); >+ ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); >+ RefPtr<ProgramCodeBlock> result = adoptRef(new ProgramCodeBlock( >+ CodeBlock::CopyParsedBlock, *executable->m_evalCodeBlock)); >+ 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(); >+ 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) >@@ -240,14 +416,6 @@ JSObject* EvalExecutable::compileInterna > 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) > { >@@ -344,14 +512,6 @@ JSObject* ProgramExecutable::compileInte > 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) > { >@@ -538,15 +698,6 @@ JSObject* FunctionExecutable::compileFor > 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)); >@@ -570,15 +721,6 @@ JSObject* FunctionExecutable::compileFor > return 0; > } > >-#if ENABLE(DFG_JIT) >-CompilationResult FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan> plan) >-{ >- return JSC::replaceWithDeferredOptimizedCode( >- plan, m_codeBlockForConstruct, m_jitCodeForConstruct, >- &m_jitCodeForConstructWithArityCheck, &m_numParametersForConstruct); >-} >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void FunctionExecutable::jettisonOptimizedCodeForCall(VM& vm) > { >Index: Source/JavaScriptCore/runtime/Executable.h >=================================================================== >--- Source/JavaScriptCore/runtime/Executable.h (revision 154632) >+++ Source/JavaScriptCore/runtime/Executable.h (working copy) >@@ -244,6 +244,7 @@ public: > return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter); > #endif > } >+ > #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP) > > protected: >@@ -402,6 +403,20 @@ public: > m_startColumn = startColumn; > } > >+ void installCode(CodeBlock*); >+ PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception); >+ PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind); >+ >+ JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind) >+ { >+ if (hasJITCodeFor(kind)) >+ return 0; >+ return prepareForExecutionImpl(exec, scope, kind); >+ } >+ >+private: >+ JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind); >+ > protected: > void finishCreation(VM& vm) > { >@@ -430,24 +445,8 @@ public: > > static void destroy(JSCell*); > >- JSObject* compile(ExecState* exec, JSScope* scope) >- { >- RELEASE_ASSERT(exec->vm().dynamicGlobalObject); >- JSObject* error = 0; >- if (!m_evalCodeBlock) >- error = compileInternal(exec, scope, JITCode::bottomTierJIT()); >- ASSERT(!error == !!m_evalCodeBlock); >- return error; >- } >- >-#if ENABLE(DFG_JIT) >- JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex); >- CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>); >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void jettisonOptimizedCode(VM&); >- CompilationResult jitCompile(ExecState*); > #endif > > EvalCodeBlock& generatedBytecode() >@@ -481,10 +480,10 @@ public: > unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); } > > private: >+ friend class ScriptExecutable; > static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; > EvalExecutable(ExecState*, const SourceCode&, bool); > >- JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX); > static void visitChildren(JSCell*, SlotVisitor&); > > RefPtr<EvalCodeBlock> m_evalCodeBlock; >@@ -508,24 +507,8 @@ public: > > static void destroy(JSCell*); > >- JSObject* compile(ExecState* exec, JSScope* scope) >- { >- RELEASE_ASSERT(exec->vm().dynamicGlobalObject); >- JSObject* error = 0; >- if (!m_programCodeBlock) >- error = compileInternal(exec, scope, JITCode::bottomTierJIT()); >- ASSERT(!error == !!m_programCodeBlock); >- return error; >- } >- >-#if ENABLE(DFG_JIT) >- JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex); >- CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>); >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void jettisonOptimizedCode(VM&); >- CompilationResult jitCompile(ExecState*); > #endif > > ProgramCodeBlock& generatedBytecode() >@@ -557,11 +540,12 @@ public: > ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); } > > private: >+ friend class ScriptExecutable; >+ > static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; > > ProgramExecutable(ExecState*, const SourceCode&); > >- JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX); > static void visitChildren(JSCell*, SlotVisitor&); > > WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock; >@@ -602,24 +586,8 @@ public: > > PassRefPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception); > >- JSObject* compileForCall(ExecState* exec, JSScope* scope) >- { >- RELEASE_ASSERT(exec->vm().dynamicGlobalObject); >- JSObject* error = 0; >- if (!m_codeBlockForCall) >- error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT()); >- ASSERT(!error == !!m_codeBlockForCall); >- return error; >- } >- >-#if ENABLE(DFG_JIT) >- JSObject* compileOptimizedForCall(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex); >- CompilationResult replaceWithDeferredOptimizedCodeForCall(PassRefPtr<DFG::Plan>); >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void jettisonOptimizedCodeForCall(VM&); >- CompilationResult jitCompileForCall(ExecState*); > #endif > > bool isGeneratedForCall() const >@@ -633,24 +601,8 @@ public: > return *m_codeBlockForCall; > } > >- JSObject* compileForConstruct(ExecState* exec, JSScope* scope) >- { >- RELEASE_ASSERT(exec->vm().dynamicGlobalObject); >- JSObject* error = 0; >- if (!m_codeBlockForConstruct) >- error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT()); >- ASSERT(!error == !!m_codeBlockForConstruct); >- return error; >- } >- >-#if ENABLE(DFG_JIT) >- JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex); >- CompilationResult replaceWithDeferredOptimizedCodeForConstruct(PassRefPtr<DFG::Plan>); >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void jettisonOptimizedCodeForConstruct(VM&); >- CompilationResult jitCompileForConstruct(ExecState*); > #endif > > bool isGeneratedForConstruct() const >@@ -664,39 +616,6 @@ public: > return *m_codeBlockForConstruct; > } > >- JSObject* compileFor(ExecState* exec, JSScope* scope, CodeSpecializationKind kind) >- { >- ASSERT(exec->callee()); >- ASSERT(exec->callee()->inherits(JSFunction::info())); >- ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this); >- >- if (kind == CodeForCall) >- return compileForCall(exec, scope); >- ASSERT(kind == CodeForConstruct); >- return compileForConstruct(exec, scope); >- } >- >-#if ENABLE(DFG_JIT) >- JSObject* compileOptimizedFor(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex, CodeSpecializationKind kind) >- { >- ASSERT(exec->callee()); >- ASSERT(exec->callee()->inherits(JSFunction::info())); >- ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this); >- >- if (kind == CodeForCall) >- return compileOptimizedForCall(exec, scope, result, bytecodeIndex); >- ASSERT(kind == CodeForConstruct); >- return compileOptimizedForConstruct(exec, scope, result, bytecodeIndex); >- } >- >- CompilationResult replaceWithDeferredOptimizedCodeFor(PassRefPtr<DFG::Plan> plan, CodeSpecializationKind kind) >- { >- if (kind == CodeForCall) >- return replaceWithDeferredOptimizedCodeForCall(plan); >- return replaceWithDeferredOptimizedCodeForConstruct(plan); >- } >-#endif // ENABLE(DFG_JIT) >- > #if ENABLE(JIT) > void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind) > { >@@ -707,14 +626,6 @@ public: > jettisonOptimizedCodeForConstruct(vm); > } > } >- >- CompilationResult jitCompileFor(ExecState* exec, CodeSpecializationKind kind) >- { >- if (kind == CodeForCall) >- return jitCompileForCall(exec); >- ASSERT(kind == CodeForConstruct); >- return jitCompileForConstruct(exec); >- } > #endif > > bool isGeneratedFor(CodeSpecializationKind kind) >@@ -764,9 +675,6 @@ public: > private: > FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn); > >- JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX); >- JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, CompilationResult* = 0, unsigned bytecodeIndex = UINT_MAX); >- > RefPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind) > { > if (kind == CodeForCall) >@@ -786,6 +694,8 @@ private: > return false; > } > >+ friend class ScriptExecutable; >+ > static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; > WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable; > RefPtr<FunctionCodeBlock> m_codeBlockForCall; >Index: Source/JavaScriptCore/runtime/ExecutionHarness.h >=================================================================== >--- Source/JavaScriptCore/runtime/ExecutionHarness.h (revision 154632) >+++ Source/JavaScriptCore/runtime/ExecutionHarness.h (working copy) >@@ -45,7 +45,7 @@ inline CompilationResult prepareForExecu > #if ENABLE(LLINT) > if (JITCode::isBaselineCode(jitType)) { > // Start off in the low level interpreter. >- LLInt::getEntrypoint(exec->vm(), codeBlock, jitCode); >+ LLInt::getEntrypoint(exec->vm(), codeBlock); > if (exec->vm().m_perBytecodeProfiler) > exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock); > return CompilationSuccessful; >@@ -70,7 +70,7 @@ inline CompilationResult prepareFunction > #if ENABLE(LLINT) > if (JITCode::isBaselineCode(jitType)) { > // Start off in the low level interpreter. >- LLInt::getFunctionEntrypoint(exec->vm(), kind, jitCode, jitCodeWithArityCheck); >+ LLInt::getFunctionEntrypoint(exec->vm(), codeBlock); > if (exec->vm().m_perBytecodeProfiler) > exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock); > return CompilationSuccessful; >@@ -88,44 +88,15 @@ inline CompilationResult prepareFunction > } > > 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) >+ ExecState* exec, ExecutableBase* executable, CodeBlockType* codeBlock, >+ JITCode::JITType jitType, unsigned bytecodeIndex) > { > CompilationResult result = prepareForExecutionImpl(exec, codeBlock, jitCode, jitType, bytecodeIndex); >- return installOptimizedCode(result, sink, codeBlock, jitCode, MacroAssemblerCodePtr(), 0); >+ if (result != CompilationSuccessful) >+ return result; >+ executable->installCode(codeBlock); >+ return CompilationSuccessful; > } > > inline CompilationResult prepareFunctionForExecution( >@@ -136,7 +107,10 @@ inline CompilationResult prepareFunction > { > CompilationResult result = prepareFunctionForExecutionImpl(exec, codeBlock, > jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, kind); >- return installOptimizedCode(result, sink, codeBlock, jitCode, jitCodeWithArityCheck, &numParameters); >+ if (result != CompilationSuccessful) >+ return result; >+ executable->installCode(codeBlock); >+ return CompilationSuccessful; > } > > #if ENABLE(DFG_JIT)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 120326
:
209681
|
209794
|
209797
|
209834
|
209837
|
209845
|
209846