DFG generic array access cases should not be guarded by CheckStructure even of the...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 20:38:26 +0000 (20:38 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2013 20:38:26 +0000 (20:38 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@145578 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

index 4319a4d..295abc6 100644 (file)
@@ -1,3 +1,18 @@
+2013-03-12  Filip Pizlo  <fpizlo@apple.com>
+
+        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):
+
 2013-03-12  Gabor Rapcsanyi  <rgabor@webkit.org>
 
         https://bugs.webkit.org/show_bug.cgi?id=112141
index d92d357..4b0bbf3 100644 (file)
@@ -838,7 +838,26 @@ private:
         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 @@ private:
             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 @@ private:
             return;
             
         case Array::Generic:
+            findAndRemoveUnnecessaryStructureCheck(base.node(), node->codeOrigin);
             return;
             
         default: {