DFG generic array access cases should not be guarded by CheckStructure even of the profiling tells us that it could be
https://bugs.webkit.org/show_bug.cgi?id=112183

Reviewed by Oliver Hunt.
        
Slight speed-up on string-unpack-code.

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::findAndRemoveUnnecessaryStructureCheck):
(FixupPhase):
(JSC::DFG::FixupPhase::checkArray):
(JSC::DFG::FixupPhase::blessArrayOperation):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145578 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index d92d357..4b0bbf3 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -838,7 +838,26 @@
         m_insertionSet.execute(block);
     }
     
-    Node* checkArray(ArrayMode arrayMode, CodeOrigin codeOrigin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
+    void findAndRemoveUnnecessaryStructureCheck(Node* array, const CodeOrigin& codeOrigin)
+    {
+        for (unsigned index = m_indexInBlock; index--;) {
+            Node* previousNode = m_block->at(index);
+            if (previousNode->codeOrigin != codeOrigin)
+                return;
+            
+            if (previousNode->op() != CheckStructure)
+                continue;
+            
+            if (previousNode->child1() != array)
+                continue;
+            
+            previousNode->child1() = Edge();
+            previousNode->convertToPhantom();
+            return; // Assume we were smart enough to only insert one CheckStructure on the array.
+        }
+    }
+    
+    Node* checkArray(ArrayMode arrayMode, const CodeOrigin& codeOrigin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
     {
         ASSERT(arrayMode.isSpecific());
         
@@ -850,12 +869,9 @@
             if (structure) {
                 if (m_indexInBlock > 0) {
                     // If the previous node was a CheckStructure inserted because of stuff
-                    // that the array profile told us, then remove it.
-                    Node* previousNode = m_block->at(m_indexInBlock - 1);
-                    if (previousNode->op() == CheckStructure
-                        && previousNode->child1() == array
-                        && previousNode->codeOrigin == codeOrigin)
-                        previousNode->convertToPhantom();
+                    // that the array profile told us, then remove it, since we're going to be
+                    // doing arrayification instead.
+                    findAndRemoveUnnecessaryStructureCheck(array, codeOrigin);
                 }
                 
                 m_insertionSet.insertNode(
@@ -908,6 +924,7 @@
             return;
             
         case Array::Generic:
+            findAndRemoveUnnecessaryStructureCheck(base.node(), node->codeOrigin);
             return;
             
         default: {