diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index 5a76aa8df..621d6e96a 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -145,7 +145,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 +259,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 +285,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 +302,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 +330,7 @@ private: } case ArithAbs: { - if (m_graph[node.child1()].shouldSpeculateInteger() + if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic() && node.canSpeculateInteger()) break; fixDoubleEdge(0); @@ -328,13 +351,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,6 +382,19 @@ 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; } @@ -392,15 +432,17 @@ private: if (arrayMode.isJSArrayWithOriginalStructure()) { JSGlobalObject* globalObject = m_graph.baselineCodeBlockFor(codeOrigin)->globalObject(); switch (arrayMode.type()) { + case Array::Int32: + structure = globalObject->originalArrayStructureForIndexingType(ArrayWithInt32); + break; + case Array::Double: + structure = globalObject->originalArrayStructureForIndexingType(ArrayWithDouble); + break; case Array::Contiguous: - structure = globalObject->arrayStructure(); - if (structure->indexingType() != ArrayWithContiguous) - structure = 0; + structure = globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous); break; case Array::ArrayStorage: - structure = globalObject->arrayStructureWithArrayStorage(); - if (structure->indexingType() != ArrayWithArrayStorage) - structure = 0; + structure = globalObject->originalArrayStructureForIndexingType(ArrayWithArrayStorage); break; default: break; |