DFG shouldn't insert store barriers when it has it on good authority that we're not...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Sep 2014 22:53:20 +0000 (22:53 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Sep 2014 22:53:20 +0000 (22:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137161

Reviewed by Mark Hahnenberg.

This looks like a 1% Octane speed-up.

* bytecode/SpeculatedType.h:
(JSC::isNotCellSpeculation):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::insertStoreBarrier):
(JSC::DFG::FixupPhase::insertCheck):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateNotCell):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174025 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/SpeculatedType.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNode.h

index e20c5d3..0bc82ae 100644 (file)
@@ -1,3 +1,21 @@
+2014-09-26  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG shouldn't insert store barriers when it has it on good authority that we're not storing a cell
+        https://bugs.webkit.org/show_bug.cgi?id=137161
+
+        Reviewed by Mark Hahnenberg.
+        
+        This looks like a 1% Octane speed-up.
+
+        * bytecode/SpeculatedType.h:
+        (JSC::isNotCellSpeculation):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertStoreBarrier):
+        (JSC::DFG::FixupPhase::insertCheck):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateNotCell):
+
 2014-09-26  Peter Varga  <pvarga@webkit.org>
 
         Fix typo in YARR at BOL check
index 6f658df..b00f297 100644 (file)
@@ -98,6 +98,11 @@ inline bool isCellSpeculation(SpeculatedType value)
     return !!(value & SpecCell) && !(value & ~SpecCell);
 }
 
+inline bool isNotCellSpeculation(SpeculatedType value)
+{
+    return !(value & SpecCell) && value;
+}
+
 inline bool isObjectSpeculation(SpeculatedType value)
 {
     return !!(value & SpecObject) && !(value & ~SpecObject);
index 02ab5d8..c2d35c4 100644 (file)
@@ -644,7 +644,7 @@ private:
             case Array::Arguments:
                 fixEdge<KnownCellUse>(child1);
                 fixEdge<Int32Use>(child2);
-                insertStoreBarrier(m_indexInBlock, child1);
+                insertStoreBarrier(m_indexInBlock, child1, child3);
                 break;
             default:
                 fixEdge<KnownCellUse>(child1);
@@ -682,7 +682,7 @@ private:
                 break;
             case Array::Contiguous:
             case Array::ArrayStorage:
-                insertStoreBarrier(m_indexInBlock, node->child1());
+                insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
                 break;
             default:
                 break;
@@ -854,7 +854,7 @@ private:
 
         case PutClosureVar: {
             fixEdge<KnownCellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
             break;
         }
 
@@ -899,7 +899,7 @@ private:
         case PutByIdFlush:
         case PutByIdDirect: {
             fixEdge<CellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
             break;
         }
 
@@ -942,13 +942,13 @@ private:
             if (!node->child1()->hasStorageResult())
                 fixEdge<KnownCellUse>(node->child1());
             fixEdge<KnownCellUse>(node->child2());
-            insertStoreBarrier(m_indexInBlock, node->child2());
+            insertStoreBarrier(m_indexInBlock, node->child2(), node->child3());
             break;
         }
             
         case MultiPutByOffset: {
             fixEdge<CellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
             break;
         }
             
@@ -1640,10 +1640,45 @@ private:
         edge.setUseKind(useKind);
     }
     
-    void insertStoreBarrier(unsigned indexInBlock, Edge child1)
+    void insertStoreBarrier(unsigned indexInBlock, Edge base, Edge value = Edge())
     {
-        Node* barrierNode = m_graph.addNode(SpecNone, StoreBarrier, m_currentNode->origin, child1);
-        m_insertionSet.insert(indexInBlock, barrierNode);
+        if (!!value) {
+            if (value->shouldSpeculateInt32()) {
+                insertCheck<Int32Use>(indexInBlock, value.node());
+                return;
+            }
+            
+            if (value->shouldSpeculateBoolean()) {
+                insertCheck<BooleanUse>(indexInBlock, value.node());
+                return;
+            }
+            
+            if (value->shouldSpeculateOther()) {
+                insertCheck<OtherUse>(indexInBlock, value.node());
+                return;
+            }
+            
+            if (value->shouldSpeculateNumber()) {
+                insertCheck<NumberUse>(indexInBlock, value.node());
+                return;
+            }
+            
+            if (value->shouldSpeculateNotCell()) {
+                insertCheck<NotCellUse>(indexInBlock, value.node());
+                return;
+            }
+        }
+
+        m_insertionSet.insertNode(
+            indexInBlock, SpecNone, StoreBarrier, m_currentNode->origin, base);
+    }
+    
+    template<UseKind useKind>
+    void insertCheck(unsigned indexInBlock, Node* node)
+    {
+        observeUseKindOnNode<useKind>(node);
+        m_insertionSet.insertNode(
+            indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
     }
 
     void fixIntConvertingEdge(Edge& edge)
index 1bd190b..8c080e2 100644 (file)
@@ -1682,6 +1682,11 @@ struct Node {
         return isCellSpeculation(prediction());
     }
     
+    bool shouldSpeculateNotCell()
+    {
+        return isNotCellSpeculation(prediction());
+    }
+    
     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
     {
         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();