<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[242954] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/242954">242954</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2019-03-14 12:27:28 -0700 (Thu, 14 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fixup uses KnownInt32 incorrectly in some nodes
https://bugs.webkit.org/show_bug.cgi?id=195279
<rdar://problem/47915654>

Reviewed by Yusuke Suzuki.

JSTests:

* stress/known-int32-cant-be-used-across-bytecode-boundary.js: Added.
(foo):

Source/JavaScriptCore:

Fixup was sometimes using KnownInt32 edges when it knew some
incoming value is an Int32 based on what the bytecode would return.
However, because bytecode may result in Int32 for some node does
not mean we'll pick Int32 as the value format for that local. For example,
we may choose for a value to be represented as a double. This patch
corrects such uses of KnownInt32.

* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArrayPush):
(JSC::DFG::SpeculativeJIT::compileGetDirectPname):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArrayPush):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressknownint32cantbeusedacrossbytecodeboundaryjs">trunk/JSTests/stress/known-int32-cant-be-used-across-bytecode-boundary.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog  2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/JSTests/ChangeLog     2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2019-03-14  Saam barati  <sbarati@apple.com>
+
+        Fixup uses KnownInt32 incorrectly in some nodes
+        https://bugs.webkit.org/show_bug.cgi?id=195279
+        <rdar://problem/47915654>
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/known-int32-cant-be-used-across-bytecode-boundary.js: Added.
+        (foo):
+
</ins><span class="cx"> 2019-03-14  Keith Miller  <keith_miller@apple.com>
</span><span class="cx"> 
</span><span class="cx">         DFG liveness can't skip tail caller inline frames
</span></span></pre></div>
<a id="trunkJSTestsstressknownint32cantbeusedacrossbytecodeboundaryjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/known-int32-cant-be-used-across-bytecode-boundary.js (0 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/known-int32-cant-be-used-across-bytecode-boundary.js                                (rev 0)
+++ trunk/JSTests/stress/known-int32-cant-be-used-across-bytecode-boundary.js   2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+//@ runDefault("--useConcurrentJIT=0", "--useMaximalFlushInsertionPhase=1")
+
+function foo() {
+    var x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13;
+    var copy = [];
+    var value = this[1];
+
+    for (var p in this)
+        copy[copy.length] = value;
+
+    for (var i = 0; i < 1000; i++) {
+        for (var j = 0; j < 1; j++) {
+        }
+        Math.min(0 ** []);
+    }
+};
+
+noInline(foo);
+
+let array0 = new Array(3).fill(1);
+delete array0[0];
+
+([])[1000] = 0xFFFFF;
+
+for (var i = 0; i < 100; i++)
+    foo.call(array0);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2019-03-14  Saam barati  <sbarati@apple.com>
+
+        Fixup uses KnownInt32 incorrectly in some nodes
+        https://bugs.webkit.org/show_bug.cgi?id=195279
+        <rdar://problem/47915654>
+
+        Reviewed by Yusuke Suzuki.
+
+        Fixup was sometimes using KnownInt32 edges when it knew some
+        incoming value is an Int32 based on what the bytecode would return.
+        However, because bytecode may result in Int32 for some node does
+        not mean we'll pick Int32 as the value format for that local. For example,
+        we may choose for a value to be represented as a double. This patch
+        corrects such uses of KnownInt32.
+
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArrayPush):
+        (JSC::DFG::SpeculativeJIT::compileGetDirectPname):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileArrayPush):
+
</ins><span class="cx"> 2019-03-14  Keith Miller  <keith_miller@apple.com>
</span><span class="cx"> 
</span><span class="cx">         DFG liveness can't skip tail caller inline frames
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp 2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp    2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -661,6 +661,12 @@
</span><span class="cx">                     if (!m_candidates.contains(node))
</span><span class="cx">                         break;
</span><span class="cx"> 
</span><ins>+                    ASSERT(node->origin.exitOK);
+                    ASSERT(node->child1().useKind() == Int32Use);
+                    insertionSet.insertNode(
+                        nodeIndex, SpecNone, Check, node->origin,
+                        node->child1()); 
+
</ins><span class="cx">                     node->setOpAndDefaultFlags(PhantomCreateRest);
</span><span class="cx">                     // We don't need this parameter for OSR exit, we can find out all the information
</span><span class="cx">                     // we need via the static parameter count and the dynamic argument count.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp   2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1149,12 +1149,10 @@
</span><span class="cx">                 Edge& element = m_graph.varArgChild(node, i + elementOffset);
</span><span class="cx">                 switch (node->arrayMode().type()) {
</span><span class="cx">                 case Array::Int32:
</span><del>-                    insertCheck<Int32Use>(element.node());
-                    fixEdge<KnownInt32Use>(element);
</del><ins>+                    fixEdge<Int32Use>(element);
</ins><span class="cx">                     break;
</span><span class="cx">                 case Array::Double:
</span><del>-                    insertCheck<DoubleRepRealUse>(element.node());
-                    fixEdge<DoubleRepUse>(element);
</del><ins>+                    fixEdge<DoubleRepRealUse>(element);
</ins><span class="cx">                     break;
</span><span class="cx">                 case Array::Contiguous:
</span><span class="cx">                 case Array::ArrayStorage:
</span><span class="lines">@@ -1163,7 +1161,6 @@
</span><span class="cx">                 default:
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                ASSERT(shouldNotHaveTypeCheck(element.useKind()));
</del><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1868,7 +1865,7 @@
</span><span class="cx">             
</span><span class="cx">             blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
</span><span class="cx">             fixEdge<CellUse>(m_graph.varArgChild(node, 0));
</span><del>-            fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 1));
</del><ins>+            fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case GetDirectPname: {
</span><span class="lines">@@ -1878,7 +1875,7 @@
</span><span class="cx">             Edge& enumerator = m_graph.varArgChild(node, 3);
</span><span class="cx">             fixEdge<CellUse>(base);
</span><span class="cx">             fixEdge<KnownCellUse>(property);
</span><del>-            fixEdge<KnownInt32Use>(index);
</del><ins>+            fixEdge<Int32Use>(index);
</ins><span class="cx">             fixEdge<KnownCellUse>(enumerator);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1889,16 +1886,16 @@
</span><span class="cx">         }
</span><span class="cx">         case GetEnumeratorStructurePname: {
</span><span class="cx">             fixEdge<KnownCellUse>(node->child1());
</span><del>-            fixEdge<KnownInt32Use>(node->child2());
</del><ins>+            fixEdge<Int32Use>(node->child2());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case GetEnumeratorGenericPname: {
</span><span class="cx">             fixEdge<KnownCellUse>(node->child1());
</span><del>-            fixEdge<KnownInt32Use>(node->child2());
</del><ins>+            fixEdge<Int32Use>(node->child2());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case ToIndexString: {
</span><del>-            fixEdge<KnownInt32Use>(node->child1());
</del><ins>+            fixEdge<Int32Use>(node->child1());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case ProfileType: {
</span><span class="lines">@@ -1990,7 +1987,7 @@
</span><span class="cx"> 
</span><span class="cx">         case CreateRest: {
</span><span class="cx">             watchHavingABadTime(node);
</span><del>-            fixEdge<KnownInt32Use>(node->child1());
</del><ins>+            fixEdge<Int32Use>(node->child1());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2154,7 +2151,7 @@
</span><span class="cx">             else
</span><span class="cx">                 fixEdge<UntypedUse>(propertyEdge);
</span><span class="cx">             fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
</span><del>-            fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 3));
</del><ins>+            fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2204,7 +2201,7 @@
</span><span class="cx">                 fixEdge<UntypedUse>(propertyEdge);
</span><span class="cx">             fixEdge<CellUse>(m_graph.varArgChild(node, 2));
</span><span class="cx">             fixEdge<CellUse>(m_graph.varArgChild(node, 3));
</span><del>-            fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 4));
</del><ins>+            fixEdge<Int32Use>(m_graph.varArgChild(node, 4));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp    2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp       2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -8570,12 +8570,13 @@
</span><span class="cx">     case Array::Contiguous: {
</span><span class="cx">         if (elementCount == 1) {
</span><span class="cx">             Edge& element = m_jit.graph().varArgChild(node, elementOffset);
</span><ins>+            if (node->arrayMode().type() == Array::Int32) {
+                ASSERT(element.useKind() == Int32Use);
+                speculateInt32(element);
+            }
</ins><span class="cx">             JSValueOperand value(this, element, ManualOperandSpeculation);
</span><span class="cx">             JSValueRegs valueRegs = value.jsValueRegs();
</span><span class="cx"> 
</span><del>-            if (node->arrayMode().type() == Array::Int32)
-                DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecInt32Only));
-
</del><span class="cx">             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
</span><span class="cx">             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
</span><span class="cx">             m_jit.storeValue(valueRegs, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
</span><span class="lines">@@ -8590,6 +8591,14 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (node->arrayMode().type() == Array::Int32) {
+            for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
+                Edge element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
+                ASSERT(element.useKind() == Int32Use);
+                speculateInt32(element);
+            }
+        }
+
</ins><span class="cx">         GPRTemporary buffer(this);
</span><span class="cx">         GPRReg bufferGPR = buffer.gpr();
</span><span class="cx"> 
</span><span class="lines">@@ -8615,12 +8624,9 @@
</span><span class="cx">         storageDone.link(&m_jit);
</span><span class="cx">         for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
</span><span class="cx">             Edge& element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
</span><del>-            JSValueOperand value(this, element, ManualOperandSpeculation);
</del><ins>+            JSValueOperand value(this, element, ManualOperandSpeculation); // We did type checks above.
</ins><span class="cx">             JSValueRegs valueRegs = value.jsValueRegs();
</span><span class="cx"> 
</span><del>-            if (node->arrayMode().type() == Array::Int32)
-                DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecInt32Only));
-
</del><span class="cx">             m_jit.storeValue(valueRegs, MacroAssembler::Address(bufferGPR, sizeof(EncodedJSValue) * elementIndex));
</span><span class="cx">             value.use();
</span><span class="cx">         }
</span><span class="lines">@@ -8643,11 +8649,10 @@
</span><span class="cx">     case Array::Double: {
</span><span class="cx">         if (elementCount == 1) {
</span><span class="cx">             Edge& element = m_jit.graph().varArgChild(node, elementOffset);
</span><ins>+            speculate(node, element);
</ins><span class="cx">             SpeculateDoubleOperand value(this, element);
</span><span class="cx">             FPRReg valueFPR = value.fpr();
</span><span class="cx"> 
</span><del>-            DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecDoubleReal));
-
</del><span class="cx">             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
</span><span class="cx">             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
</span><span class="cx">             m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
</span><span class="lines">@@ -8662,6 +8667,12 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
+            Edge element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
+            ASSERT(element.useKind() == DoubleRepRealUse);
+            speculate(node, element);
+        }
+
</ins><span class="cx">         GPRTemporary buffer(this);
</span><span class="cx">         GPRReg bufferGPR = buffer.gpr();
</span><span class="cx"> 
</span><span class="lines">@@ -8690,8 +8701,6 @@
</span><span class="cx">             SpeculateDoubleOperand value(this, element);
</span><span class="cx">             FPRReg valueFPR = value.fpr();
</span><span class="cx"> 
</span><del>-            DFG_ASSERT(m_jit.graph(), node, !needsTypeCheck(element, SpecDoubleReal));
-
</del><span class="cx">             m_jit.storeDouble(valueFPR, MacroAssembler::Address(bufferGPR, sizeof(double) * elementIndex));
</span><span class="cx">             value.use();
</span><span class="cx">         }
</span><span class="lines">@@ -13086,6 +13095,7 @@
</span><span class="cx"> {
</span><span class="cx">     Edge& baseEdge = m_jit.graph().varArgChild(node, 0);
</span><span class="cx">     Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
</span><ins>+    Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
</ins><span class="cx"> 
</span><span class="cx">     SpeculateCellOperand base(this, baseEdge);
</span><span class="cx">     SpeculateCellOperand property(this, propertyEdge);
</span><span class="lines">@@ -13094,6 +13104,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86)
</span><span class="cx">     // Not enough registers on X86 for this code, so always use the slow path.
</span><ins>+    speculate(node, indexEdge);
</ins><span class="cx">     flushRegisters();
</span><span class="cx">     JSValueRegsFlushedCallResult result(this);
</span><span class="cx">     JSValueRegs resultRegs = result.regs();
</span><span class="lines">@@ -13101,7 +13112,6 @@
</span><span class="cx">     m_jit.exceptionCheck();
</span><span class="cx">     jsValueResult(resultRegs, node);
</span><span class="cx"> #else
</span><del>-    Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
</del><span class="cx">     Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
</span><span class="cx">     SpeculateStrictInt32Operand index(this, indexEdge);
</span><span class="cx">     SpeculateCellOperand enumerator(this, enumeratorEdge);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (242953 => 242954)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp      2019-03-14 19:22:06 UTC (rev 242953)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2019-03-14 19:27:28 UTC (rev 242954)
</span><span class="lines">@@ -4674,14 +4674,12 @@
</span><span class="cx">                 Output::StoreType storeType;
</span><span class="cx">                 
</span><span class="cx">                 Edge& element = m_graph.varArgChild(m_node, elementOffset);
</span><ins>+                speculate(element);
</ins><span class="cx">                 if (m_node->arrayMode().type() != Array::Double) {
</span><span class="cx">                     value = lowJSValue(element, ManualOperandSpeculation);
</span><del>-                    if (m_node->arrayMode().type() == Array::Int32)
-                        DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecInt32Only));
</del><span class="cx">                     storeType = Output::Store64;
</span><span class="cx">                 } else {
</span><span class="cx">                     value = lowDouble(element);
</span><del>-                    DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecDoubleReal));
</del><span class="cx">                     storeType = Output::StoreDouble;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="lines">@@ -4720,6 +4718,11 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
+                Edge element = m_graph.varArgChild(m_node, elementIndex + elementOffset);
+                speculate(element);
+            }
+
</ins><span class="cx">             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
</span><span class="cx">             LValue newLength = m_out.add(prevLength, m_out.constInt32(elementCount));
</span><span class="cx"> 
</span><span class="lines">@@ -4756,12 +4759,9 @@
</span><span class="cx">                 Output::StoreType storeType;
</span><span class="cx">                 if (m_node->arrayMode().type() != Array::Double) {
</span><span class="cx">                     value = lowJSValue(element, ManualOperandSpeculation);
</span><del>-                    if (m_node->arrayMode().type() == Array::Int32)
-                        DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecInt32Only));
</del><span class="cx">                     storeType = Output::Store64;
</span><span class="cx">                 } else {
</span><span class="cx">                     value = lowDouble(element);
</span><del>-                    DFG_ASSERT(m_graph, m_node, !m_interpreter.needsTypeCheck(element, SpecDoubleReal));
</del><span class="cx">                     storeType = Output::StoreDouble;
</span><span class="cx">                 }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>