summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp474
1 files changed, 286 insertions, 188 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 98bdaac06..53174604a 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,8 +45,8 @@ public:
#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 @@ public:
propagateBackward();
} while (m_changed);
+ // 2) repropagate predictions while doing double voting.
+
do {
m_changed = false;
doRoundOfDoubleVoting();
@@ -75,8 +77,6 @@ public:
doRoundOfDoubleVoting();
propagateBackward();
} while (m_changed);
-
- fixup();
}
private:
@@ -100,15 +100,31 @@ private:
return m_graph[m_compileIndex].predict(prediction);
}
+ bool isNotNegZero(NodeIndex nodeIndex)
+ {
+ if (!m_graph.isNumberConstant(nodeIndex))
+ return false;
+ double value = m_graph.valueOfNumberConstant(nodeIndex);
+ return !value && 1.0 / value < 0.0;
+ }
+
+ bool isNotZero(NodeIndex nodeIndex)
+ {
+ if (!m_graph.isNumberConstant(nodeIndex))
+ return false;
+ return !!m_graph.valueOfNumberConstant(nodeIndex);
+ }
+
void propagate(Node& node)
{
if (!node.shouldGenerate())
return;
- NodeType op = static_cast<NodeType>(node.op);
+ NodeType op = node.op();
+ NodeFlags flags = node.flags() & NodeBackPropMask;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex);
+ dataLog(" %s @%u: %s ", Graph::opName(op), m_compileIndex, nodeFlagsAsString(flags));
#endif
bool changed = false;
@@ -121,14 +137,26 @@ private:
}
case GetLocal: {
- PredictedType prediction = node.variableAccessData()->prediction();
+ VariableAccessData* variableAccessData = node.variableAccessData();
+ PredictedType prediction = variableAccessData->prediction();
if (prediction)
changed |= mergePrediction(prediction);
+
+ changed |= variableAccessData->mergeFlags(flags);
break;
}
case SetLocal: {
- changed |= node.variableAccessData()->predict(m_graph[node.child1()].prediction());
+ VariableAccessData* variableAccessData = node.variableAccessData();
+ changed |= variableAccessData->predict(m_graph[node.child1()].prediction());
+ changed |= m_graph[node.child1()].mergeFlags(variableAccessData->flags());
+ break;
+ }
+
+ case Flush: {
+ // Make sure that the analysis knows that flushed locals escape.
+ VariableAccessData* variableAccessData = node.variableAccessData();
+ changed |= variableAccessData->mergeFlags(NodeUsedAsValue);
break;
}
@@ -137,21 +165,47 @@ private:
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:
+ case ArrayPop: {
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
+ break;
+ }
+
case ArrayPush: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
+ break;
+ }
+
+ case RegExpExec:
+ case RegExpTest: {
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case StringCharCodeAt: {
changed |= mergePrediction(PredictInt32);
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
break;
}
@@ -160,19 +214,26 @@ private:
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);
}
+
+ flags |= NodeUsedAsValue;
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case UInt32ToNumber: {
if (nodeCanSpeculateInteger(node.arithNodeFlags()))
- changed |= setPrediction(PredictInt32);
+ changed |= mergePrediction(PredictInt32);
else
- changed |= setPrediction(PredictNumber);
+ changed |= mergePrediction(PredictNumber);
+
+ changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
@@ -192,10 +253,34 @@ private:
} else
changed |= mergePrediction(PredictString | PredictInt32 | PredictDouble);
}
+
+ if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index()))
+ flags &= ~NodeNeedsNegZero;
+
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
+ break;
+ }
+
+ case ArithAdd: {
+ PredictedType left = m_graph[node.child1()].prediction();
+ PredictedType right = m_graph[node.child2()].prediction();
+
+ if (left && right) {
+ if (m_graph.addShouldSpeculateInteger(node))
+ changed |= mergePrediction(PredictInt32);
+ else
+ changed |= mergePrediction(PredictDouble);
+ }
+
+ if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index()))
+ flags &= ~NodeNeedsNegZero;
+
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
- case ArithAdd:
case ArithSub: {
PredictedType left = m_graph[node.child1()].prediction();
PredictedType right = m_graph[node.child2()].prediction();
@@ -206,6 +291,12 @@ private:
else
changed |= mergePrediction(PredictDouble);
}
+
+ if (isNotZero(node.child1().index()) || isNotZero(node.child2().index()))
+ flags &= ~NodeNeedsNegZero;
+
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
@@ -216,37 +307,68 @@ private:
else
changed |= mergePrediction(PredictDouble);
}
+
+ changed |= m_graph[node.child1()].mergeFlags(flags);
break;
- case ArithMul:
case ArithMin:
- case ArithMax:
+ case ArithMax: {
+ PredictedType left = m_graph[node.child1()].prediction();
+ PredictedType right = m_graph[node.child2()].prediction();
+
+ if (left && right) {
+ if (isInt32Prediction(mergePredictions(left, right))
+ && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ changed |= mergePrediction(PredictInt32);
+ else
+ changed |= mergePrediction(PredictDouble);
+ }
+
+ flags |= NodeUsedAsNumber;
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
+ break;
+ }
+
+ case ArithMul:
case ArithDiv: {
PredictedType left = m_graph[node.child1()].prediction();
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);
}
+
+ // As soon as a multiply happens, we can easily end up in the part
+ // of the double domain where the point at which you do truncation
+ // can change the outcome. So, ArithMul always checks for overflow
+ // no matter what, and always forces its inputs to check as well.
+
+ flags |= NodeUsedAsNumber | NodeNeedsNegZero;
+ changed |= m_graph[node.child1()].mergeFlags(flags);
+ changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithSqrt: {
changed |= setPrediction(PredictDouble);
+ 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);
break;
}
@@ -257,64 +379,63 @@ private:
case CompareGreaterEq:
case CompareEq:
case CompareStrictEq:
- case InstanceOf: {
+ case InstanceOf:
+ case IsUndefined:
+ case IsBoolean:
+ case IsNumber:
+ case IsString:
+ case IsObject:
+ case IsFunction: {
changed |= setPrediction(PredictBoolean);
+ 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 |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case GetByIdFlush:
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
case GetByVal: {
- if (m_graph[node.child1()].shouldSpeculateUint32Array() || 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(NodeUsedAsValue);
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
break;
}
case GetPropertyStorage:
case GetIndexedPropertyStorage: {
changed |= setPrediction(PredictOther);
+ changed |= mergeDefaultFlags(node);
break;
}
case GetByOffset: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergePrediction(node.getHeapPrediction());
+ changed |= mergeDefaultFlags(node);
break;
}
case Call:
case Construct: {
- if (node.getHeapPrediction())
- changed |= mergePrediction(node.getHeapPrediction());
+ 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;
}
@@ -327,18 +448,17 @@ private:
}
changed |= mergePrediction(prediction);
}
+ changed |= mergeDefaultFlags(node);
break;
}
case GetGlobalVar: {
- PredictedType prediction = m_graph.getGlobalVarPrediction(node.varNumber());
- if (prediction)
- changed |= mergePrediction(prediction);
+ changed |= mergePrediction(node.getHeapPrediction());
break;
}
case PutGlobalVar: {
- changed |= m_graph.predictGlobalVar(node.varNumber(), m_graph[node.child1()].prediction());
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
break;
}
@@ -348,8 +468,7 @@ private:
case ResolveBaseStrictPut:
case ResolveGlobal: {
PredictedType prediction = node.getHeapPrediction();
- if (prediction)
- changed |= mergePrediction(prediction);
+ changed |= mergePrediction(prediction);
break;
}
@@ -366,10 +485,21 @@ private:
case CreateThis:
case NewObject: {
changed |= setPrediction(PredictFinalObject);
+ changed |= mergeDefaultFlags(node);
+ break;
+ }
+
+ 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 NewArray:
case NewArrayBuffer: {
changed |= setPrediction(PredictArray);
break;
@@ -380,9 +510,19 @@ private:
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);
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ ++childIdx)
+ changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsNumber);
break;
}
@@ -399,10 +539,12 @@ private:
} 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);
}
+ changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
@@ -418,8 +560,8 @@ private:
break;
}
+ case PutByValAlias:
case GetArrayLength:
- case GetByteArrayLength:
case GetInt8ArrayLength:
case GetInt16ArrayLength:
case GetInt32ArrayLength:
@@ -429,38 +571,56 @@ private:
case GetUint32ArrayLength:
case GetFloat32ArrayLength:
case GetFloat64ArrayLength:
- case GetStringLength: {
+ case GetStringLength:
+ case Int32ToDouble:
+ case DoubleAsInt32: {
// This node should never be visible at this stage of compilation. It is
// inserted by fixup(), which follows this phase.
ASSERT_NOT_REACHED();
break;
}
- case Flush:
+ case PutByVal:
+ 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 PutByVal:
- case PutByValAlias:
- case PutById:
- case PutByIdDirect:
case CheckStructure:
case CheckFunction:
case PutStructure:
- case PutByOffset:
case TearOffActivation:
+ case CheckNumber:
+ changed |= mergeDefaultFlags(node);
break;
// These gets ignored because it doesn't do anything.
@@ -474,6 +634,7 @@ private:
break;
#else
default:
+ changed |= mergeDefaultFlags(node);
break;
#endif
}
@@ -484,6 +645,28 @@ private:
m_changed |= changed;
}
+
+ bool mergeDefaultFlags(Node& node)
+ {
+ bool changed = false;
+ if (node.flags() & NodeHasVarArgs) {
+ 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(NodeUsedAsValue);
+ if (!node.child2())
+ return changed;
+ changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
+ if (!node.child3())
+ return changed;
+ changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
+ }
+ return changed;
+ }
void propagateForward()
{
@@ -502,10 +685,10 @@ private:
for (m_compileIndex = m_graph.size(); m_compileIndex-- > 0;)
propagate(m_graph[m_compileIndex]);
}
-
- void vote(NodeUse nodeUse, VariableAccessData::Ballot ballot)
+
+ void vote(Edge nodeUse, VariableAccessData::Ballot ballot)
{
- switch (m_graph[nodeUse].op) {
+ switch (m_graph[nodeUse].op()) {
case ValueToInt32:
case UInt32ToNumber:
nodeUse = m_graph[nodeUse].child1();
@@ -514,14 +697,16 @@ private:
break;
}
- if (m_graph[nodeUse].op == GetLocal)
+ if (m_graph[nodeUse].op() == GetLocal)
m_graph[nodeUse].variableAccessData()->vote(ballot);
}
void vote(Node& node, VariableAccessData::Ballot ballot)
{
- if (node.flags & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
+ if (node.flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ childIdx++)
vote(m_graph.m_varArgChildren[childIdx], ballot);
return;
}
@@ -546,7 +731,7 @@ private:
m_graph.m_variableAccessData[i].find()->clearVotes();
for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex) {
Node& node = m_graph[m_compileIndex];
- switch (node.op) {
+ switch (node.op()) {
case ValueAdd:
case ArithAdd:
case ArithSub: {
@@ -576,7 +761,9 @@ private:
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;
@@ -588,7 +775,8 @@ private:
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;
@@ -615,115 +803,25 @@ private:
}
}
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
- VariableAccessData* variableAccessData = m_graph.m_variableAccessData[i].find();
+ VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
+ if (!variableAccessData->isRoot())
+ continue;
if (operandIsArgument(variableAccessData->local())
|| m_graph.isCaptured(variableAccessData->local()))
continue;
m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
}
- }
-
- void fixupNode(Node& node)
- {
- if (!node.shouldGenerate())
- return;
-
- NodeType op = static_cast<NodeType>(node.op);
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex);
-#endif
-
- switch (op) {
- case GetById: {
- if (!isInt32Prediction(m_graph[m_compileIndex].prediction()))
- break;
- if (codeBlock()->identifier(node.identifierNumber()) != globalData().propertyNames->length)
- break;
- 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)
- break;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" @%u -> %s", m_compileIndex, isArray ? "GetArrayLength" : "GetStringLength");
-#endif
- if (isArray)
- node.op = GetArrayLength;
- else if (isString)
- node.op = GetStringLength;
- else if (isByteArray)
- node.op = GetByteArrayLength;
- else if (isInt8Array)
- node.op = GetInt8ArrayLength;
- else if (isInt16Array)
- node.op = GetInt16ArrayLength;
- else if (isInt32Array)
- node.op = GetInt32ArrayLength;
- else if (isUint8Array)
- node.op = GetUint8ArrayLength;
- else if (isUint8ClampedArray)
- node.op = GetUint8ClampedArrayLength;
- else if (isUint16Array)
- node.op = GetUint16ArrayLength;
- else if (isUint32Array)
- node.op = GetUint32ArrayLength;
- else if (isFloat32Array)
- node.op = GetFloat32ArrayLength;
- else if (isFloat64Array)
- node.op = GetFloat64ArrayLength;
- else
- ASSERT_NOT_REACHED();
- // No longer MustGenerate
- ASSERT(node.flags & NodeMustGenerate);
- node.flags &= ~NodeMustGenerate;
- m_graph.deref(m_compileIndex);
- break;
- }
- case GetIndexedPropertyStorage: {
- PredictedType basePrediction = m_graph[node.child2()].prediction();
- if (!(basePrediction & PredictInt32) && basePrediction) {
- node.setOpAndDefaultFlags(Nop);
- m_graph.clearAndDerefChild1(node);
- m_graph.clearAndDerefChild2(node);
- m_graph.clearAndDerefChild3(node);
- node.setRefCount(0);
- }
- break;
- }
- case GetByVal:
- case StringCharAt:
- case StringCharCodeAt: {
- if (!!node.child3() && m_graph[node.child3()].op == Nop)
- node.children.child3() = NodeUse();
- break;
- }
- default:
- break;
+ for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
+ m_changed |= m_graph.m_argumentPositions[i].mergeArgumentAwareness();
+ for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
+ VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
+ if (!variableAccessData->isRoot())
+ continue;
+ if (operandIsArgument(variableAccessData->local())
+ || m_graph.isCaptured(variableAccessData->local()))
+ continue;
+ m_changed |= variableAccessData->makePredictionForDoubleFormat();
}
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog("\n");
-#endif
- }
-
- void fixup()
- {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog("Performing Fixup\n");
-#endif
- for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex)
- fixupNode(m_graph[m_compileIndex]);
}
NodeIndex m_compileIndex;