Title: [230287] trunk
Revision
230287
Author
[email protected]
Date
2018-04-04 17:30:48 -0700 (Wed, 04 Apr 2018)

Log Message

REGRESSION(r222563): removed DoubleReal type check causes tons of crashes because CSE has never known how to handle SaneChain
https://bugs.webkit.org/show_bug.cgi?id=184319

Reviewed by Saam Barati.

JSTests:

* stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js: Added.
(foo):
(bar):
* stress/array-push-nan-to-double-array.js: Added.
(foo):
(bar):

Source/_javascript_Core:

In r222581, we replaced type checks about DoubleReal in ArrayPush in the DFG/FTL backends with
assertions. That's correct because FixupPhase was emitting those checks as Check(DoubleRealRep:) before
the ArrayPush.

But this revealed a longstanding CSE bug: CSE will happily match a SaneChain GetByVal with a InBounds
GetByVal. SaneChain can return NaN while InBounds cannot. This means that if we first use AI to
eliminate the Check(DoubleRealRep:) based on the input being a GetByVal(InBounds) but then replace that
with a GetByVal(SaneChain), then we will hit the assertion.

This teaches CSE to not replace GetByVal(InBounds) with GetByVal(SaneChain) and vice versa. That gets
tricky because PutByVal can match either. So, we use the fact that it's legal for a store to def() more
than once: PutByVal now defs() a HeapLocation for InBounds and a HeapLocation for SaneChain.

* dfg/DFGCSEPhase.cpp:
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGHeapLocation.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArrayPush):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (230286 => 230287)


--- trunk/JSTests/ChangeLog	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/JSTests/ChangeLog	2018-04-05 00:30:48 UTC (rev 230287)
@@ -1,3 +1,17 @@
+2018-04-04  Filip Pizlo  <[email protected]>
+
+        REGRESSION(r222563): removed DoubleReal type check causes tons of crashes because CSE has never known how to handle SaneChain
+        https://bugs.webkit.org/show_bug.cgi?id=184319
+
+        Reviewed by Saam Barati.
+
+        * stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js: Added.
+        (foo):
+        (bar):
+        * stress/array-push-nan-to-double-array.js: Added.
+        (foo):
+        (bar):
+
 2018-04-03  Mark Lam  <[email protected]>
 
         Test js-fixed-array-out-of-memory.js should be excluded for memory limited devices.

Added: trunk/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js (0 => 230287)


--- trunk/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js	                        (rev 0)
+++ trunk/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js	2018-04-05 00:30:48 UTC (rev 230287)
@@ -0,0 +1,23 @@
+function foo(array, otherArray, i)
+{
+    var x = otherArray[i];
+    var y = otherArray[i];
+    array.push(y);
+    return x / 42;
+}
+
+function bar()
+{
+    return [];
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i)
+    foo(bar(), [42.5], 0);
+
+var result = bar();
+foo(result, [,42.5], 0);
+if (result[0] !== void 0)
+    throw "Bad result: " + result;

Added: trunk/JSTests/stress/array-push-nan-to-double-array.js (0 => 230287)


--- trunk/JSTests/stress/array-push-nan-to-double-array.js	                        (rev 0)
+++ trunk/JSTests/stress/array-push-nan-to-double-array.js	2018-04-05 00:30:48 UTC (rev 230287)
@@ -0,0 +1,20 @@
+function foo(array, num, denum)
+{
+    array.push(num/denum);
+}
+
+function bar()
+{
+    return [];
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i)
+    foo(bar(), 42.5, 3.1);
+
+var result = bar();
+foo(result, 0, 0);
+if ("" + result[0] !== "NaN")
+    throw "Bad result: " + result;

Modified: trunk/Source/_javascript_Core/ChangeLog (230286 => 230287)


--- trunk/Source/_javascript_Core/ChangeLog	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-04-05 00:30:48 UTC (rev 230287)
@@ -1,5 +1,34 @@
 2018-04-04  Filip Pizlo  <[email protected]>
 
+        REGRESSION(r222563): removed DoubleReal type check causes tons of crashes because CSE has never known how to handle SaneChain
+        https://bugs.webkit.org/show_bug.cgi?id=184319
+
+        Reviewed by Saam Barati.
+
+        In r222581, we replaced type checks about DoubleReal in ArrayPush in the DFG/FTL backends with
+        assertions. That's correct because FixupPhase was emitting those checks as Check(DoubleRealRep:) before
+        the ArrayPush.
+
+        But this revealed a longstanding CSE bug: CSE will happily match a SaneChain GetByVal with a InBounds
+        GetByVal. SaneChain can return NaN while InBounds cannot. This means that if we first use AI to
+        eliminate the Check(DoubleRealRep:) based on the input being a GetByVal(InBounds) but then replace that
+        with a GetByVal(SaneChain), then we will hit the assertion.
+
+        This teaches CSE to not replace GetByVal(InBounds) with GetByVal(SaneChain) and vice versa. That gets
+        tricky because PutByVal can match either. So, we use the fact that it's legal for a store to def() more
+        than once: PutByVal now defs() a HeapLocation for InBounds and a HeapLocation for SaneChain.
+
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArrayPush):
+
+2018-04-04  Filip Pizlo  <[email protected]>
+
         Remove poisoning of typed array vector
         https://bugs.webkit.org/show_bug.cgi?id=184313
 

Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (230286 => 230287)


--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2018-04-05 00:30:48 UTC (rev 230287)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -469,22 +469,21 @@
                         case Array::Int32:
                             if (!mode.isInBounds())
                                 break;
-                            heap = HeapLocation(
-                                indexedPropertyLoc, IndexedInt32Properties, base, index);
+                            heap = HeapLocation(indexedPropertyLoc, IndexedInt32Properties, base, index);
                             break;
                             
-                        case Array::Double:
+                        case Array::Double: {
                             if (!mode.isInBounds())
                                 break;
-                            heap = HeapLocation(
-                                indexedPropertyLoc, IndexedDoubleProperties, base, index);
+                            LocationKind kind = mode.isSaneChain() ? IndexedPropertyDoubleSaneChainLoc : IndexedPropertyDoubleLoc;
+                            heap = HeapLocation(kind, IndexedDoubleProperties, base, index);
                             break;
+                        }
                             
                         case Array::Contiguous:
                             if (!mode.isInBounds())
                                 break;
-                            heap = HeapLocation(
-                                indexedPropertyLoc, IndexedContiguousProperties, base, index);
+                            heap = HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, base, index);
                             break;
                             
                         case Array::Int8Array:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (230286 => 230287)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-04-05 00:30:48 UTC (rev 230287)
@@ -812,7 +812,8 @@
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
                 read(IndexedDoubleProperties);
-                def(HeapLocation(indexedPropertyLoc, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
+                LocationKind kind = mode.isSaneChain() ? IndexedPropertyDoubleSaneChainLoc : IndexedPropertyDoubleLoc;
+                def(HeapLocation(kind, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
             read(World);
@@ -931,7 +932,8 @@
             write(IndexedDoubleProperties);
             if (node->arrayMode().mayStoreToHole())
                 write(Butterfly_publicLength);
-            def(HeapLocation(indexedPropertyLoc, IndexedDoubleProperties, base, index), LazyNode(value));
+            def(HeapLocation(IndexedPropertyDoubleLoc, IndexedDoubleProperties, base, index), LazyNode(value));
+            def(HeapLocation(IndexedPropertyDoubleSaneChainLoc, IndexedDoubleProperties, base, index), LazyNode(value));
             return;
             
         case Array::Contiguous:

Modified: trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp (230286 => 230287)


--- trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-04-05 00:30:48 UTC (rev 230287)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -128,6 +128,10 @@
         out.print("IndexedPropertyDoubleLoc");
         return;
 
+    case IndexedPropertyDoubleSaneChainLoc:
+        out.print("IndexedPropertyDoubleSaneChainLoc");
+        return;
+
     case IndexedPropertyInt52Loc:
         out.print("IndexedPropertyInt52Loc");
         return;

Modified: trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h (230286 => 230287)


--- trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-04-05 00:30:48 UTC (rev 230287)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,6 +48,7 @@
     GlobalVariableLoc,
     HasIndexedPropertyLoc,
     IndexedPropertyDoubleLoc,
+    IndexedPropertyDoubleSaneChainLoc,
     IndexedPropertyInt52Loc,
     IndexedPropertyJSLoc,
     IndexedPropertyStorageLoc,

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (230286 => 230287)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-04-05 00:30:48 UTC (rev 230287)
@@ -8216,7 +8216,7 @@
             JSValueRegs valueRegs = value.jsValueRegs();
 
             if (node->arrayMode().type() == Array::Int32)
-                RELEASE_ASSERT(!needsTypeCheck(element, SpecInt32Only));
+                DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecInt32Only));
 
             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
@@ -8261,7 +8261,7 @@
             JSValueRegs valueRegs = value.jsValueRegs();
 
             if (node->arrayMode().type() == Array::Int32)
-                RELEASE_ASSERT(!needsTypeCheck(element, SpecInt32Only));
+                DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecInt32Only));
 
             m_jit.storeValue(valueRegs, MacroAssembler::Address(bufferGPR, sizeof(EncodedJSValue) * elementIndex));
             value.use();
@@ -8288,7 +8288,7 @@
             SpeculateDoubleOperand value(this, element);
             FPRReg valueFPR = value.fpr();
 
-            RELEASE_ASSERT(!needsTypeCheck(element, SpecDoubleReal));
+            DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecDoubleReal));
 
             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
@@ -8332,7 +8332,7 @@
             SpeculateDoubleOperand value(this, element);
             FPRReg valueFPR = value.fpr();
 
-            RELEASE_ASSERT(!needsTypeCheck(element, SpecDoubleReal));
+            DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecDoubleReal));
 
             m_jit.storeDouble(valueFPR, MacroAssembler::Address(bufferGPR, sizeof(double) * elementIndex));
             value.use();

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (230286 => 230287)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-05 00:22:09 UTC (rev 230286)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-05 00:30:48 UTC (rev 230287)
@@ -4449,11 +4449,11 @@
                 if (m_node->arrayMode().type() != Array::Double) {
                     value = lowJSValue(element, ManualOperandSpeculation);
                     if (m_node->arrayMode().type() == Array::Int32)
-                        RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecInt32Only));
+                        DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecInt32Only));
                     storeType = Output::Store64;
                 } else {
                     value = lowDouble(element);
-                    RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecDoubleReal));
+                    DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecDoubleReal));
                     storeType = Output::StoreDouble;
                 }
 
@@ -4529,11 +4529,11 @@
                 if (m_node->arrayMode().type() != Array::Double) {
                     value = lowJSValue(element, ManualOperandSpeculation);
                     if (m_node->arrayMode().type() == Array::Int32)
-                        RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecInt32Only));
+                        DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecInt32Only));
                     storeType = Output::Store64;
                 } else {
                     value = lowDouble(element);
-                    RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecDoubleReal));
+                    DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecDoubleReal));
                     storeType = Output::StoreDouble;
                 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to