summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp108
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