Title: [261313] trunk
Revision
261313
Author
keith_mil...@apple.com
Date
2020-05-07 11:00:12 -0700 (Thu, 07 May 2020)

Log Message

Fix ArrayMode nodes after r261260
https://bugs.webkit.org/show_bug.cgi?id=211543

Reviewed by Yusuke Suzuki.

I accidentally ran tests with a release build rather than
release+assert when uploading r261260. This patch skips the
CheckArray node in the ArrayMode clobbersTop() logic before
Fixup. And also marks a GetArrayLength in the TypedArray
intrsinics as ExitOK.

This patch also relands r261260.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):

Modified Paths

Added Paths

Diff

Added: trunk/JSTests/stress/for-of-get-by-val-marks-clobbers-exit-state.js (0 => 261313)


--- trunk/JSTests/stress/for-of-get-by-val-marks-clobbers-exit-state.js	                        (rev 0)
+++ trunk/JSTests/stress/for-of-get-by-val-marks-clobbers-exit-state.js	2020-05-07 18:00:12 UTC (rev 261313)
@@ -0,0 +1,10 @@
+const a0 = new Array(100);
+a0.x = 0;
+
+function foo() {
+  for (const q of a0) {}
+}
+
+for (let i = 0; i < 1000; i++) {
+  foo();
+}

Added: trunk/JSTests/stress/put-by-val-correctly-clobbers-exit-state-when-misprofiling-index.js (0 => 261313)


--- trunk/JSTests/stress/put-by-val-correctly-clobbers-exit-state-when-misprofiling-index.js	                        (rev 0)
+++ trunk/JSTests/stress/put-by-val-correctly-clobbers-exit-state-when-misprofiling-index.js	2020-05-07 18:00:12 UTC (rev 261313)
@@ -0,0 +1,10 @@
+let foo = $vm.createBuiltin(`(function (array, index) {
+    index = @idWithProfile(index, "SpecObject");
+    return array[index];
+})`);
+noInline(foo);
+
+for (let i = 0; i < 1e5; ++i) {
+    if (foo([1,2], 0) !== 1)
+        throw new Error();
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (261312 => 261313)


--- trunk/Source/_javascript_Core/ChangeLog	2020-05-07 17:58:19 UTC (rev 261312)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-05-07 18:00:12 UTC (rev 261313)
@@ -1,3 +1,23 @@
+2020-05-07  Keith Miller  <keith_mil...@apple.com>
+
+        Fix ArrayMode nodes after r261260
+        https://bugs.webkit.org/show_bug.cgi?id=211543
+
+        Reviewed by Yusuke Suzuki.
+
+        I accidentally ran tests with a release build rather than
+        release+assert when uploading r261260. This patch skips the
+        CheckArray node in the ArrayMode clobbersTop() logic before
+        Fixup. And also marks a GetArrayLength in the TypedArray
+        intrsinics as ExitOK.
+
+        This patch also relands r261260.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
 2020-05-07  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, reverting r261260.

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (261312 => 261313)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2020-05-07 17:58:19 UTC (rev 261312)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2020-05-07 18:00:12 UTC (rev 261313)
@@ -3750,7 +3750,11 @@
         });
 
         Node* lengthNode = addToGraph(GetArrayLength, OpInfo(ArrayMode(arrayType, Array::Read).asWord()), thisNode);
+        // Our ArrayMode shouldn't cause us to exit here so we should be ok to exit without effects.
+        m_exitOK = true;
+        addToGraph(ExitOK);
 
+
         if (!logSize) {
             set(result, lengthNode);
             return true;
@@ -6901,6 +6905,9 @@
                     Node* iterable = get(bytecode.m_iterable);
                     Node* butterfly = addToGraph(GetButterfly, iterable);
                     Node* length = addToGraph(GetArrayLength, OpInfo(arrayMode.asWord()), iterable, butterfly);
+                    // GetArrayLength is pessimized prior to fixup.
+                    m_exitOK = true;
+                    addToGraph(ExitOK);
                     Node* isOutOfBounds = addToGraph(CompareGreaterEq, Edge(index, Int32Use), Edge(length, Int32Use));
 
                     isDone = addToGraph(ArithBitOr, isDone, isOutOfBounds);

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (261312 => 261313)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2020-05-07 17:58:19 UTC (rev 261312)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2020-05-07 18:00:12 UTC (rev 261313)
@@ -155,6 +155,46 @@
         read(World);
         write(Heap);
     };
+
+    // Since Fixup can widen our ArrayModes based on profiling from other nodes we pessimistically assume
+    // all nodes with an ArrayMode can clobber top. We allow some nodes like CheckArray because they can
+    // only exit.
+    if (graph.m_planStage < PlanStage::AfterFixup && node->hasArrayMode()) {
+        switch (node->op()) {
+        case CheckArray:
+        case CheckArrayOrEmpty:
+            break;
+        case GetIndexedPropertyStorage:
+        case GetArrayLength:
+        case GetVectorLength:
+        case InByVal:
+        case PutByValDirect:
+        case PutByVal:
+        case PutByValAlias:
+        case GetByVal:
+        case StringCharAt:
+        case StringCharCodeAt:
+        case StringCodePointAt:
+        case Arrayify:
+        case ArrayifyToStructure:
+        case ArrayPush:
+        case ArrayPop:
+        case ArrayIndexOf:
+        case HasIndexedProperty:
+        case AtomicsAdd:
+        case AtomicsAnd:
+        case AtomicsCompareExchange:
+        case AtomicsExchange:
+        case AtomicsLoad:
+        case AtomicsOr:
+        case AtomicsStore:
+        case AtomicsSub:
+        case AtomicsXor:
+            return clobberTop();
+        default:
+            DFG_CRASH(graph, node, "Unhandled ArrayMode opcode.");
+        }
+    }
     
     switch (node->op()) {
     case JSConstant:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (261312 => 261313)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-05-07 17:58:19 UTC (rev 261312)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-05-07 18:00:12 UTC (rev 261313)
@@ -180,6 +180,10 @@
     {
         NodeType op = node->op();
 
+#if ASSERT_ENABLED
+        bool usedToClobberExitState = clobbersExitState(m_graph, node);
+#endif
+
         switch (op) {
         case SetLocal: {
             // This gets handled by fixupGetAndSetLocalsInBlock().
@@ -1281,7 +1285,7 @@
                 node->setArrayMode(ArrayMode(Array::Generic, node->arrayMode().action()));
                 break;
             }
-            
+
             node->setArrayMode(
                 node->arrayMode().refine(
                     m_graph, node, base->prediction(), index->prediction()));
@@ -2720,6 +2724,12 @@
             break;
 #endif // not ASSERT_ENABLED
         }
+
+#if ASSERT_ENABLED
+        // It would be invalid for Fixup to take a node that didn't clobber exit state and mark it as clobbering afterwords.
+        DFG_ASSERT(m_graph, node, usedToClobberExitState || !clobbersExitState(m_graph, node));
+#endif
+
     }
 
     void watchHavingABadTime(Node* node)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to