Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (112014 => 112015)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2012-03-24 21:22:41 UTC (rev 112014)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2012-03-25 00:46:21 UTC (rev 112015)
@@ -84,13 +84,13 @@
dataLog(" ");
}
-void Graph::dumpCodeOrigin(NodeIndex nodeIndex)
+void Graph::dumpCodeOrigin(NodeIndex prevNodeIndex, NodeIndex nodeIndex)
{
- if (!nodeIndex)
+ if (prevNodeIndex == NoNode)
return;
Node& currentNode = at(nodeIndex);
- Node& previousNode = at(nodeIndex - 1);
+ Node& previousNode = at(prevNodeIndex);
if (previousNode.codeOrigin.inlineCallFrame == currentNode.codeOrigin.inlineCallFrame)
return;
@@ -131,7 +131,6 @@
--refCount;
}
- dumpCodeOrigin(nodeIndex);
printWhiteSpace((node.codeOrigin.inlineDepth() - 1) * 2);
// Example/explanation of dataflow dump output
@@ -263,6 +262,7 @@
void Graph::dump()
{
+ NodeIndex lastNodeIndex = NoNode;
for (size_t b = 0; b < m_blocks.size(); ++b) {
BasicBlock* block = m_blocks[b].get();
dataLog("Block #%u (bc#%u): %s%s\n", (int)b, block->bytecodeBegin, block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "");
@@ -281,8 +281,11 @@
dataLog(" var links: ");
dumpOperands(block->variablesAtHead, WTF::dataFile());
dataLog("\n");
- for (size_t i = 0; i < block->size(); ++i)
+ for (size_t i = 0; i < block->size(); ++i) {
+ dumpCodeOrigin(lastNodeIndex, block->at(i));
dump(block->at(i));
+ lastNodeIndex = block->at(i);
+ }
dataLog(" vars after: ");
if (block->cfaHasVisited)
dumpOperands(block->valuesAtTail, WTF::dataFile());
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (112014 => 112015)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2012-03-24 21:22:41 UTC (rev 112014)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2012-03-25 00:46:21 UTC (rev 112015)
@@ -45,8 +45,8 @@
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
m_count = 0;
#endif
- // Two stage process: first propagate predictions, then propagate while doing double voting.
-
+ // 1) propagate predictions
+
do {
m_changed = false;
@@ -64,6 +64,8 @@
propagateBackward();
} while (m_changed);
+ // 2) repropagate predictions while doing double voting.
+
do {
m_changed = false;
doRoundOfDoubleVoting();
@@ -119,14 +121,12 @@
return;
NodeType op = node.op();
- NodeFlags flags = node.flags();
+ NodeFlags flags = node.flags() & NodeBackPropMask;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" %s @%u: %s ", Graph::opName(op), m_compileIndex, nodeFlagsAsString(flags));
#endif
- flags &= NodeBackPropMask;
-
bool changed = false;
switch (op) {
@@ -156,7 +156,7 @@
case Flush: {
// Make sure that the analysis knows that flushed locals escape.
VariableAccessData* variableAccessData = node.variableAccessData();
- variableAccessData->mergeFlags(NodeUsedAsNumber | NodeNeedsNegZero);
+ changed |= variableAccessData->mergeFlags(NodeUsedAsValue);
break;
}
@@ -165,36 +165,47 @@
case BitXor:
case BitRShift:
case BitLShift:
- case BitURShift:
+ case BitURShift: {
+ changed |= setPrediction(PredictInt32);
+ flags |= NodeUsedAsInt;
+ flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero);
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
+ break;
+ }
+
case ValueToInt32: {
changed |= setPrediction(PredictInt32);
+ flags |= NodeUsedAsInt;
+ flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero);
+ changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
case ArrayPop: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case ArrayPush: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
break;
}
case RegExpExec:
case RegExpTest: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case StringCharCodeAt: {
changed |= mergePrediction(PredictInt32);
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
break;
}
@@ -203,13 +214,16 @@
PredictedType right = m_graph[node.child2()].prediction();
if (left && right) {
- if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (isInt32Prediction(mergePredictions(left, right))
+ && nodeCanSpeculateInteger(node.arithNodeFlags()))
changed |= mergePrediction(PredictInt32);
else
changed |= mergePrediction(PredictDouble);
}
- changed |= mergeDefaultArithFlags(node, flags);
+ flags |= NodeUsedAsValue;
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
@@ -303,7 +317,8 @@
PredictedType right = m_graph[node.child2()].prediction();
if (left && right) {
- if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (isInt32Prediction(mergePredictions(left, right))
+ && nodeCanSpeculateInteger(node.arithNodeFlags()))
changed |= mergePrediction(PredictInt32);
else
changed |= mergePrediction(PredictDouble);
@@ -321,7 +336,8 @@
PredictedType right = m_graph[node.child2()].prediction();
if (left && right) {
- if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (isInt32Prediction(mergePredictions(left, right))
+ && nodeCanSpeculateInteger(node.arithNodeFlags()))
changed |= mergePrediction(PredictInt32);
else
changed |= mergePrediction(PredictDouble);
@@ -340,18 +356,16 @@
case ArithSqrt: {
changed |= setPrediction(PredictDouble);
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= m_graph[node.child1()].mergeFlags(flags | NodeUsedAsValue);
break;
}
case ArithAbs: {
PredictedType child = m_graph[node.child1()].prediction();
- if (child) {
- if (nodeCanSpeculateInteger(node.arithNodeFlags()))
- changed |= mergePrediction(child);
- else
- changed |= setPrediction(PredictDouble);
- }
+ if (nodeCanSpeculateInteger(node.arithNodeFlags()))
+ changed |= mergePrediction(child);
+ else
+ changed |= setPrediction(PredictDouble);
flags &= ~NodeNeedsNegZero;
changed |= m_graph[node.child1()].mergeFlags(flags);
@@ -367,71 +381,55 @@
case CompareStrictEq:
case InstanceOf: {
changed |= setPrediction(PredictBoolean);
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
}
case GetById: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- else if (codeBlock()->identifier(node.identifierNumber()) == globalData().propertyNames->length) {
- // If there is no prediction from value profiles, check if we might be
- // able to infer the type ourselves.
- bool isArray = isArrayPrediction(m_graph[node.child1()].prediction());
- bool isString = isStringPrediction(m_graph[node.child1()].prediction());
- bool isByteArray = m_graph[node.child1()].shouldSpeculateByteArray();
- bool isInt8Array = m_graph[node.child1()].shouldSpeculateInt8Array();
- bool isInt16Array = m_graph[node.child1()].shouldSpeculateInt16Array();
- bool isInt32Array = m_graph[node.child1()].shouldSpeculateInt32Array();
- bool isUint8Array = m_graph[node.child1()].shouldSpeculateUint8Array();
- bool isUint8ClampedArray = m_graph[node.child1()].shouldSpeculateUint8ClampedArray();
- bool isUint16Array = m_graph[node.child1()].shouldSpeculateUint16Array();
- bool isUint32Array = m_graph[node.child1()].shouldSpeculateUint32Array();
- bool isFloat32Array = m_graph[node.child1()].shouldSpeculateFloat32Array();
- bool isFloat64Array = m_graph[node.child1()].shouldSpeculateFloat64Array();
- if (isArray || isString || isByteArray || isInt8Array || isInt16Array || isInt32Array || isUint8Array || isUint8ClampedArray || isUint16Array || isUint32Array || isFloat32Array || isFloat64Array)
- changed |= mergePrediction(PredictInt32);
- }
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case GetByIdFlush:
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
case GetByVal: {
- if (m_graph[node.child1()].shouldSpeculateFloat32Array() || m_graph[node.child1()].shouldSpeculateFloat64Array())
+ if (m_graph[node.child1()].shouldSpeculateFloat32Array()
+ || m_graph[node.child1()].shouldSpeculateFloat64Array())
changed |= mergePrediction(PredictDouble);
- else if (node.getHeapPrediction())
+ else
changed |= mergePrediction(node.getHeapPrediction());
- changed |= m_graph[node.child1()].mergeFlags(flags | NodeUsedAsNumber | NodeNeedsNegZero);
- changed |= m_graph[node.child2()].mergeFlags(flags | NodeUsedAsNumber);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
break;
}
case GetPropertyStorage:
case GetIndexedPropertyStorage: {
changed |= setPrediction(PredictOther);
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
}
case GetByOffset: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case Call:
case Construct: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergePrediction(node.getHeapPrediction());
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ ++childIdx) {
+ Edge edge = m_graph.m_varArgChildren[childIdx];
+ changed |= m_graph[edge].mergeFlags(NodeUsedAsValue);
+ }
break;
}
@@ -444,20 +442,20 @@
}
changed |= mergePrediction(prediction);
}
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
}
case GetGlobalVar: {
PredictedType prediction = m_graph.getGlobalVarPrediction(node.varNumber());
- if (prediction)
- changed |= mergePrediction(prediction);
+ changed |= mergePrediction(prediction);
break;
}
case PutGlobalVar: {
- changed |= m_graph.predictGlobalVar(node.varNumber(), m_graph[node.child1()].prediction());
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= m_graph.predictGlobalVar(
+ node.varNumber(), m_graph[node.child1()].prediction());
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
break;
}
@@ -467,8 +465,7 @@
case ResolveBaseStrictPut:
case ResolveGlobal: {
PredictedType prediction = node.getHeapPrediction();
- if (prediction)
- changed |= mergePrediction(prediction);
+ changed |= mergePrediction(prediction);
break;
}
@@ -485,14 +482,23 @@
case CreateThis:
case NewObject: {
changed |= setPrediction(PredictFinalObject);
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
}
- case NewArray:
+ case NewArray: {
+ changed |= setPrediction(PredictArray);
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ ++childIdx) {
+ Edge edge = m_graph.m_varArgChildren[childIdx];
+ changed |= m_graph[edge].mergeFlags(NodeUsedAsValue);
+ }
+ break;
+ }
+
case NewArrayBuffer: {
changed |= setPrediction(PredictArray);
- changed |= mergeDefaultArithFlags(node, flags);
break;
}
@@ -501,10 +507,19 @@
break;
}
- case StringCharAt:
+ case StringCharAt: {
+ changed |= setPrediction(PredictString);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
+ break;
+ }
+
case StrCat: {
changed |= setPrediction(PredictString);
- changed |= mergeDefaultArithFlags(node, flags);
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ ++childIdx)
+ changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsNumber);
break;
}
@@ -521,7 +536,8 @@
} else if (child & PredictObjectMask) {
// Objects get turned into strings. So if the input has hints of objectness,
// the output will have hinsts of stringiness.
- changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, PredictString));
+ changed |= mergePrediction(
+ mergePredictions(child & ~PredictObjectMask, PredictString));
} else
changed |= mergePrediction(child);
}
@@ -541,6 +557,7 @@
break;
}
+ case PutByValAlias:
case GetArrayLength:
case GetByteArrayLength:
case GetInt8ArrayLength:
@@ -560,33 +577,45 @@
}
case PutByVal:
- changed |= m_graph[node.child1()].mergeFlags(flags | NodeUsedAsNumber | NodeNeedsNegZero);
- changed |= m_graph[node.child2()].mergeFlags(flags | NodeUsedAsNumber);
- changed |= m_graph[node.child3()].mergeFlags(flags | NodeUsedAsNumber | NodeNeedsNegZero);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
+ changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
break;
+ case PutScopedVar:
+ case Return:
+ case Throw:
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ break;
+
+ case PutById:
+ case PutByIdDirect:
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
+ break;
+
+ case PutByOffset:
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
+ break;
+
+ case Phi:
+ break;
+
#ifndef NDEBUG
// These get ignored because they don't return anything.
- case PutScopedVar:
case DFG::Jump:
case Branch:
case Breakpoint:
- case Return:
case CheckHasInstance:
- case Phi:
- case Throw:
case ThrowReferenceError:
case ForceOSRExit:
case SetArgument:
- case PutByValAlias:
- case PutById:
- case PutByIdDirect:
case CheckStructure:
case CheckFunction:
case PutStructure:
- case PutByOffset:
case TearOffActivation:
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
// These gets ignored because it doesn't do anything.
@@ -600,7 +629,7 @@
break;
#else
default:
- changed |= mergeDefaultArithFlags(node, flags);
+ changed |= mergeDefaultFlags(node);
break;
#endif
}
@@ -611,24 +640,25 @@
m_changed |= changed;
}
-
- bool mergeDefaultArithFlags(Node& node, NodeFlags flags)
+
+ bool mergeDefaultFlags(Node& node)
{
bool changed = false;
- flags |= NodeUsedAsNumber | NodeNeedsNegZero;
if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
- changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(flags);
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ childIdx++)
+ changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsValue);
} else {
if (!node.child1())
return changed;
- changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
if (!node.child2())
return changed;
- changed |= m_graph[node.child2()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
if (!node.child3())
return changed;
- changed |= m_graph[node.child3()].mergeFlags(flags);
+ changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
}
return changed;
}
@@ -650,7 +680,7 @@
for (m_compileIndex = m_graph.size(); m_compileIndex-- > 0;)
propagate(m_graph[m_compileIndex]);
}
-
+
void vote(Edge nodeUse, VariableAccessData::Ballot ballot)
{
switch (m_graph[nodeUse].op()) {
@@ -669,7 +699,9 @@
void vote(Node& node, VariableAccessData::Ballot ballot)
{
if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ childIdx++)
vote(m_graph.m_varArgChildren[childIdx], ballot);
return;
}
@@ -724,7 +756,9 @@
VariableAccessData::Ballot ballot;
- if (isNumberPrediction(left) && isNumberPrediction(right) && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()]) && node.canSpeculateInteger()))
+ if (isNumberPrediction(left) && isNumberPrediction(right)
+ && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()])
+ && node.canSpeculateInteger()))
ballot = VariableAccessData::VoteDouble;
else
ballot = VariableAccessData::VoteValue;
@@ -736,7 +770,8 @@
case ArithAbs:
VariableAccessData::Ballot ballot;
- if (!(m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger()))
+ if (!(m_graph[node.child1()].shouldSpeculateInteger()
+ && node.canSpeculateInteger()))
ballot = VariableAccessData::VoteDouble;
else
ballot = VariableAccessData::VoteValue;