Commit 43a2fe75 authored by fpizlo@apple.com's avatar fpizlo@apple.com

DFG should not try to predict argument types by looking at the values of

argument registers at the time of compilation
https://bugs.webkit.org/show_bug.cgi?id=70578

Reviewed by Oliver Hunt.

* bytecode/CodeBlock.cpp:
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
* dfg/DFGDriver.h:
(JSC::DFG::tryCompileFunction):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::predictArgumentTypes):
* dfg/DFGGraph.h:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::compileOptimizedForCall):
(JSC::FunctionExecutable::compileOptimizedForConstruct):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* runtime/Executable.h:
(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileForConstruct):
(JSC::FunctionExecutable::compileFor):
(JSC::FunctionExecutable::compileOptimizedFor):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@98082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6d6fa24a
2011-10-20 Filip Pizlo <fpizlo@apple.com>
DFG should not try to predict argument types by looking at the values of
argument registers at the time of compilation
https://bugs.webkit.org/show_bug.cgi?id=70578
Reviewed by Oliver Hunt.
* bytecode/CodeBlock.cpp:
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
* dfg/DFGDriver.h:
(JSC::DFG::tryCompileFunction):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::predictArgumentTypes):
* dfg/DFGGraph.h:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::compileOptimizedForCall):
(JSC::FunctionExecutable::compileOptimizedForConstruct):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* runtime/Executable.h:
(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileForConstruct):
(JSC::FunctionExecutable::compileFor):
(JSC::FunctionExecutable::compileOptimizedFor):
2011-10-20 Filip Pizlo <fpizlo@apple.com>
DFG call optimization handling will fail if the call had been unlinked due
......@@ -1827,16 +1827,6 @@ void CodeBlock::copyDataFromAlternative()
}
#if ENABLE(JIT)
// FIXME: Implement OSR. If compileOptimized() is called from somewhere other than the
// epilogue, do OSR from the old code block to the new one.
// FIXME: After doing successful optimized compilation, reset the profiling counter to -1, so
// that the next execution of the old code block will jump straight into compileOptimized()
// and perform OSR.
// FIXME: Ensure that a call to compileOptimized() just does OSR (and resets the counter to -1)
// if the code had already been compiled.
CodeBlock* ProgramCodeBlock::replacement()
{
return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
......
......@@ -35,7 +35,7 @@
namespace JSC { namespace DFG {
enum CompileMode { CompileFunction, CompileOther };
inline bool compile(CompileMode compileMode, ExecState* exec, ExecState* calleeArgsExec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
{
JSGlobalData* globalData = &exec->globalData();
Graph dfg;
......@@ -43,7 +43,7 @@ inline bool compile(CompileMode compileMode, ExecState* exec, ExecState* calleeA
return false;
if (compileMode == CompileFunction)
dfg.predictArgumentTypes(calleeArgsExec, codeBlock);
dfg.predictArgumentTypes(codeBlock);
propagate(dfg, globalData, codeBlock);
......@@ -64,12 +64,12 @@ inline bool compile(CompileMode compileMode, ExecState* exec, ExecState* calleeA
bool tryCompile(ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode)
{
return compile(CompileOther, exec, 0, codeBlock, jitCode, 0);
return compile(CompileOther, exec, codeBlock, jitCode, 0);
}
bool tryCompileFunction(ExecState* exec, ExecState* calleeArgsExec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck)
bool tryCompileFunction(ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck)
{
return compile(CompileFunction, exec, calleeArgsExec, codeBlock, jitCode, &jitCodeWithArityCheck);
return compile(CompileFunction, exec, codeBlock, jitCode, &jitCodeWithArityCheck);
}
} } // namespace JSC::DFG
......
......@@ -39,10 +39,10 @@ namespace DFG {
#if ENABLE(DFG_JIT)
bool tryCompile(ExecState*, CodeBlock*, JITCode&);
bool tryCompileFunction(ExecState*, ExecState* calleeArgsExec, CodeBlock*, JITCode&, MacroAssemblerCodePtr& jitCodeWithArityCheck);
bool tryCompileFunction(ExecState*, CodeBlock*, JITCode&, MacroAssemblerCodePtr& jitCodeWithArityCheck);
#else
inline bool tryCompile(ExecState*, CodeBlock*, JITCode&) { return false; }
inline bool tryCompileFunction(ExecState*, ExecState*, CodeBlock*, JITCode&, MacroAssemblerCodePtr&) { return false; }
inline bool tryCompileFunction(ExecState*, CodeBlock*, JITCode&, MacroAssemblerCodePtr&) { return false; }
#endif
} } // namespace JSC::DFG
......
......@@ -284,15 +284,8 @@ void Graph::refChildren(NodeIndex op)
}
}
void Graph::predictArgumentTypes(ExecState* exec, CodeBlock* codeBlock)
void Graph::predictArgumentTypes(CodeBlock* codeBlock)
{
if (exec) {
size_t numberOfArguments = std::min(exec->argumentCountIncludingThis(), m_arguments.size());
for (size_t arg = 1; arg < numberOfArguments; ++arg)
at(m_arguments[arg]).variableAccessData()->predict(predictionFromValue(exec->argument(arg - 1)));
}
ASSERT(codeBlock);
ASSERT(codeBlock->alternative());
......
......@@ -201,7 +201,7 @@ public:
const char* nameOfVariableAccessData(VariableAccessData*);
#endif
void predictArgumentTypes(ExecState*, CodeBlock*);
void predictArgumentTypes(CodeBlock*);
StructureSet* addStructureSet(const StructureSet& structureSet)
{
......
......@@ -384,24 +384,24 @@ void ProgramExecutable::clearCodeVirtual()
Base::clearCodeVirtual();
}
JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec)
JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
{
ASSERT(exec->globalData().dynamicGlobalObject);
ASSERT(!!m_codeBlockForCall);
JSObject* error = 0;
if (m_codeBlockForCall->getJITType() != JITCode::topTierJIT())
error = compileForCallInternal(exec, scopeChainNode, calleeArgsExec, JITCode::nextTierJIT(m_codeBlockForCall->getJITType()));
error = compileForCallInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_codeBlockForCall->getJITType()));
ASSERT(!!m_codeBlockForCall);
return error;
}
JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec)
JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
{
ASSERT(exec->globalData().dynamicGlobalObject);
ASSERT(!!m_codeBlockForConstruct);
JSObject* error = 0;
if (m_codeBlockForConstruct->getJITType() != JITCode::topTierJIT())
error = compileForConstructInternal(exec, scopeChainNode, calleeArgsExec, JITCode::nextTierJIT(m_codeBlockForConstruct->getJITType()));
error = compileForConstructInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_codeBlockForConstruct->getJITType()));
ASSERT(!!m_codeBlockForConstruct);
return error;
}
......@@ -435,7 +435,7 @@ PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ExecState*
return result.release();
}
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec, JITCode::JITType jitType)
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
#if !ENABLE(JIT)
UNUSED_PARAM(jitType);
......@@ -459,7 +459,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
if (globalData->canUseJIT()) {
bool dfgCompiled = false;
if (jitType == JITCode::DFGJIT)
dfgCompiled = DFG::tryCompileFunction(exec, calleeArgsExec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
dfgCompiled = DFG::tryCompileFunction(exec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
if (dfgCompiled) {
if (m_codeBlockForCall->alternative())
m_codeBlockForCall->alternative()->unlinkIncomingCalls();
......@@ -478,8 +478,6 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
m_codeBlockForCall->setJITCode(m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
}
#else
UNUSED_PARAM(calleeArgsExec);
#endif
#if ENABLE(JIT)
......@@ -496,7 +494,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
return 0;
}
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec, JITCode::JITType jitType)
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
UNUSED_PARAM(jitType);
......@@ -519,7 +517,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
if (globalData->canUseJIT()) {
bool dfgCompiled = false;
if (jitType == JITCode::DFGJIT)
dfgCompiled = DFG::tryCompileFunction(exec, calleeArgsExec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
dfgCompiled = DFG::tryCompileFunction(exec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
if (dfgCompiled) {
if (m_codeBlockForConstruct->alternative())
m_codeBlockForConstruct->alternative()->unlinkIncomingCalls();
......@@ -538,8 +536,6 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
m_codeBlockForConstruct->setJITCode(m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
}
#else
UNUSED_PARAM(calleeArgsExec);
#endif
#if ENABLE(JIT)
......
......@@ -464,17 +464,17 @@ namespace JSC {
PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ExecState*, ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec = 0)
JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
{
ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForCall)
error = compileForCallInternal(exec, scopeChainNode, calleeArgsExec, JITCode::bottomTierJIT());
error = compileForCallInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
ASSERT(!error == !!m_codeBlockForCall);
return error;
}
JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec = 0);
JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*);
#if ENABLE(JIT)
void jettisonOptimizedCodeForCall(JSGlobalData&);
......@@ -491,17 +491,17 @@ namespace JSC {
return *m_codeBlockForCall;
}
JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec = 0)
JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
{
ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForConstruct)
error = compileForConstructInternal(exec, scopeChainNode, calleeArgsExec, JITCode::bottomTierJIT());
error = compileForConstructInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
ASSERT(!error == !!m_codeBlockForConstruct);
return error;
}
JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec = 0);
JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*);
#if ENABLE(JIT)
void jettisonOptimizedCodeForConstruct(JSGlobalData&);
......@@ -520,30 +520,26 @@ namespace JSC {
JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
{
// compileFor should only be called with a callframe set up to call this function,
// since we will make speculative optimizations based on the arguments.
ASSERT(exec->callee());
ASSERT(exec->callee()->inherits(&JSFunction::s_info));
ASSERT(asFunction(exec->callee())->jsExecutable() == this);
if (kind == CodeForCall)
return compileForCall(exec, scopeChainNode, exec);
return compileForCall(exec, scopeChainNode);
ASSERT(kind == CodeForConstruct);
return compileForConstruct(exec, scopeChainNode, exec);
return compileForConstruct(exec, scopeChainNode);
}
JSObject* compileOptimizedFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
{
// compileOptimizedFor should only be called with a callframe set up to call this function,
// since we will make speculative optimizations based on the arguments.
ASSERT(exec->callee());
ASSERT(exec->callee()->inherits(&JSFunction::s_info));
ASSERT(asFunction(exec->callee())->jsExecutable() == this);
if (kind == CodeForCall)
return compileOptimizedForCall(exec, scopeChainNode, exec);
return compileOptimizedForCall(exec, scopeChainNode);
ASSERT(kind == CodeForConstruct);
return compileOptimizedForConstruct(exec, scopeChainNode, exec);
return compileOptimizedForConstruct(exec, scopeChainNode);
}
#if ENABLE(JIT)
......@@ -606,8 +602,8 @@ namespace JSC {
FunctionExecutable(JSGlobalData&, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec, JITCode::JITType);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec, JITCode::JITType);
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
OwnPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment