Title: [136546] trunk/Source/_javascript_Core
- Revision
- 136546
- Author
- fpi...@apple.com
- Date
- 2012-12-04 12:25:24 -0800 (Tue, 04 Dec 2012)
Log Message
DFG should inline code blocks that use scoped variable access
https://bugs.webkit.org/show_bug.cgi?id=103974
Reviewed by Oliver Hunt.
This mostly just turns on something we could have done all along, but also adds a few key
necessities to make this right:
1) Constant folding of SkipScope, since if we inline with a known JSFunction* then the
scope is constant.
2) Interference analysis for GetLocal<->PutScopedVar and SetLocal<->GetScopedVar.
This is not meant to be a speed-up on major benchmarks since we don't yet inline most
closure calls for entirely unrelated reasons. But on toy programs it can be >2x faster.
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::getScope):
(JSC::DFG::ByteCodeParser::parseResolveOperations):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::scopedVarLoadElimination):
(JSC::DFG::CSEPhase::scopedVarStoreElimination):
(JSC::DFG::CSEPhase::getLocalLoadElimination):
(JSC::DFG::CSEPhase::setLocalStoreElimination):
* dfg/DFGCapabilities.h:
(JSC::DFG::canInlineResolveOperations):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (136545 => 136546)
--- trunk/Source/_javascript_Core/ChangeLog 2012-12-04 20:17:55 UTC (rev 136545)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-12-04 20:25:24 UTC (rev 136546)
@@ -1,5 +1,36 @@
2012-12-03 Filip Pizlo <fpi...@apple.com>
+ DFG should inline code blocks that use scoped variable access
+ https://bugs.webkit.org/show_bug.cgi?id=103974
+
+ Reviewed by Oliver Hunt.
+
+ This mostly just turns on something we could have done all along, but also adds a few key
+ necessities to make this right:
+
+ 1) Constant folding of SkipScope, since if we inline with a known JSFunction* then the
+ scope is constant.
+
+ 2) Interference analysis for GetLocal<->PutScopedVar and SetLocal<->GetScopedVar.
+
+ This is not meant to be a speed-up on major benchmarks since we don't yet inline most
+ closure calls for entirely unrelated reasons. But on toy programs it can be >2x faster.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getScope):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getLocalLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineResolveOperations):
+
+2012-12-03 Filip Pizlo <fpi...@apple.com>
+
Replace JSValue::description() with JSValue::dump(PrintStream&)
https://bugs.webkit.org/show_bug.cgi?id=103866
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (136545 => 136546)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-12-04 20:17:55 UTC (rev 136545)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-12-04 20:25:24 UTC (rev 136546)
@@ -1385,11 +1385,21 @@
case GetMyScope:
case SkipTopScope:
- case SkipScope:
node.setCanExit(false);
forNode(nodeIndex).set(SpecCellOther);
break;
+ case SkipScope: {
+ node.setCanExit(false);
+ JSValue child = forNode(node.child1()).value();
+ if (child && trySetConstant(nodeIndex, JSValue(jsCast<JSScope*>(child.asCell())->next()))) {
+ m_foundConstants = true;
+ break;
+ }
+ forNode(nodeIndex).set(SpecCellOther);
+ break;
+ }
+
case GetScopeRegisters:
node.setCanExit(false);
forNode(node.child1()).filter(SpecCell);
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (136545 => 136546)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-12-04 20:17:55 UTC (rev 136545)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-12-04 20:25:24 UTC (rev 136546)
@@ -1886,9 +1886,16 @@
NodeIndex ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
{
- NodeIndex localBase = addToGraph(GetMyScope);
- if (skipTop)
+ NodeIndex localBase;
+ if (m_inlineStackTop->m_inlineCallFrame) {
+ ASSERT(m_inlineStackTop->m_inlineCallFrame->callee);
+ localBase = cellConstant(m_inlineStackTop->m_inlineCallFrame->callee->scope());
+ } else
+ localBase = addToGraph(GetMyScope);
+ if (skipTop) {
+ ASSERT(!m_inlineStackTop->m_inlineCallFrame);
localBase = addToGraph(SkipTopScope, localBase);
+ }
for (unsigned n = skipCount; n--;)
localBase = addToGraph(SkipScope, localBase);
return localBase;
@@ -1954,7 +1961,6 @@
break;
case ResolveOperation::SkipScopes:
- ASSERT(!m_inlineStackTop->m_inlineCallFrame);
skipCount += pc->m_scopesToSkip;
skippedScopes = true;
++pc;
Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (136545 => 136546)
--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2012-12-04 20:17:55 UTC (rev 136545)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2012-12-04 20:25:24 UTC (rev 136546)
@@ -236,6 +236,13 @@
return node.child3().index();
break;
}
+ case SetLocal: {
+ VariableAccessData* variableAccessData = node.variableAccessData();
+ if (variableAccessData->isCaptured()
+ && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
+ return NoNode;
+ break;
+ }
default:
break;
}
@@ -318,6 +325,14 @@
return NoNode;
break;
}
+
+ case GetLocal: {
+ VariableAccessData* variableAccessData = node.variableAccessData();
+ if (variableAccessData->isCaptured()
+ && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
+ return NoNode;
+ break;
+ }
default:
break;
@@ -830,6 +845,11 @@
}
break;
+ case PutScopedVar:
+ if (static_cast<VirtualRegister>(node.varNumber()) == local)
+ return NoNode;
+ break;
+
default:
if (careAboutClobbering && m_graph.clobbersWorld(index))
return NoNode;
@@ -882,9 +902,13 @@
return result;
}
+ case GetScopedVar:
+ if (static_cast<VirtualRegister>(node.varNumber()) == local)
+ result.mayBeAccessed = true;
+ break;
+
case GetMyScope:
case SkipTopScope:
- case GetScopeRegisters:
if (m_graph.uncheckedActivationRegisterFor(node.codeOrigin) == local)
result.mayBeAccessed = true;
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.h (136545 => 136546)
--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.h 2012-12-04 20:17:55 UTC (rev 136545)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.h 2012-12-04 20:25:24 UTC (rev 136546)
@@ -82,6 +82,10 @@
case ResolveOperation::GetAndReturnGlobalProperty:
case ResolveOperation::GetAndReturnGlobalVar:
case ResolveOperation::GetAndReturnGlobalVarWatchable:
+ case ResolveOperation::SkipScopes:
+ case ResolveOperation::SetBaseToScope:
+ case ResolveOperation::ReturnScopeAsBase:
+ case ResolveOperation::GetAndReturnScopedVar:
continue;
case ResolveOperation::Fail:
@@ -94,12 +98,8 @@
return false;
case ResolveOperation::SkipTopScopeNode:
- case ResolveOperation::SkipScopes:
- case ResolveOperation::SetBaseToScope:
- case ResolveOperation::ReturnScopeAsBase:
- case ResolveOperation::GetAndReturnScopedVar:
- // These opcodes would be easy to support with inlining, but we currently don't do it.
- // The issue is that the scope chain will not be set correctly.
+ // We don't inline code blocks that create activations. Creation of
+ // activations is the only thing that leads to SkipTopScopeNode.
return false;
case ResolveOperation::CheckForDynamicEntriesBeforeGlobalScope:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes