[DFG] Introduce ArrayUse
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Sep 2016 21:17:33 +0000 (21:17 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Sep 2016 21:17:33 +0000 (21:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162063

Reviewed by Keith Miller.

ArrayUse is particularly useful: for IsJSArray.
We can drop IsJSArray in fixup phase by setting ArrayUse edge filter.

Since @isJSArray user is limited (Array.prototype.concat), the effect of this patch is small.
But later, I'll update {@isArray, Array.isArray} to use @isJSArray[1]. In that patch, we are planning
to implement more aggressive optimization like, setting CellUse edge filter to avoid cell check in
SpeculativeJIT::compileIsJSArray.

In the benchmark using Array.prototype.concat, we can see perf improvement since we can drop IsJSArray in fixup phase.

                                             baseline                  patched

    lazy-array-species-watchpoints       25.0911+-0.0516     ^     24.7687+-0.0767        ^ definitely 1.0130x faster

[1]: https://bugs.webkit.org/show_bug.cgi?id=162000

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculateArray):
(JSC::DFG::SpeculativeJIT::speculate):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGUseKind.cpp:
(WTF::printInternal):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
(JSC::DFG::isCell):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::speculate):
(JSC::FTL::DFG::LowerDFGToB3::speculateArray):
(JSC::FTL::DFG::LowerDFGToB3::speculateObject): Deleted.

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGUseKind.cpp
Source/JavaScriptCore/dfg/DFGUseKind.h
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

index 22c8ce8..733cf6c 100644 (file)
@@ -1,3 +1,46 @@
+2016-09-16  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [DFG] Introduce ArrayUse
+        https://bugs.webkit.org/show_bug.cgi?id=162063
+
+        Reviewed by Keith Miller.
+
+        ArrayUse is particularly useful: for IsJSArray.
+        We can drop IsJSArray in fixup phase by setting ArrayUse edge filter.
+
+        Since @isJSArray user is limited (Array.prototype.concat), the effect of this patch is small.
+        But later, I'll update {@isArray, Array.isArray} to use @isJSArray[1]. In that patch, we are planning
+        to implement more aggressive optimization like, setting CellUse edge filter to avoid cell check in
+        SpeculativeJIT::compileIsJSArray.
+
+        In the benchmark using Array.prototype.concat, we can see perf improvement since we can drop IsJSArray in fixup phase.
+
+                                                     baseline                  patched
+
+            lazy-array-species-watchpoints       25.0911+-0.0516     ^     24.7687+-0.0767        ^ definitely 1.0130x faster
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=162000
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculateArray):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isCell):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::speculate):
+        (JSC::FTL::DFG::LowerDFGToB3::speculateArray):
+        (JSC::FTL::DFG::LowerDFGToB3::speculateObject): Deleted.
+
 2016-09-16  Joseph Pecoraro  <pecoraro@apple.com>
 
         test262: Various Constructors length properties should be configurable
index 27a0f30..628a06d 100644 (file)
@@ -1417,6 +1417,16 @@ private:
             }
             break;
 
+        case IsJSArray:
+            if (node->child1()->shouldSpeculateArray()) {
+                m_insertionSet.insertNode(
+                    m_indexInBlock, SpecNone, Check, node->origin,
+                    Edge(node->child1().node(), ArrayUse));
+                m_graph.convertToConstant(node, jsBoolean(true));
+                observeUseKindOnNode<ArrayUse>(node);
+            }
+            break;
+
         case GetEnumerableLength: {
             fixEdge<CellUse>(node->child1());
             break;
@@ -1622,7 +1632,6 @@ private:
         case NewRegexp:
         case DeleteById:
         case DeleteByVal:
-        case IsJSArray:
         case IsTypedArrayView:
         case IsEmpty:
         case IsUndefined:
index fd76950..8fdc56f 100644 (file)
@@ -55,6 +55,7 @@ public:
         case CellUse:
         case CellOrOtherUse:
         case ObjectUse:
+        case ArrayUse:
         case FunctionUse:
         case FinalObjectUse:
         case RegExpObjectUse:
index 6f172c7..331331f 100644 (file)
@@ -7394,6 +7394,20 @@ void SpeculativeJIT::speculateRegExpObject(Edge edge)
     speculateRegExpObject(edge, operand.gpr());
 }
 
+void SpeculativeJIT::speculateArray(Edge edge, GPRReg cell)
+{
+    speculateCellType(edge, cell, SpecArray, ArrayType);
+}
+
+void SpeculativeJIT::speculateArray(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecArray))
+        return;
+
+    SpeculateCellOperand operand(this, edge);
+    speculateArray(edge, operand.gpr());
+}
+
 void SpeculativeJIT::speculateMapObject(Edge edge, GPRReg cell)
 {
     speculateCellType(edge, cell, SpecMapObject, JSMapType);
@@ -7703,6 +7717,9 @@ void SpeculativeJIT::speculate(Node*, Edge edge)
     case FunctionUse:
         speculateFunction(edge);
         break;
+    case ArrayUse:
+        speculateArray(edge);
+        break;
     case FinalObjectUse:
         speculateFinalObject(edge);
         break;
index 9a77732..199d2a0 100644 (file)
@@ -2674,6 +2674,8 @@ public:
     void speculateCell(Edge);
     void speculateCellOrOther(Edge);
     void speculateObject(Edge);
+    void speculateArray(Edge, GPRReg cell);
+    void speculateArray(Edge);
     void speculateFunction(Edge);
     void speculateFinalObject(Edge);
     void speculateRegExpObject(Edge, GPRReg cell);
index 6956498..792eb0f 100644 (file)
@@ -85,6 +85,9 @@ void printInternal(PrintStream& out, UseKind useKind)
     case ObjectUse:
         out.print("Object");
         return;
+    case ArrayUse:
+        out.print("Array");
+        return;
     case FunctionUse:
         out.print("Function");
         return;
index a5c21c1..3dec5e1 100644 (file)
@@ -53,6 +53,7 @@ enum UseKind {
     KnownCellUse,
     CellOrOtherUse,
     ObjectUse,
+    ArrayUse,
     FunctionUse,
     FinalObjectUse,
     RegExpObjectUse,
@@ -117,6 +118,8 @@ inline SpeculatedType typeFilterFor(UseKind useKind)
         return SpecCell | SpecOther;
     case ObjectUse:
         return SpecObject;
+    case ArrayUse:
+        return SpecArray;
     case FunctionUse:
         return SpecFunction;
     case FinalObjectUse:
@@ -218,6 +221,7 @@ inline bool isCell(UseKind kind)
     case CellUse:
     case KnownCellUse:
     case ObjectUse:
+    case ArrayUse:
     case FunctionUse:
     case FinalObjectUse:
     case RegExpObjectUse:
index e61b4ef..f369839 100644 (file)
@@ -422,6 +422,7 @@ CapabilityLevel canCompile(Graph& graph)
                 case KnownCellUse:
                 case CellOrOtherUse:
                 case ObjectUse:
+                case ArrayUse:
                 case FunctionUse:
                 case ObjectOrOtherUse:
                 case StringUse:
index 0b1a02f..75ecec2 100644 (file)
@@ -10676,6 +10676,9 @@ private:
         case ObjectUse:
             speculateObject(edge);
             break;
+        case ArrayUse:
+            speculateArray(edge);
+            break;
         case FunctionUse:
             speculateFunction(edge);
             break;
@@ -10960,6 +10963,17 @@ private:
     {
         speculateObject(edge, lowCell(edge));
     }
+
+    void speculateArray(Edge edge, LValue cell)
+    {
+        FTL_TYPE_CHECK(
+            jsValueValue(cell), edge, SpecArray, isNotType(cell, ArrayType));
+    }
+
+    void speculateArray(Edge edge)
+    {
+        speculateArray(edge, lowCell(edge));
+    }
     
     void speculateFunction(Edge edge, LValue cell)
     {