diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 108 |
1 files changed, 75 insertions, 33 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index 5a76aa8df..1ba40def3 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -69,7 +69,7 @@ private: NodeType op = node.op(); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex); + dataLogF(" %s @%u: ", Graph::opName(op), m_compileIndex); #endif switch (op) { @@ -134,6 +134,17 @@ private: m_graph[node.child2()].prediction())); blessArrayOperation(node.child1(), node.child2(), 2); + + Node* nodePtr = &m_graph[m_compileIndex]; + ArrayMode arrayMode = nodePtr->arrayMode(); + if (arrayMode.type() == Array::Double + && arrayMode.arrayClass() == Array::OriginalArray + && arrayMode.speculation() == Array::InBounds + && arrayMode.conversion() == Array::AsIs + && m_graph.globalObjectFor(nodePtr->codeOrigin)->arrayPrototypeChainIsSane() + && !(nodePtr->flags() & NodeUsedAsOther)) + nodePtr->setArrayMode(arrayMode.withSpeculation(Array::SaneChain)); + break; } case StringCharAt: @@ -145,7 +156,30 @@ private: } case ArrayPush: { + // May need to refine the array mode in case the value prediction contravenes + // the array prediction. For example, we may have evidence showing that the + // array is in Int32 mode, but the value we're storing is likely to be a double. + // Then we should turn this into a conversion to Double array followed by the + // push. On the other hand, we absolutely don't want to refine based on the + // base prediction. If it has non-cell garbage in it, then we want that to be + // ignored. That's because ArrayPush can't handle any array modes that aren't + // array-related - so if refine() turned this into a "Generic" ArrayPush then + // that would break things. + node.setArrayMode( + node.arrayMode().refine( + m_graph[node.child1()].prediction() & SpecCell, + SpecInt32, + m_graph[node.child2()].prediction())); blessArrayOperation(node.child1(), node.child2(), 2); + + Node* nodePtr = &m_graph[m_compileIndex]; + switch (nodePtr->arrayMode().type()) { + case Array::Double: + fixDoubleEdge(1); + break; + default: + break; + } break; } @@ -236,7 +270,7 @@ private: case ValueAdd: { if (m_graph.addShouldSpeculateInteger(node)) break; - if (!Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()])) + if (!Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()])) break; fixDoubleEdge(0); fixDoubleEdge(1); @@ -262,7 +296,7 @@ private: case ArithMin: case ArithMax: case ArithMod: { - if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]) + if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) break; fixDoubleEdge(0); @@ -279,7 +313,7 @@ private: } case ArithDiv: { - if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]) + if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) { if (isX86()) break; @@ -307,7 +341,7 @@ private: } case ArithAbs: { - if (m_graph[node.child1()].shouldSpeculateInteger() + if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic() && node.canSpeculateInteger()) break; fixDoubleEdge(0); @@ -328,13 +362,17 @@ private: node.setArrayMode( node.arrayMode().refine( m_graph[child1].prediction(), - m_graph[child2].prediction())); + m_graph[child2].prediction(), + m_graph[child3].prediction())); blessArrayOperation(child1, child2, 3); Node* nodePtr = &m_graph[m_compileIndex]; switch (nodePtr->arrayMode().modeForPut().type()) { + case Array::Double: + fixDoubleEdge(2); + break; case Array::Int8Array: case Array::Int16Array: case Array::Int32Array: @@ -355,16 +393,29 @@ private: break; } + case NewArray: { + for (unsigned i = m_graph.varArgNumChildren(node); i--;) { + node.setIndexingType( + leastUpperBoundOfIndexingTypeAndType( + node.indexingType(), m_graph[m_graph.varArgChild(node, i)].prediction())); + } + if (node.indexingType() == ArrayWithDouble) { + for (unsigned i = m_graph.varArgNumChildren(node); i--;) + fixDoubleEdge(i); + } + break; + } + default: break; } #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) if (!(node.flags() & NodeHasVarArgs)) { - dataLog("new children: "); + dataLogF("new children: "); node.dumpChildren(WTF::dataFile()); } - dataLog("\n"); + dataLogF("\n"); #endif } @@ -384,29 +435,12 @@ private: m_graph.ref(array); + Structure* structure = arrayMode.originalArrayStructure(m_graph, codeOrigin); + if (arrayMode.doesConversion()) { if (index != NoNode) m_graph.ref(index); - Structure* structure = 0; - if (arrayMode.isJSArrayWithOriginalStructure()) { - JSGlobalObject* globalObject = m_graph.baselineCodeBlockFor(codeOrigin)->globalObject(); - switch (arrayMode.type()) { - case Array::Contiguous: - structure = globalObject->arrayStructure(); - if (structure->indexingType() != ArrayWithContiguous) - structure = 0; - break; - case Array::ArrayStorage: - structure = globalObject->arrayStructureWithArrayStorage(); - if (structure->indexingType() != ArrayWithArrayStorage) - structure = 0; - break; - default: - break; - } - } - if (structure) { Node arrayify(ArrayifyToStructure, codeOrigin, OpInfo(structure), OpInfo(arrayMode.asWord()), array, index); arrayify.ref(); @@ -421,11 +455,19 @@ private: m_insertionSet.append(m_indexInBlock, arrayifyIndex); } } else { - Node checkArray(CheckArray, codeOrigin, OpInfo(arrayMode.asWord()), array); - checkArray.ref(); - NodeIndex checkArrayIndex = m_graph.size(); - m_graph.append(checkArray); - m_insertionSet.append(m_indexInBlock, checkArrayIndex); + if (structure) { + Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(structure)), array); + checkStructure.ref(); + NodeIndex checkStructureIndex = m_graph.size(); + m_graph.append(checkStructure); + m_insertionSet.append(m_indexInBlock, checkStructureIndex); + } else { + Node checkArray(CheckArray, codeOrigin, OpInfo(arrayMode.asWord()), array); + checkArray.ref(); + NodeIndex checkArrayIndex = m_graph.size(); + m_graph.append(checkArray); + m_insertionSet.append(m_indexInBlock, checkArrayIndex); + } } if (!storageCheck(arrayMode)) @@ -506,7 +548,7 @@ private: NodeIndex resultIndex = (NodeIndex)m_graph.size(); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog("(replacing @%u->@%u with @%u->@%u) ", + dataLogF("(replacing @%u->@%u with @%u->@%u) ", m_compileIndex, edge.index(), m_compileIndex, resultIndex); #endif |