diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractState.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractState.cpp | 108 |
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; |