diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractState.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractState.cpp | 189 |
1 files changed, 121 insertions, 68 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index 7ab05f329..6df40ca6f 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -100,7 +100,7 @@ void AbstractState::initialize(Graph& graph) root->cfaShouldRevisit = true; for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) { Node& node = graph[root->variablesAtHead.argument(i)]; - ASSERT(node.op == SetArgument); + ASSERT(node.op() == SetArgument); if (!node.shouldGenerate()) { // The argument is dead. We don't do any checks for such arguments, and so // for the purpose of the analysis, they contain no value. @@ -118,8 +118,6 @@ void AbstractState::initialize(Graph& graph) root->valuesAtHead.argument(i).set(PredictInt32); else if (isArrayPrediction(prediction)) root->valuesAtHead.argument(i).set(PredictArray); - else if (isByteArrayPrediction(prediction)) - root->valuesAtHead.argument(i).set(PredictByteArray); else if (isBooleanPrediction(prediction)) root->valuesAtHead.argument(i).set(PredictBoolean); else if (isInt8ArrayPrediction(prediction)) @@ -222,7 +220,7 @@ bool AbstractState::execute(unsigned indexInBlock) if (!node.shouldGenerate()) return true; - switch (node.op) { + switch (node.op()) { case JSConstant: case WeakJSConstant: { JSValue value = m_graph.valueOfJSConstant(nodeIndex); @@ -253,13 +251,11 @@ bool AbstractState::execute(unsigned indexInBlock) break; } - PredictedType predictedType = node.variableAccessData()->prediction(); + PredictedType predictedType = node.variableAccessData()->argumentAwarePrediction(); if (isInt32Prediction(predictedType)) forNode(node.child1()).filter(PredictInt32); else if (isArrayPrediction(predictedType)) forNode(node.child1()).filter(PredictArray); - else if (isByteArrayPrediction(predictedType)) - forNode(node.child1()).filter(PredictByteArray); else if (isBooleanPrediction(predictedType)) forNode(node.child1()).filter(PredictBoolean); @@ -290,15 +286,30 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(PredictInt32); break; + case DoubleAsInt32: + forNode(node.child1()).filter(PredictNumber); + forNode(nodeIndex).set(PredictInt32); + break; + case ValueToInt32: - if (m_graph[node.child1()].shouldNotSpeculateInteger()) { - if (m_graph[node.child1()].shouldSpeculateDouble()) - forNode(node.child1()).filter(PredictNumber); - } else + if (m_graph[node.child1()].shouldSpeculateInteger()) forNode(node.child1()).filter(PredictInt32); + else if (m_graph[node.child1()].shouldSpeculateNumber()) + forNode(node.child1()).filter(PredictNumber); + else if (m_graph[node.child1()].shouldSpeculateBoolean()) + forNode(node.child1()).filter(PredictBoolean); forNode(nodeIndex).set(PredictInt32); break; + + case Int32ToDouble: + forNode(node.child1()).filter(PredictNumber); + forNode(nodeIndex).set(PredictDouble); + break; + + case CheckNumber: + forNode(node.child1()).filter(PredictNumber); + break; case ValueAdd: case ArithAdd: { @@ -314,7 +325,7 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(PredictDouble); break; } - if (node.op == ValueAdd) { + if (node.op() == ValueAdd) { clobberStructures(indexInBlock); forNode(nodeIndex).set(PredictString | PredictInt32 | PredictNumber); break; @@ -351,7 +362,8 @@ bool AbstractState::execute(unsigned indexInBlock) case ArithMul: case ArithDiv: case ArithMin: - case ArithMax: { + case ArithMax: + case ArithMod: { if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) { forNode(node.child1()).filter(PredictInt32); forNode(node.child2()).filter(PredictInt32); @@ -364,19 +376,6 @@ bool AbstractState::execute(unsigned indexInBlock) break; } - case ArithMod: { - if (m_graph[node.child1()].shouldNotSpeculateInteger() || m_graph[node.child2()].shouldNotSpeculateInteger() || !node.canSpeculateInteger()) { - forNode(node.child1()).filter(PredictNumber); - forNode(node.child2()).filter(PredictNumber); - forNode(nodeIndex).set(PredictDouble); - break; - } - forNode(node.child1()).filter(PredictInt32); - forNode(node.child2()).filter(PredictInt32); - forNode(nodeIndex).set(PredictInt32); - break; - } - case ArithAbs: if (m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger()) { forNode(node.child1()).filter(PredictInt32); @@ -394,7 +393,7 @@ bool AbstractState::execute(unsigned indexInBlock) case LogicalNot: { Node& child = m_graph[node.child1()]; - if (isBooleanPrediction(child.prediction()) || !child.prediction()) + if (isBooleanPrediction(child.prediction())) forNode(node.child1()).filter(PredictBoolean); else if (child.shouldSpeculateFinalObjectOrOther()) forNode(node.child1()).filter(PredictFinalObject | PredictOther); @@ -409,12 +408,24 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(PredictBoolean); break; } + + case IsUndefined: + case IsBoolean: + case IsNumber: + case IsString: + case IsObject: + case IsFunction: { + forNode(nodeIndex).set(PredictBoolean); + break; + } case CompareLess: case CompareLessEq: case CompareGreater: case CompareGreaterEq: case CompareEq: { + forNode(nodeIndex).set(PredictBoolean); + Node& left = m_graph[node.child1()]; Node& right = m_graph[node.child2()]; PredictedType filter; @@ -422,17 +433,45 @@ bool AbstractState::execute(unsigned indexInBlock) filter = PredictInt32; else if (Node::shouldSpeculateNumber(left, right)) filter = PredictNumber; - else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(left, right)) - filter = PredictFinalObject; - else if (node.op == CompareEq && Node::shouldSpeculateArray(left, right)) - filter = PredictArray; - else { + else if (node.op() == CompareEq) { + if ((m_graph.isConstant(node.child1().index()) + && m_graph.valueOfJSConstant(node.child1().index()).isNull()) + || (m_graph.isConstant(node.child2().index()) + && m_graph.valueOfJSConstant(node.child2().index()).isNull())) { + // We know that this won't clobber the world. But that's all we know. + break; + } + + if (Node::shouldSpeculateFinalObject(left, right)) + filter = PredictFinalObject; + else if (Node::shouldSpeculateArray(left, right)) + filter = PredictArray; + else if (left.shouldSpeculateFinalObject() && right.shouldSpeculateFinalObjectOrOther()) { + forNode(node.child1()).filter(PredictFinalObject); + forNode(node.child2()).filter(PredictFinalObject | PredictOther); + break; + } else if (right.shouldSpeculateFinalObject() && left.shouldSpeculateFinalObjectOrOther()) { + forNode(node.child1()).filter(PredictFinalObject | PredictOther); + forNode(node.child2()).filter(PredictFinalObject); + break; + } else if (left.shouldSpeculateArray() && right.shouldSpeculateArrayOrOther()) { + forNode(node.child1()).filter(PredictFinalObject); + forNode(node.child2()).filter(PredictFinalObject | PredictOther); + break; + } else if (right.shouldSpeculateArray() && left.shouldSpeculateArrayOrOther()) { + forNode(node.child1()).filter(PredictFinalObject | PredictOther); + forNode(node.child2()).filter(PredictFinalObject); + break; + } else { + filter = PredictTop; + clobberStructures(indexInBlock); + } + } else { filter = PredictTop; clobberStructures(indexInBlock); } forNode(node.child1()).filter(filter); forNode(node.child2()).filter(filter); - forNode(nodeIndex).set(PredictBoolean); break; } @@ -468,12 +507,6 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(PredictString); break; } - if (m_graph[node.child1()].shouldSpeculateByteArray()) { - forNode(node.child1()).filter(PredictByteArray); - forNode(node.child2()).filter(PredictInt32); - forNode(nodeIndex).set(PredictInt32); - break; - } if (m_graph[node.child1()].shouldSpeculateInt8Array()) { forNode(node.child1()).filter(PredictInt8Array); @@ -514,7 +547,10 @@ bool AbstractState::execute(unsigned indexInBlock) if (m_graph[node.child1()].shouldSpeculateUint32Array()) { forNode(node.child1()).filter(PredictUint32Array); forNode(node.child2()).filter(PredictInt32); - forNode(nodeIndex).set(PredictDouble); + if (node.shouldSpeculateInteger()) + forNode(nodeIndex).set(PredictInt32); + else + forNode(nodeIndex).set(PredictDouble); break; } if (m_graph[node.child1()].shouldSpeculateFloat32Array()) { @@ -543,58 +579,73 @@ bool AbstractState::execute(unsigned indexInBlock) break; } if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) { - ASSERT(node.op == PutByVal); + ASSERT(node.op() == PutByVal); clobberStructures(indexInBlock); forNode(nodeIndex).makeTop(); break; } - if (m_graph[node.child1()].shouldSpeculateByteArray()) { - forNode(node.child1()).filter(PredictByteArray); - forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); - break; - } if (m_graph[node.child1()].shouldSpeculateInt8Array()) { forNode(node.child1()).filter(PredictInt8Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateInt16Array()) { forNode(node.child1()).filter(PredictInt16Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateInt32Array()) { forNode(node.child1()).filter(PredictInt32Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateUint8Array()) { forNode(node.child1()).filter(PredictUint8Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateUint8ClampedArray()) { forNode(node.child1()).filter(PredictUint8ClampedArray); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateUint16Array()) { forNode(node.child1()).filter(PredictUint16Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateUint32Array()) { forNode(node.child1()).filter(PredictUint32Array); forNode(node.child2()).filter(PredictInt32); - forNode(node.child3()).filter(PredictNumber); + if (m_graph[node.child3()].shouldSpeculateInteger()) + forNode(node.child3()).filter(PredictInt32); + else + forNode(node.child3()).filter(PredictNumber); break; } if (m_graph[node.child1()].shouldSpeculateFloat32Array()) { @@ -625,6 +676,13 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).makeTop(); break; + case RegExpExec: + case RegExpTest: + forNode(node.child1()).filter(PredictCell); + forNode(node.child2()).filter(PredictCell); + forNode(nodeIndex).makeTop(); + break; + case Jump: break; @@ -633,7 +691,7 @@ bool AbstractState::execute(unsigned indexInBlock) // propagation, and to take it one step further, where a variable's value // is specialized on each direction of a branch. For now, we don't do this. Node& child = m_graph[node.child1()]; - if (isBooleanPrediction(child.prediction()) || !child.prediction()) + if (child.shouldSpeculateBoolean()) forNode(node.child1()).filter(PredictBoolean); else if (child.shouldSpeculateFinalObjectOrOther()) forNode(node.child1()).filter(PredictFinalObject | PredictOther); @@ -787,10 +845,6 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(PredictInt32); break; - case GetByteArrayLength: - forNode(node.child1()).filter(PredictByteArray); - forNode(nodeIndex).set(PredictInt32); - break; case GetInt8ArrayLength: forNode(node.child1()).filter(PredictInt8Array); forNode(nodeIndex).set(PredictInt32); @@ -854,11 +908,6 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).clear(); break; } - if (m_graph[node.child1()].shouldSpeculateByteArray()) { - forNode(node.child1()).filter(PredictByteArray); - forNode(nodeIndex).clear(); - break; - } if (m_graph[node.child1()].shouldSpeculateInt8Array()) { forNode(node.child1()).filter(PredictInt8Array); @@ -974,6 +1023,10 @@ bool AbstractState::execute(unsigned indexInBlock) case InlineStart: case Nop: break; + + case LastNodeType: + ASSERT_NOT_REACHED(); + break; } return m_isValid; @@ -1005,10 +1058,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract return false; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" It's live, node @%u.\n", nodeIndex); + dataLog(" It's live, node @%u.\n", nodeIndex); #endif - - switch (node.op) { + + switch (node.op()) { case Phi: case SetArgument: case Flush: @@ -1110,7 +1163,7 @@ inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBloc ASSERT(terminal.isTerminal()); - switch (terminal.op) { + switch (terminal.op()) { case Jump: return merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get()); |