<!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>[214927] 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/214927">214927</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2017-04-04 20:50:07 -0700 (Tue, 04 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>On ARM64, DFG::SpeculativeJIT::compileArithMod() failed to ensure result is of DataFormatInt32.
https://bugs.webkit.org/show_bug.cgi?id=170473
&lt;rdar://problem/29912391&gt;

Reviewed by Saam Barati.

JSTests:

* stress/regress-170473.js: Added.

Source/JavaScriptCore:

In Unchecked mode, when DFG::SpeculativeJIT::compileArithMod() detects that the
divisor is 0, we want it to return 0.  The result is expected to be of
DataFormatIn32.

The ARM implementation just returns the value in the divisor register.  However,
the divisor in this case can be of DataFormatJSInt32.  On ARM64, returning the
divisor register yields the wrong result format because the same register also
holds the upper 32-bit of the JSValue encoding.  The fix is to return an
immediate 0 instead.

Also turned on the assertion in jitAssertIsInt32 for ARM64.  This assertion being
disabled may have contributed to this bug going unnoticed all this time.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithMod):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::jitAssertIsInt32):</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="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelperscpp">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressregress170473js">trunk/JSTests/stress/regress-170473.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (214926 => 214927)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-04-05 03:43:44 UTC (rev 214926)
+++ trunk/JSTests/ChangeLog        2017-04-05 03:50:07 UTC (rev 214927)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2017-04-04  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        On ARM64, DFG::SpeculativeJIT::compileArithMod() failed to ensure result is of DataFormatInt32.
+        https://bugs.webkit.org/show_bug.cgi?id=170473
+        &lt;rdar://problem/29912391&gt;
+
+        Reviewed by Saam Barati.
+
+        * stress/regress-170473.js: Added.
+
</ins><span class="cx"> 2017-04-03  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix incorrect capacity delta calculation reported in SparseArrayValueMap::add().
</span></span></pre></div>
<a id="trunkJSTestsstressregress170473js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/regress-170473.js (0 => 214927)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/regress-170473.js                                (rev 0)
+++ trunk/JSTests/stress/regress-170473.js        2017-04-05 03:50:07 UTC (rev 214927)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+var heap = new SharedArrayBuffer(4096);
+var Uint8ArrayView = new Uint8Array(heap);
+
+function test(k)  {
+    var d = new Float32Array();
+    var c = d | 0;
+    var b = 1 % c;
+    var a = b | 0;
+    Uint8ArrayView[a] = 0;
+}
+noInline(test);
+
+for (var k = 0; k &lt; 200; ++k)
+    test(k);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (214926 => 214927)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-04-05 03:43:44 UTC (rev 214926)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-04-05 03:50:07 UTC (rev 214927)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-04-04  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        On ARM64, DFG::SpeculativeJIT::compileArithMod() failed to ensure result is of DataFormatInt32.
+        https://bugs.webkit.org/show_bug.cgi?id=170473
+        &lt;rdar://problem/29912391&gt;
+
+        Reviewed by Saam Barati.
+
+        In Unchecked mode, when DFG::SpeculativeJIT::compileArithMod() detects that the
+        divisor is 0, we want it to return 0.  The result is expected to be of
+        DataFormatIn32.
+
+        The ARM implementation just returns the value in the divisor register.  However,
+        the divisor in this case can be of DataFormatJSInt32.  On ARM64, returning the
+        divisor register yields the wrong result format because the same register also
+        holds the upper 32-bit of the JSValue encoding.  The fix is to return an
+        immediate 0 instead.
+
+        Also turned on the assertion in jitAssertIsInt32 for ARM64.  This assertion being
+        disabled may have contributed to this bug going unnoticed all this time.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::jitAssertIsInt32):
+
</ins><span class="cx"> 2017-04-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Air::eliminateDeadCode should not repeatedly process the same live instructions
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (214926 => 214927)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-04-05 03:43:44 UTC (rev 214926)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-04-05 03:50:07 UTC (rev 214927)
</span><span class="lines">@@ -5101,7 +5101,10 @@
</span><span class="cx">             speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, divisorGPR));
</span><span class="cx">         else {
</span><span class="cx">             JITCompiler::Jump denominatorNotZero = m_jit.branchTest32(JITCompiler::NonZero, divisorGPR);
</span><del>-            m_jit.move(divisorGPR, quotientThenRemainderGPR);
</del><ins>+            // We know that the low 32-bit of divisorGPR is 0, but we don't know if the high bits are.
+            // So, use TrustedImm32(0) on ARM instead because done expects the result to be in DataFormatInt32.
+            // Using an immediate 0 doesn't cost anything extra on ARM.
+            m_jit.move(TrustedImm32(0), quotientThenRemainderGPR);
</ins><span class="cx">             done.append(m_jit.jump());
</span><span class="cx">             denominatorNotZero.link(&amp;m_jit);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp (214926 => 214927)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp        2017-04-05 03:43:44 UTC (rev 214926)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp        2017-04-05 03:50:07 UTC (rev 214927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 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">@@ -192,7 +192,7 @@
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> void AssemblyHelpers::jitAssertIsInt32(GPRReg gpr)
</span><span class="cx"> {
</span><del>-#if CPU(X86_64)
</del><ins>+#if CPU(X86_64) || CPU(ARM64)
</ins><span class="cx">     Jump checkInt32 = branch64(BelowOrEqual, gpr, TrustedImm64(static_cast&lt;uintptr_t&gt;(0xFFFFFFFFu)));
</span><span class="cx">     abortWithReason(AHIsNotInt32);
</span><span class="cx">     checkInt32.link(this);
</span></span></pre>
</div>
</div>

</body>
</html>