summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractState.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp108
1 files changed, 60 insertions, 48 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 58ff7d23c..e518c24a8 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -839,7 +839,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case GetByVal: {
node.setCanExit(true);
- switch (node.arrayMode()) {
+ switch (node.arrayMode().type()) {
case Array::SelectUsingPredictions:
case Array::Unprofiled:
ASSERT_NOT_REACHED();
@@ -859,18 +859,12 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(node.child2()).filter(SpecInt32);
forNode(nodeIndex).makeTop();
break;
- case IN_BOUNDS_CONTIGUOUS_MODES:
- case IN_BOUNDS_ARRAY_STORAGE_MODES:
+ case Array::Contiguous:
+ case Array::ArrayStorage:
+ case Array::SlowPutArrayStorage:
forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).makeTop();
- break;
- case OUT_OF_BOUNDS_CONTIGUOUS_MODES:
- case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
- case SLOW_PUT_ARRAY_STORAGE_MODES:
- case ALL_EFFECTFUL_MODES:
- forNode(node.child1()).filter(SpecCell);
- forNode(node.child2()).filter(SpecInt32);
- clobberWorld(node.codeOrigin, indexInBlock);
+ if (node.arrayMode().isOutOfBounds())
+ clobberWorld(node.codeOrigin, indexInBlock);
forNode(nodeIndex).makeTop();
break;
case Array::Int8Array:
@@ -925,31 +919,32 @@ bool AbstractState::execute(unsigned indexInBlock)
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
Edge child3 = m_graph.varArgChild(node, 2);
- switch (modeForPut(node.arrayMode())) {
+ switch (node.arrayMode().modeForPut().type()) {
case Array::ForceExit:
m_isValid = false;
break;
case Array::Generic:
clobberWorld(node.codeOrigin, indexInBlock);
break;
- case IN_BOUNDS_CONTIGUOUS_MODES:
- case CONTIGUOUS_TO_TAIL_MODES:
- case IN_BOUNDS_ARRAY_STORAGE_MODES:
+ case Array::Contiguous:
+ case Array::ArrayStorage:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
+ if (node.arrayMode().isOutOfBounds())
+ clobberWorld(node.codeOrigin, indexInBlock);
break;
- case OUT_OF_BOUNDS_CONTIGUOUS_MODES:
- case ARRAY_STORAGE_TO_HOLE_MODES:
- case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
- case SLOW_PUT_ARRAY_STORAGE_MODES:
- case ALL_EFFECTFUL_MODES:
+ case Array::SlowPutArrayStorage:
forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
- clobberWorld(node.codeOrigin, indexInBlock);
+ if (node.arrayMode().mayStoreToHole())
+ clobberWorld(node.codeOrigin, indexInBlock);
break;
case Array::Arguments:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
break;
case Array::Int8Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -957,6 +952,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Int16Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -964,6 +960,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Int32Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -971,6 +968,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Uint8Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -978,6 +976,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Uint8ClampedArray:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -985,6 +984,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Uint16Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -992,6 +992,7 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Uint32Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
if (m_graph[child3].shouldSpeculateInteger())
forNode(child3).filter(SpecInt32);
@@ -999,15 +1000,17 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(child3).filter(SpecNumber);
break;
case Array::Float32Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
forNode(child3).filter(SpecNumber);
break;
case Array::Float64Array:
+ forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
forNode(child3).filter(SpecNumber);
break;
default:
- ASSERT_NOT_REACHED();
+ CRASH();
break;
}
break;
@@ -1324,7 +1327,8 @@ bool AbstractState::execute(unsigned indexInBlock)
// the futurePossibleStructure set then the constant folding phase should
// turn this into a watchpoint instead.
StructureSet& set = node.structureSet();
- if (value.m_futurePossibleStructure.isSubsetOf(set))
+ if (value.m_futurePossibleStructure.isSubsetOf(set)
+ || value.m_currentKnownStructure.isSubsetOf(set))
m_foundConstants = true;
node.setCanExit(
!value.m_currentKnownStructure.isSubsetOf(set)
@@ -1365,23 +1369,24 @@ bool AbstractState::execute(unsigned indexInBlock)
case GetButterfly:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
- node.setCanExit(false);
+ node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
forNode(node.child1()).filter(SpecCell);
forNode(nodeIndex).clear(); // The result is not a JS value.
break;
case CheckArray: {
- if (modeAlreadyChecked(forNode(node.child1()), node.arrayMode())) {
+ if (node.arrayMode().alreadyChecked(forNode(node.child1()))) {
m_foundConstants = true;
node.setCanExit(false);
break;
}
node.setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
- switch (node.arrayMode()) {
+ switch (node.arrayMode().type()) {
case Array::String:
forNode(node.child1()).filter(SpecString);
break;
- case ALL_CONTIGUOUS_MODES:
- case ALL_ARRAY_STORAGE_MODES:
+ case Array::Contiguous:
+ case Array::ArrayStorage:
+ case Array::SlowPutArrayStorage:
// This doesn't filter anything meaningful right now. We may want to add
// CFA tracking of array mode speculations, but we don't have that, yet.
forNode(node.child1()).filter(SpecCell);
@@ -1420,33 +1425,40 @@ bool AbstractState::execute(unsigned indexInBlock)
ASSERT_NOT_REACHED();
break;
}
- forNode(node.child1()).filterArrayModes(arrayModesFor(node.arrayMode()));
+ forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
+ m_haveStructures = true;
break;
}
case Arrayify: {
- if (modeAlreadyChecked(forNode(node.child1()), node.arrayMode())) {
+ if (node.arrayMode().alreadyChecked(forNode(node.child1()))) {
m_foundConstants = true;
node.setCanExit(false);
break;
}
- switch (node.arrayMode()) {
- case ALL_EFFECTFUL_MODES:
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecCell);
- if (node.child2())
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).clear();
- clobberStructures(indexInBlock);
- forNode(node.child1()).filterArrayModes(arrayModesFor(node.arrayMode()));
- break;
- default:
- CRASH();
- break;
- }
+ ASSERT(node.arrayMode().conversion() == Array::Convert);
+ node.setCanExit(true);
+ forNode(node.child1()).filter(SpecCell);
+ if (node.child2())
+ forNode(node.child2()).filter(SpecInt32);
+ clobberStructures(indexInBlock);
+ forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
+ m_haveStructures = true;
+ break;
+ }
+ case ArrayifyToStructure: {
+ AbstractValue& value = forNode(node.child1());
+ StructureSet set = node.structure();
+ if (value.m_futurePossibleStructure.isSubsetOf(set)
+ || value.m_currentKnownStructure.isSubsetOf(set))
+ m_foundConstants = true;
+ node.setCanExit(true);
+ clobberStructures(indexInBlock);
+ value.filter(set);
+ m_haveStructures = true;
break;
}
case GetIndexedPropertyStorage: {
- switch (node.arrayMode()) {
+ switch (node.arrayMode().type()) {
case Array::String:
// Strings are weird - we may spec fail if the string was a rope. That is of course
// stupid, and we should fix that, but for now let's at least be honest about it.
@@ -1460,13 +1472,13 @@ bool AbstractState::execute(unsigned indexInBlock)
break;
}
case GetByOffset:
- node.setCanExit(false);
+ node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
forNode(node.child1()).filter(SpecCell);
forNode(nodeIndex).makeTop();
break;
case PutByOffset:
- node.setCanExit(false);
+ node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
forNode(node.child1()).filter(SpecCell);
break;