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.cpp64
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;