Commit 75afc4f8 authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: Executable and CodeBlock should be aware of DFG::Plans that complete asynchronously

https://bugs.webkit.org/show_bug.cgi?id=116350

Reviewed by Oliver Hunt.

This refactors compilation so that:

- JITStubs knows exactly what the result of compilation was. For example, if
  compilation was deferred, it will now know this.

- The set of things that has to happen to install compiled code is now factored
  out into JSC::installOptimizedCode().

- A bunch of the code in Executable.cpp is now made more common to reduce code
  duplication. For example, the heap heuristics stuff is now in one place.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::ProgramCodeBlock::compileOptimized):
(JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
(JSC):
(JSC::EvalCodeBlock::compileOptimized):
(JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::FunctionCodeBlock::compileOptimized):
(JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::ProgramCodeBlock::jitCompileImpl):
(JSC::EvalCodeBlock::jitCompileImpl):
(JSC::FunctionCodeBlock::jitCompileImpl):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::jitCompile):
(ProgramCodeBlock):
(EvalCodeBlock):
(FunctionCodeBlock):
* dfg/DFGDesiredIdentifiers.cpp:
(JSC::DFG::DesiredIdentifiers::numberOfIdentifiers):
(DFG):
(JSC::DFG::DesiredIdentifiers::at):
* dfg/DFGDesiredIdentifiers.h:
(JSC):
(DesiredIdentifiers):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
(DFG):
* dfg/DFGDriver.h:
(DFG):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalizeCommon):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::compileInThread):
(JSC::DFG::Plan::reallyAdd):
* dfg/DFGPlan.h:
(JSC):
(Plan):
(DFG):
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeFunction):
* jit/JITDriver.h:
(JSC::jitCompileIfAppropriateImpl):
(JSC::jitCompileFunctionIfAppropriateImpl):
(JSC):
(JSC::jitCompileIfAppropriate):
(JSC::jitCompileFunctionIfAppropriate):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/CompilationResult.cpp: Added.
(WTF):
(WTF::printInternal):
* runtime/CompilationResult.h: Added.
(JSC):
(WTF):
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileOptimized):
(JSC::EvalExecutable::jitCompile):
(JSC::EvalExecutable::compileInternal):
(JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
(JSC):
(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::compileForCallInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
* runtime/Executable.h:
(ScriptExecutable):
(EvalExecutable):
(ProgramExecutable):
(FunctionExecutable):
(JSC::FunctionExecutable::compileOptimizedFor):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
(JSC::FunctionExecutable::jitCompileFor):
* runtime/ExecutionHarness.h:
(JSC::prepareForExecutionImpl):
(JSC::prepareFunctionForExecutionImpl):
(JSC):
(JSC::installOptimizedCode):
(JSC::prepareForExecution):
(JSC::prepareFunctionForExecution):
(JSC::replaceWithDeferredOptimizedCode):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153165 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 176a347f
2013-05-17 Filip Pizlo <fpizlo@apple.com>
fourthTier: Executable and CodeBlock should be aware of DFG::Plans that complete asynchronously
https://bugs.webkit.org/show_bug.cgi?id=116350
Reviewed by Oliver Hunt.
This refactors compilation so that:
- JITStubs knows exactly what the result of compilation was. For example, if
compilation was deferred, it will now know this.
- The set of things that has to happen to install compiled code is now factored
out into JSC::installOptimizedCode().
- A bunch of the code in Executable.cpp is now made more common to reduce code
duplication. For example, the heap heuristics stuff is now in one place.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::ProgramCodeBlock::compileOptimized):
(JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
(JSC):
(JSC::EvalCodeBlock::compileOptimized):
(JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::FunctionCodeBlock::compileOptimized):
(JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
(JSC::ProgramCodeBlock::jitCompileImpl):
(JSC::EvalCodeBlock::jitCompileImpl):
(JSC::FunctionCodeBlock::jitCompileImpl):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::jitCompile):
(ProgramCodeBlock):
(EvalCodeBlock):
(FunctionCodeBlock):
* dfg/DFGDesiredIdentifiers.cpp:
(JSC::DFG::DesiredIdentifiers::numberOfIdentifiers):
(DFG):
(JSC::DFG::DesiredIdentifiers::at):
* dfg/DFGDesiredIdentifiers.h:
(JSC):
(DesiredIdentifiers):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
(DFG):
* dfg/DFGDriver.h:
(DFG):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
(JSC::DFG::tryFinalizePlan):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalizeCommon):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::compileInThread):
(JSC::DFG::Plan::reallyAdd):
* dfg/DFGPlan.h:
(JSC):
(Plan):
(DFG):
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeFunction):
* jit/JITDriver.h:
(JSC::jitCompileIfAppropriateImpl):
(JSC::jitCompileFunctionIfAppropriateImpl):
(JSC):
(JSC::jitCompileIfAppropriate):
(JSC::jitCompileFunctionIfAppropriate):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/CompilationResult.cpp: Added.
(WTF):
(WTF::printInternal):
* runtime/CompilationResult.h: Added.
(JSC):
(WTF):
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileOptimized):
(JSC::EvalExecutable::jitCompile):
(JSC::EvalExecutable::compileInternal):
(JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
(JSC):
(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::compileForCallInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
* runtime/Executable.h:
(ScriptExecutable):
(EvalExecutable):
(ProgramExecutable):
(FunctionExecutable):
(JSC::FunctionExecutable::compileOptimizedFor):
(JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
(JSC::FunctionExecutable::jitCompileFor):
* runtime/ExecutionHarness.h:
(JSC::prepareForExecutionImpl):
(JSC::prepareFunctionForExecutionImpl):
(JSC):
(JSC::installOptimizedCode):
(JSC::prepareForExecution):
(JSC::prepareFunctionForExecution):
(JSC::replaceWithDeferredOptimizedCode):
2013-05-16 Mark Hahnenberg <mhahnenberg@apple.com>
observeUseKindOnNode doesn't contain a case for KnownCellUse
......
......@@ -749,7 +749,7 @@
A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7386552118697B400540279 /* ThunkGenerators.cpp */; };
A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; };
A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */; };
A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; };
A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -765,11 +765,11 @@
A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
A78853F917972629001440E4 /* IntendedStructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78853F717972629001440E4 /* IntendedStructureChain.cpp */; };
A78853FA17972629001440E4 /* IntendedStructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = A78853F817972629001440E4 /* IntendedStructureChain.h */; };
A78853FA17972629001440E4 /* IntendedStructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = A78853F817972629001440E4 /* IntendedStructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78A976C179738B8009DF744 /* DFGFailedFinalizer.cpp */; };
A78A9775179738B8009DF744 /* DFGFailedFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A976D179738B8009DF744 /* DFGFailedFinalizer.h */; };
A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78A976E179738B8009DF744 /* DFGFinalizer.cpp */; };
A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A976F179738B8009DF744 /* DFGFinalizer.h */; };
A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A976F179738B8009DF744 /* DFGFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
A78A9778179738B8009DF744 /* DFGJITFinalizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78A9770179738B8009DF744 /* DFGJITFinalizer.cpp */; };
A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A9771179738B8009DF744 /* DFGJITFinalizer.h */; };
A78A977A179738B8009DF744 /* DFGPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78A9772179738B8009DF744 /* DFGPlan.cpp */; };
......@@ -791,6 +791,8 @@
A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DCB77912E3D90500911940 /* WriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E2EA690FB460CF00601F06 /* LiteralParser.h */; };
A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */; };
A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E5A3A51797432D00E893C0 /* CompilationResult.cpp */; };
A7E5A3A81797432D00E893C0 /* CompilationResult.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E5A3A61797432D00E893C0 /* CompilationResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
......@@ -1813,6 +1815,8 @@
A7DCB77912E3D90500911940 /* WriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrier.h; sourceTree = "<group>"; };
A7E2EA690FB460CF00601F06 /* LiteralParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralParser.h; sourceTree = "<group>"; };
A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralParser.cpp; sourceTree = "<group>"; };
A7E5A3A51797432D00E893C0 /* CompilationResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompilationResult.cpp; sourceTree = "<group>"; };
A7E5A3A61797432D00E893C0 /* CompilationResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompilationResult.h; sourceTree = "<group>"; };
A7F8690E0F9584A100558697 /* CachedCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedCall.h; sourceTree = "<group>"; };
A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameClosure.h; sourceTree = "<group>"; };
A7F9935D0FD7325100A0B2D0 /* JSONObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONObject.h; sourceTree = "<group>"; };
......@@ -2642,6 +2646,8 @@
7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
isa = PBXGroup;
children = (
A7E5A3A51797432D00E893C0 /* CompilationResult.cpp */,
A7E5A3A61797432D00E893C0 /* CompilationResult.h */,
BCF605110E203EF800B9A64D /* ArgList.cpp */,
BCF605120E203EF800B9A64D /* ArgList.h */,
BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
......@@ -3631,6 +3637,7 @@
141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
A7E5A3A81797432D00E893C0 /* CompilationResult.h in Headers */,
C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */,
8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
......@@ -4144,6 +4151,7 @@
65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */,
65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */,
0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */,
0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
......
......@@ -2808,30 +2808,51 @@ CodeBlock* FunctionCodeBlock::replacement()
return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
}
JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, CompilationResult& result, unsigned bytecodeIndex)
{
if (JITCode::isHigherTier(replacement()->getJITType(), getJITType()))
if (JITCode::isHigherTier(replacement()->getJITType(), getJITType())) {
result = CompilationNotNeeded;
return 0;
JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex);
}
JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
return error;
}
JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
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()->getJITType(), getJITType()))
if (JITCode::isHigherTier(replacement()->getJITType(), getJITType())) {
result = CompilationNotNeeded;
return 0;
JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex);
}
JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, result, bytecodeIndex);
return error;
}
JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
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()->getJITType(), getJITType()))
if (JITCode::isHigherTier(replacement()->getJITType(), getJITType())) {
result = CompilationNotNeeded;
return 0;
JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall);
}
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);
}
DFG::CapabilityLevel ProgramCodeBlock::canCompileWithDFGInternal()
{
return DFG::canCompileProgram(this);
......@@ -2875,21 +2896,21 @@ void FunctionCodeBlock::jettisonImpl()
static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
bool ProgramCodeBlock::jitCompileImpl(ExecState* exec)
CompilationResult ProgramCodeBlock::jitCompileImpl(ExecState* exec)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);
}
bool EvalCodeBlock::jitCompileImpl(ExecState* exec)
CompilationResult EvalCodeBlock::jitCompileImpl(ExecState* exec)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);
}
bool FunctionCodeBlock::jitCompileImpl(ExecState* exec)
CompilationResult FunctionCodeBlock::jitCompileImpl(ExecState* exec)
{
ASSERT(getJITType() == JITCode::InterpreterThunk);
ASSERT(this == replacement());
......
......@@ -303,22 +303,20 @@ class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFi
PassRefPtr<JITCode> getJITCode() { return m_jitCode; }
MacroAssemblerCodePtr getJITCodeWithArityCheck() { return m_jitCodeWithArityCheck; }
JITCode::JITType getJITType() const { return JITCode::jitTypeFor(m_jitCode.get()); }
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0;
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0;
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0;
void jettison();
enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
JITCompilationResult jitCompile(ExecState* exec)
CompilationResult jitCompile(ExecState* exec)
{
if (getJITType() != JITCode::InterpreterThunk) {
ASSERT(getJITType() == JITCode::BaselineJIT);
return AlreadyCompiled;
return CompilationNotNeeded;
}
#if ENABLE(JIT)
if (jitCompileImpl(exec))
return CompiledSuccessfully;
return CouldNotCompile;
return jitCompileImpl(exec);
#else
UNUSED_PARAM(exec);
return CouldNotCompile;
return CompilationFailed;
#endif
}
virtual CodeBlock* replacement() = 0;
......@@ -943,7 +941,7 @@ class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFi
protected:
#if ENABLE(JIT)
virtual bool jitCompileImpl(ExecState*) = 0;
virtual CompilationResult jitCompileImpl(ExecState*) = 0;
virtual void jettisonImpl() = 0;
#endif
virtual void visitWeakReferences(SlotVisitor&);
......@@ -1175,9 +1173,10 @@ class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFi
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
#endif
......@@ -1200,9 +1199,10 @@ class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFi
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
#endif
......@@ -1225,9 +1225,10 @@ class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFi
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
#endif
......
......@@ -28,6 +28,8 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
namespace JSC { namespace DFG {
DesiredIdentifiers::DesiredIdentifiers(CodeBlock* codeBlock)
......@@ -39,11 +41,27 @@ DesiredIdentifiers::~DesiredIdentifiers()
{
}
unsigned DesiredIdentifiers::numberOfIdentifiers()
{
return m_codeBlock->numberOfIdentifiers() + m_addedIdentifiers.size();
}
void DesiredIdentifiers::addLazily(StringImpl* rep)
{
m_addedIdentifiers.append(rep);
}
StringImpl* DesiredIdentifiers::at(unsigned index) const
{
StringImpl* result;
if (index < m_codeBlock->numberOfIdentifiers())
result = m_codeBlock->identifier(index).impl();
else
result = m_addedIdentifiers[index - m_codeBlock->numberOfIdentifiers()];
ASSERT(result->hasAtLeastOneRef());
return result;
}
void DesiredIdentifiers::reallyAdd(VM& vm)
{
for (unsigned i = 0; i < m_addedIdentifiers.size(); ++i) {
......
......@@ -30,33 +30,23 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
#include "Identifier.h"
namespace JSC { namespace DFG {
namespace JSC {
class CodeBlock;
namespace DFG {
class DesiredIdentifiers {
public:
DesiredIdentifiers(CodeBlock*);
~DesiredIdentifiers();
unsigned numberOfIdentifiers()
{
return m_codeBlock->numberOfIdentifiers() + m_addedIdentifiers.size();
}
unsigned numberOfIdentifiers();
void addLazily(StringImpl*);
StringImpl* at(unsigned index) const
{
StringImpl* result;
if (index < m_codeBlock->numberOfIdentifiers())
result = m_codeBlock->identifier(index).impl();
else
result = m_addedIdentifiers[index - m_codeBlock->numberOfIdentifiers()];
ASSERT(result->hasAtLeastOneRef());
return result;
}
StringImpl* at(unsigned index) const;
StringImpl* operator[](unsigned index) const { return at(index); }
......
......@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
#include "DFGJITCode.h"
#include "DFGPlan.h"
#include "DFGThunks.h"
......@@ -38,6 +39,7 @@
#include "JITCode.h"
#include "Operations.h"
#include "Options.h"
#include "SamplingTool.h"
namespace JSC { namespace DFG {
......@@ -48,7 +50,7 @@ unsigned getNumCompilations()
return numCompilations;
}
static bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
static CompilationResult compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck, unsigned osrEntryBytecodeIndex)
{
SamplingRegion samplingRegion("DFG Compilation (Driver)");
......@@ -61,10 +63,10 @@ static bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
ASSERT(osrEntryBytecodeIndex != UINT_MAX);
if (!Options::useDFGJIT())
return false;
return CompilationFailed;
if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount()))
return false;
return CompilationFailed;
if (logCompilationChanges())
dataLog("DFG compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n");
......@@ -89,9 +91,10 @@ static bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
numVarsWithValues = codeBlock->m_numVars;
else
numVarsWithValues = 0;
Plan plan(compileMode, codeBlock, osrEntryBytecodeIndex, numVarsWithValues);
for (size_t i = 0; i < plan.mustHandleValues.size(); ++i) {
int operand = plan.mustHandleValues.operandForIndex(i);
RefPtr<Plan> plan = adoptRef(
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)
&& compileMode == CompileFunction
......@@ -100,27 +103,30 @@ static bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
// also never be used. It doesn't matter what we put into the value for this,
// but it has to be an actual value that can be grokked by subsequent DFG passes,
// so we sanitize it here by turning it into Undefined.
plan.mustHandleValues[i] = jsUndefined();
plan->mustHandleValues[i] = jsUndefined();
} else
plan.mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
plan->mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
}
plan.compileInThread();
if (plan.finalize(jitCode, jitCodeWithArityCheck) != CompilationSuccessful)
return false;
return true;
plan->compileInThread();
return plan->finalize(jitCode, jitCodeWithArityCheck);
}
bool tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex)
CompilationResult tryCompile(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, unsigned bytecodeIndex)
{
return compile(CompileOther, exec, codeBlock, jitCode, 0, bytecodeIndex);
}
bool tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned 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
#endif // ENABLE(DFG_JIT)
......
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2011, 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
......@@ -27,6 +27,7 @@
#define DFGDriver_h
#include "CallFrame.h"
#include "DFGPlan.h"
#include <wtf/Platform.h>
namespace JSC {
......@@ -41,11 +42,17 @@ namespace DFG {
JS_EXPORT_PRIVATE unsigned getNumCompilations();
#if ENABLE(DFG_JIT)
bool tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned bytecodeIndex);
bool tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr& jitCodeWithArityCheck, unsigned bytecodeIndex);
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 bool tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return false; }
inline bool tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return false; }
inline CompilationResult tryCompile(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, unsigned) { return false; }
inline CompilationResult tryCompileFunction(ExecState*, CodeBlock*, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr&, unsigned) { return false; }
inline CompilationResult tryFinalizePlan(PassRefPtr<Plan>, RefPtr<JSC::JITCode>&, MacroAssemblerCodePtr*)
{
UNREACHABLE_FOR_PLATFORM();
return CompilationFailed;
}
#endif
} } // namespace JSC::DFG
......
......@@ -47,7 +47,7 @@ static const char* dfgOpNames[] = {
Graph::Graph(VM& vm, Plan& plan)
: m_vm(vm)
, m_plan(plan)
, m_codeBlock(m_plan.codeBlock)
, m_codeBlock(m_plan.codeBlock.get())
, m_profiledBlock(m_codeBlock->alternative())
, m_allocator(vm.m_dfgState->m_allocator)
, m_hasArguments(false)
......
......@@ -69,7 +69,7 @@ bool JITFinalizer::finalizeFunction(RefPtr<JSC::JITCode>& entry, MacroAssemblerC
void JITFinalizer::finalizeCommon()
{
if (m_plan.compilation)
m_plan.vm().m_perBytecodeProfiler->addCompilation(m_plan.compilation);
m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.compilation);
}
} } // namespace JSC::DFG
......
......@@ -68,15 +68,16 @@ static void dumpAndVerifyGraph(Graph& graph, const char* text)
}
Plan::Plan(
CompileMode compileMode, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex,
CompileMode compileMode, PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
unsigned numVarsWithValues)
: compileMode(compileMode)
, codeBlock(codeBlock)
, vm(*passedCodeBlock->vm())
, codeBlock(passedCodeBlock)
, osrEntryBytecodeIndex(osrEntryBytecodeIndex)
, numVarsWithValues(numVarsWithValues)
, mustHandleValues(codeBlock->numParameters(), numVarsWithValues)
, compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock), Profiler::DFG)) : 0)
, identifiers(codeBlock)
, compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock.get()), Profiler::DFG)) : 0)
, identifiers(codeBlock.get())
{
}
......@@ -89,7 +90,7 @@ void Plan::compileInThread()
SamplingRegion samplingRegion("DFG Compilation (Plan)");
CompilationScope compilationScope;
Graph dfg(vm(), *this);
Graph dfg(vm, *this);
if (!parse(dfg)) {
finalizer = adoptPtr(new FailedFinalizer(*this));
......@@ -176,7 +177,7 @@ bool Plan::isStillValid()
void Plan::reallyAdd()
{
watchpoints.reallyAdd();
identifiers.reallyAdd(vm());
identifiers.reallyAdd(vm);
}
CompilationResult Plan::finalize(RefPtr<JSC::JITCode>& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
......
......@@ -28,35 +28,38 @@
#include <wtf/Platform.h>
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
#include "CompilationResult.h"
#include "DFGDesiredIdentifiers.h"
#include "DFGDesiredStructureChains.h"
#include "DFGDesiredWatchpoints.h"
#include "DFGFinalizer.h"
#include "Operands.h"
#include "ProfilerCompilation.h"
#include <wtf/ThreadSafeRefCounted.h>
namespace JSC { namespace DFG {
namespace JSC {
class CodeBlock;
namespace DFG {
enum CompileMode { CompileFunction, CompileOther };
enum CompilationResult { CompilationFailed, CompilationInvalidated, CompilationSuccessful };