Title: [230302] branches/safari-605-branch
Revision
230302
Author
jmarc...@apple.com
Date
2018-04-05 10:05:12 -0700 (Thu, 05 Apr 2018)

Log Message

Cherry-pick r230287. rdar://problem/39208588

    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):

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-605-branch/JSTests/ChangeLog (230301 => 230302)


--- branches/safari-605-branch/JSTests/ChangeLog	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/JSTests/ChangeLog	2018-04-05 17:05:12 UTC (rev 230302)
@@ -1,3 +1,63 @@
+2018-04-05  Jason Marcell  <jmarc...@apple.com>
+
+        Cherry-pick r230287. rdar://problem/39208588
+
+    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):
+    
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230287 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2018-04-04  Filip Pizlo  <fpi...@apple.com>
+
+            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  Jason Marcell  <jmarc...@apple.com>
 
         Cherry-pick r229987. rdar://problem/39155464

Added: branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js (0 => 230302)


--- branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js	                        (rev 0)
+++ branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js	2018-04-05 17:05:12 UTC (rev 230302)
@@ -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: branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array.js (0 => 230302)


--- branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array.js	                        (rev 0)
+++ branches/safari-605-branch/JSTests/stress/array-push-nan-to-double-array.js	2018-04-05 17:05:12 UTC (rev 230302)
@@ -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: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-04-05 17:05:12 UTC (rev 230302)
@@ -1,3 +1,78 @@
+2018-04-05  Jason Marcell  <jmarc...@apple.com>
+
+        Cherry-pick r230287. rdar://problem/39208588
+
+    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):
+    
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230287 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2018-04-04  Filip Pizlo  <fpi...@apple.com>
+
+            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-03  Jason Marcell  <jmarc...@apple.com>
 
         Cherry-pick r229987. rdar://problem/39155464

Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2018-04-05 17:05:12 UTC (rev 230302)
@@ -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: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGClobberize.h (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGClobberize.h	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGClobberize.h	2018-04-05 17:05:12 UTC (rev 230302)
@@ -811,7 +811,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);
@@ -930,7 +931,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: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.cpp (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-04-05 17:05:12 UTC (rev 230302)
@@ -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: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.h (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-04-05 17:05:12 UTC (rev 230302)
@@ -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: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-04-05 17:05:12 UTC (rev 230302)
@@ -7983,7 +7983,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()));
@@ -8028,7 +8028,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();
@@ -8055,7 +8055,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()));
@@ -8099,7 +8099,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: branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (230301 => 230302)


--- branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-05 17:05:08 UTC (rev 230301)
+++ branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-05 17:05:12 UTC (rev 230302)
@@ -4345,11 +4345,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;
                 }
 
@@ -4425,11 +4425,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
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to