https://bugs.webkit.org/show_bug.cgi?id=68640
Reviewed by Gavin Barraclough.
Naive implementation of get_scoped_var in the DFG. Essentially this
is the bare minimum required to get correct behaviour, so there's no
load/store coalescing or type profiling involved, even though these
would be wins. No impact on SunSpider or V8.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasVarNumber):
(JSC::DFG::Node::hasScopeChainDepth):
(JSC::DFG::Node::scopeChainDepth):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95742
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-09-22 Oliver Hunt <oliver@apple.com>
+
+ Implement get_scoped_var in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=68640
+
+ Reviewed by Gavin Barraclough.
+
+ Naive implementation of get_scoped_var in the DFG. Essentially this
+ is the bare minimum required to get correct behaviour, so there's no
+ load/store coalescing or type profiling involved, even though these
+ would be wins. No impact on SunSpider or V8.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasVarNumber):
+ (JSC::DFG::Node::hasScopeChainDepth):
+ (JSC::DFG::Node::scopeChainDepth):
+ * dfg/DFGPropagator.cpp:
+ (JSC::DFG::Propagator::propagateNodePredictions):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
2011-09-22 Adam Roben <aroben@apple.com>
Remove FindSafari from all our .sln files
m_currentIndex += OPCODE_LENGTH(op_method_check) + OPCODE_LENGTH(op_get_by_id);
continue;
}
-
+ case op_get_scoped_var: {
+ int dst = currentInstruction[1].u.operand;
+ int slot = currentInstruction[2].u.operand;
+ int depth = currentInstruction[3].u.operand;
+ NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(depth));
+ set(dst, getScopedVar);
+ NEXT_OPCODE(op_get_scoped_var);
+ }
case op_get_by_id: {
NodeIndex base = get(currentInstruction[2].u.operand);
unsigned identifierNumber = currentInstruction[3].u.operand;
case op_get_by_val:
case op_put_by_val:
case op_method_check:
+ case op_get_scoped_var:
case op_get_by_id:
case op_put_by_id:
case op_get_global_var:
macro(GetByOffset, NodeResultJS) \
macro(GetMethod, NodeResultJS | NodeMustGenerate) \
macro(CheckMethod, NodeResultJS | NodeMustGenerate) \
+ macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \
macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
macro(PutGlobalVar, NodeMustGenerate | NodeClobbersWorld) \
\
bool hasVarNumber()
{
- return op == GetGlobalVar || op == PutGlobalVar;
+ return op == GetGlobalVar || op == PutGlobalVar || op == GetScopedVar;
}
unsigned varNumber()
return m_opInfo;
}
+ bool hasScopeChainDepth()
+ {
+ return op == GetScopedVar;
+ }
+
+ unsigned scopeChainDepth()
+ {
+ ASSERT(hasScopeChainDepth());
+ return m_opInfo2;
+ }
+
bool hasResult()
{
return op & NodeResultMask;
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
+ case GetScopedVar:
break;
// This gets ignored because it doesn't do anything.
cellResult(result.gpr(), m_compileIndex);
break;
}
+ case GetScopedVar: {
+ GPRTemporary result(this);
+ GPRReg resultGPR = result.gpr();
+ m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR);
+ bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
+ int skip = node.scopeChainDepth();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ JITCompiler::Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = m_jit.branchTestPtr(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
+ activationNotCreated.link(&m_jit);
+ }
+ while (skip--)
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
+
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, object)), resultGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, node.varNumber() * sizeof(Register)), resultGPR);
+ jsValueResult(resultGPR, m_compileIndex);
+ break;
+ }
case GetById: {
SpeculateCellOperand base(this, node.child1());
GPRTemporary result(this, base);