<!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>[214774] releases/WebKitGTK/webkit-2.16</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/214774">214774</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2017-04-03 05:33:21 -0700 (Mon, 03 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/214219">r214219</a> - [JSC] Optimize Number.prototype.toString on Int32 / Int52 / Double
https://bugs.webkit.org/show_bug.cgi?id=167454

Reviewed by Saam Barati.

JSTests:

* stress/number-to-string-abstract-operation.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):
* stress/number-to-string-radix.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):
* stress/number-to-string.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):

Source/JavaScriptCore:

This patch improves Number.toString(radix) performance
by introducing NumberToStringWithRadix DFG node. It directly
calls the operation and it always returns String.

                                               baseline                  patched

    stanford-crypto-sha256-iterative        45.130+-0.928             44.032+-1.184           might be 1.0250x faster</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit216JSTestsChangeLog">releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGByteCodeParsercpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGClobberizeh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGDoesGCcpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGFixupPhasecpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGNodeTypeh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGOperationscpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGOperationsh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSafeToExecuteh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJITcpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJITh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreftlFTLCapabilitiescpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreftlFTLLowerDFGToB3cpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCorejitCCallHelpersh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/CCallHelpers.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCorejitJITOperationsh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeIntrinsich">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeNumberPrototypecpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeNumberPrototypeh">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.h</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeStringPrototypecpp">releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit216JSTestsstressnumbertostringabstractoperationjs">releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-abstract-operation.js</a></li>
<li><a href="#releasesWebKitGTKwebkit216JSTestsstressnumbertostringradixjs">releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-radix.js</a></li>
<li><a href="#releasesWebKitGTKwebkit216JSTestsstressnumbertostringjs">releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit216JSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-03-21  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [JSC] Optimize Number.prototype.toString on Int32 / Int52 / Double
+        https://bugs.webkit.org/show_bug.cgi?id=167454
+
+        Reviewed by Saam Barati.
+
+        * stress/number-to-string-abstract-operation.js: Added.
+        (shouldBe):
+        (int32ToString):
+        (shouldBe.int32ToString.new.Number.int52ToString):
+        (shouldBe.int32ToString.new.Number):
+        (shouldBe.doubleToString):
+        * stress/number-to-string-radix.js: Added.
+        (shouldBe):
+        (int32ToString):
+        (shouldBe.int32ToString.new.Number.int52ToString):
+        (shouldBe.int32ToString.new.Number):
+        (shouldBe.doubleToString):
+        * stress/number-to-string.js: Added.
+        (shouldBe):
+        (int32ToString):
+        (shouldBe.int32ToString.new.Number.int52ToString):
+        (shouldBe.int32ToString.new.Number):
+        (shouldBe.doubleToString):
+
</ins><span class="cx"> 2017-02-23  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Intrinsicify parseInt
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216JSTestsstressnumbertostringabstractoperationjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-abstract-operation.js (0 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-abstract-operation.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-abstract-operation.js        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error(`bad value: expected:(${expected}),actual:(${actual})`);
+}
+
+function expected(num, radix)
+{
+    let characters = &quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;;
+    let result = &quot;&quot;;
+    let negative = false;
+    if (num &lt; 0) {
+        negative = true;
+        num = -num;
+    }
+
+    do {
+        const index = num % radix;
+        result = characters[index] + result;
+        num = (num - index) / radix;
+    } while (num);
+
+    if (negative)
+        return '-' + result;
+    return result;
+}
+
+{
+    function int32ToString(num)
+    {
+        return `${num}`;
+    }
+    noInline(int32ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int32ToString(i), expected(i, 10));
+        shouldBe(int32ToString(-i), expected(-i, 10));
+    }
+
+    shouldBe(int32ToString(0xffffffffff), expected(0xffffffffff, 10));
+    shouldBe(int32ToString(0.1), `0.1`);
+    shouldBe(int32ToString(-0.1), `-0.1`);
+    shouldBe(int32ToString(new Number(0xff)), `255`);
+}
+
+{
+    function int52ToString(num)
+    {
+        return `${fiatInt52(num)}`;
+    }
+    noInline(int52ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int52ToString(0xffffffff + i), expected(0xffffffff + i, 10));
+        shouldBe(int52ToString(-(0xffffffff + i)), expected(-(0xffffffff + i), 10));
+    }
+
+    shouldBe(int52ToString(0xff), `255`);
+    shouldBe(int52ToString(0.1), `0.1`);
+    shouldBe(int52ToString(-0.1), `-0.1`);
+    shouldBe(int52ToString(new Number(0xff)), `255`);
+}
+
+{
+    function doubleToString(num)
+    {
+        return `${num}`;
+    }
+    noInline(doubleToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(doubleToString(1.01), `1.01`);
+        shouldBe(doubleToString(-1.01), `-1.01`);
+    }
+
+    shouldBe(doubleToString(0xff), `255`);
+    shouldBe(doubleToString(0.1), `0.1`);
+    shouldBe(doubleToString(-0.1), `-0.1`);
+    shouldBe(doubleToString(new Number(0xff)), `255`);
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit216JSTestsstressnumbertostringradixjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-radix.js (0 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-radix.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string-radix.js        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error(`bad value: expected:(${expected}),actual:(${actual})`);
+}
+
+function expected(num, radix)
+{
+    let characters = &quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;;
+    let result = &quot;&quot;;
+    let negative = false;
+    if (num &lt; 0) {
+        negative = true;
+        num = -num;
+    }
+
+    do {
+        const index = num % radix;
+        result = characters[index] + result;
+        num = (num - index) / radix;
+    } while (num);
+
+    if (negative)
+        return '-' + result;
+    return result;
+}
+
+{
+    function int32ToString(num, radix)
+    {
+        return num.toString(radix);
+    }
+    noInline(int32ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int32ToString(i, 16), expected(i, 16));
+        shouldBe(int32ToString(-i, 16), expected(-i, 16));
+    }
+
+    shouldBe(int32ToString(0xffffffffff, 16), expected(0xffffffffff, 16));
+    shouldBe(int32ToString(0.1, 16), `0.1999999999999a`);
+    shouldBe(int32ToString(-0.1, 16), `-0.1999999999999a`);
+    shouldBe(int32ToString(new Number(0xff), 16), `ff`);
+}
+
+{
+    function int52ToString(num, radix)
+    {
+        return fiatInt52(num).toString(radix);
+    }
+    noInline(int52ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int52ToString(0xffffffff + i, 16), expected(0xffffffff + i, 16));
+        shouldBe(int52ToString(-(0xffffffff + i), 16), expected(-(0xffffffff + i), 16));
+    }
+
+    shouldBe(int52ToString(0xff, 16), `ff`);
+    shouldBe(int52ToString(0.1, 16), `0.1999999999999a`);
+    shouldBe(int52ToString(-0.1, 16), `-0.1999999999999a`);
+    shouldBe(int52ToString(new Number(0xff), 16), `ff`);
+}
+
+{
+    function doubleToString(num, radix)
+    {
+        return num.toString(radix);
+    }
+    noInline(doubleToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(doubleToString(1.01, 16), `1.028f5c28f5c29`);
+        shouldBe(doubleToString(-1.01, 16), `-1.028f5c28f5c29`);
+    }
+
+    shouldBe(doubleToString(0xff, 16), `ff`);
+    shouldBe(doubleToString(0.1, 16), `0.1999999999999a`);
+    shouldBe(doubleToString(-0.1, 16), `-0.1999999999999a`);
+    shouldBe(doubleToString(new Number(0xff), 16), `ff`);
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit216JSTestsstressnumbertostringjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string.js (0 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/number-to-string.js        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error(`bad value: expected:(${expected}),actual:(${actual})`);
+}
+
+function expected(num, radix)
+{
+    let characters = &quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;;
+    let result = &quot;&quot;;
+    let negative = false;
+    if (num &lt; 0) {
+        negative = true;
+        num = -num;
+    }
+
+    do {
+        const index = num % radix;
+        result = characters[index] + result;
+        num = (num - index) / radix;
+    } while (num);
+
+    if (negative)
+        return '-' + result;
+    return result;
+}
+
+{
+    function int32ToString(num)
+    {
+        return num.toString(16);
+    }
+    noInline(int32ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int32ToString(i), expected(i, 16));
+        shouldBe(int32ToString(-i), expected(-i, 16));
+    }
+
+    shouldBe(int32ToString(0xffffffffff), expected(0xffffffffff, 16));
+    shouldBe(int32ToString(0.1), `0.1999999999999a`);
+    shouldBe(int32ToString(-0.1), `-0.1999999999999a`);
+    shouldBe(int32ToString(new Number(0xff)), `ff`);
+}
+
+{
+    function int52ToString(num)
+    {
+        return fiatInt52(num).toString(16);
+    }
+    noInline(int52ToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(int52ToString(0xffffffff + i), expected(0xffffffff + i, 16));
+        shouldBe(int52ToString(-(0xffffffff + i)), expected(-(0xffffffff + i), 16));
+    }
+
+    shouldBe(int52ToString(0xff), `ff`);
+    shouldBe(int52ToString(0.1), `0.1999999999999a`);
+    shouldBe(int52ToString(-0.1), `-0.1999999999999a`);
+    shouldBe(int52ToString(new Number(0xff)), `ff`);
+}
+
+{
+    function doubleToString(num)
+    {
+        return num.toString(16);
+    }
+    noInline(doubleToString);
+
+    for (var i = 0; i &lt; 1e3; ++i) {
+        shouldBe(doubleToString(1.01), `1.028f5c28f5c29`);
+        shouldBe(doubleToString(-1.01), `-1.028f5c28f5c29`);
+    }
+
+    shouldBe(doubleToString(0xff), `ff`);
+    shouldBe(doubleToString(0.1), `0.1999999999999a`);
+    shouldBe(doubleToString(-0.1), `-0.1999999999999a`);
+    shouldBe(doubleToString(new Number(0xff)), `ff`);
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ChangeLog (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ChangeLog        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ChangeLog        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-03-21  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [JSC] Optimize Number.prototype.toString on Int32 / Int52 / Double
+        https://bugs.webkit.org/show_bug.cgi?id=167454
+
+        Reviewed by Saam Barati.
+
+        This patch improves Number.toString(radix) performance
+        by introducing NumberToStringWithRadix DFG node. It directly
+        calls the operation and it always returns String.
+
+                                                       baseline                  patched
+
+            stanford-crypto-sha256-iterative        45.130+-0.928             44.032+-1.184           might be 1.0250x faster
+
</ins><span class="cx"> 2017-02-24  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed. Remove inaccurate copy-paste comment from r212939.
</span><span class="lines">@@ -27,7 +42,60 @@
</span><span class="cx">         is a proven string. The DFG might be able to remove type checks in this
</span><span class="cx">         case. We also set up CSE rules for parseInt(someString, someIntRadix)
</span><span class="cx">         because it's a &quot;pure&quot; operation (modulo resolving a rope).
</span><ins>+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructor):
+        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnNumber):
+        (JSC::DFG::SpeculativeJIT::compileNumberToStringWithRadix):
+        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileToStringOrCallStringConstructor):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNumberToStringWithRadix):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JITOperations.h:
+        * runtime/Intrinsic.h:
+        * runtime/NumberPrototype.cpp:
+        (JSC::int52ToStringWithRadix):
+        (JSC::int32ToStringInternal):
+        (JSC::numberToStringInternal):
+        (JSC::int32ToString):
+        (JSC::int52ToString):
+        (JSC::numberToString):
+        (JSC::numberProtoFuncToString):
+        (JSC::integerValueToString): Deleted.
+        * runtime/NumberPrototype.h:
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">         This looks to be a 4% Octane/Box2D progression.
</span><span class="cx"> 
</span><span class="cx">         * dfg/DFGAbstractInterpreterInlines.h:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1858,6 +1858,9 @@
</span><span class="cx">                 m_graph.registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;stringObjectStructure()));
</span><span class="cx">             break;
</span><span class="cx">         case StringOrStringObjectUse:
</span><ins>+        case Int32Use:
+        case Int52RepUse:
+        case DoubleRepUse:
</ins><span class="cx">         case NotCellUse:
</span><span class="cx">             break;
</span><span class="cx">         case CellUse:
</span><span class="lines">@@ -1871,6 +1874,11 @@
</span><span class="cx">         forNode(node).set(m_graph, m_vm.stringStructure.get());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case NumberToStringWithRadix:
+        clobberWorld(node-&gt;origin.semantic, clobberLimit);
+        forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
+        break;
</ins><span class="cx">         
</span><span class="cx">     case NewStringObject: {
</span><span class="cx">         ASSERT(node-&gt;structure()-&gt;classInfo() == StringObject::info());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -2711,7 +2711,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case ToLowerCaseIntrinsic: {
</del><ins>+    case StringPrototypeToLowerCaseIntrinsic: {
</ins><span class="cx">         if (argumentCountIncludingThis != 1)
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><span class="lines">@@ -2725,6 +2725,26 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case NumberPrototypeToStringIntrinsic: {
+        if (argumentCountIncludingThis != 1 &amp;&amp; argumentCountIncludingThis != 2)
+            return false;
+
+        if (m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadType))
+            return false;
+
+        insertChecks();
+        Node* thisNumber = get(virtualRegisterForArgument(0, registerOffset));
+        if (argumentCountIncludingThis == 1) {
+            Node* result = addToGraph(ToString, thisNumber);
+            set(VirtualRegister(resultOperand), result);
+        } else {
+            Node* radix = get(virtualRegisterForArgument(1, registerOffset));
+            Node* result = addToGraph(NumberToStringWithRadix, thisNumber, radix);
+            set(VirtualRegister(resultOperand), result);
+        }
+        return true;
+    }
+
</ins><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="cx">     }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGClobberize.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1401,6 +1401,9 @@
</span><span class="cx">             write(Heap);
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        case Int32Use:
+        case Int52RepUse:
+        case DoubleRepUse:
</ins><span class="cx">         case NotCellUse:
</span><span class="cx">             def(PureValue(node));
</span><span class="cx">             return;
</span><span class="lines">@@ -1449,6 +1452,11 @@
</span><span class="cx">     case ToLowerCase:
</span><span class="cx">         def(PureValue(node));
</span><span class="cx">         return;
</span><ins>+
+    case NumberToStringWithRadix:
+        read(World);
+        write(Heap);
+        return;
</ins><span class="cx">         
</span><span class="cx">     case LastNodeType:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -178,6 +178,7 @@
</span><span class="cx">     case ToNumber:
</span><span class="cx">     case ToString:
</span><span class="cx">     case CallStringConstructor:
</span><ins>+    case NumberToStringWithRadix:
</ins><span class="cx">     case In:
</span><span class="cx">     case HasOwnProperty:
</span><span class="cx">     case Jump:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1753,6 +1753,17 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case NumberToStringWithRadix: {
+            if (node-&gt;child1()-&gt;shouldSpeculateInt32())
+                fixEdge&lt;Int32Use&gt;(node-&gt;child1());
+            else if (enableInt52() &amp;&amp; node-&gt;child1()-&gt;shouldSpeculateAnyInt())
+                fixEdge&lt;Int52RepUse&gt;(node-&gt;child1());
+            else
+                fixEdge&lt;DoubleRepUse&gt;(node-&gt;child1());
+            fixEdge&lt;Int32Use&gt;(node-&gt;child2());
+            break;
+        }
+
</ins><span class="cx">         case DefineAccessorProperty: {
</span><span class="cx">             fixEdge&lt;CellUse&gt;(m_graph.varArgChild(node, 0));
</span><span class="cx">             Edge&amp; propertyEdge = m_graph.varArgChild(node, 1);
</span><span class="lines">@@ -2229,6 +2240,24 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (node-&gt;child1()-&gt;shouldSpeculateInt32()) {
+            fixEdge&lt;Int32Use&gt;(node-&gt;child1());
+            node-&gt;clearFlags(NodeMustGenerate);
+            return;
+        }
+
+        if (enableInt52() &amp;&amp; node-&gt;child1()-&gt;shouldSpeculateAnyInt()) {
+            fixEdge&lt;Int52RepUse&gt;(node-&gt;child1());
+            node-&gt;clearFlags(NodeMustGenerate);
+            return;
+        }
+
+        if (node-&gt;child1()-&gt;shouldSpeculateNumber()) {
+            fixEdge&lt;DoubleRepUse&gt;(node-&gt;child1());
+            node-&gt;clearFlags(NodeMustGenerate);
+            return;
+        }
+
</ins><span class="cx">         // ToString(Symbol) throws an error. So if the child1 can include Symbols,
</span><span class="cx">         // we need to care about it in the clobberize. In the following case,
</span><span class="cx">         // since NotCellUse edge filter is used and this edge filters Symbols,
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGNodeType.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -335,6 +335,7 @@
</span><span class="cx">     macro(ToNumber, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(CallObjectConstructor, NodeResultJS) \
</span><span class="cx">     macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
</span><ins>+    macro(NumberToStringWithRadix, NodeResultJS | NodeMustGenerate) \
</ins><span class="cx">     macro(NewStringObject, NodeResultJS) \
</span><span class="cx">     macro(MakeRope, NodeResultJS) \
</span><span class="cx">     macro(In, NodeResultBoolean | NodeMustGenerate) \
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1644,6 +1644,75 @@
</span><span class="cx">     return jsString(exec, lowercasedString);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+char* JIT_OPERATION operationInt32ToString(ExecState* exec, int32_t value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (radix &lt; 2 || radix &gt; 36) {
+        throwVMError(exec, scope, createRangeError(exec, ASCIILiteral(&quot;toString() radix argument must be between 2 and 36&quot;)));
+        return nullptr;
+    }
+
+    return reinterpret_cast&lt;char*&gt;(int32ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt52ToString(ExecState* exec, int64_t value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (radix &lt; 2 || radix &gt; 36) {
+        throwVMError(exec, scope, createRangeError(exec, ASCIILiteral(&quot;toString() radix argument must be between 2 and 36&quot;)));
+        return nullptr;
+    }
+
+    return reinterpret_cast&lt;char*&gt;(int52ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationDoubleToString(ExecState* exec, double value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (radix &lt; 2 || radix &gt; 36) {
+        throwVMError(exec, scope, createRangeError(exec, ASCIILiteral(&quot;toString() radix argument must be between 2 and 36&quot;)));
+        return nullptr;
+    }
+
+    return reinterpret_cast&lt;char*&gt;(numberToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt32ToStringWithValidRadix(ExecState* exec, int32_t value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return reinterpret_cast&lt;char*&gt;(int32ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt52ToStringWithValidRadix(ExecState* exec, int64_t value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return reinterpret_cast&lt;char*&gt;(int52ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationDoubleToStringWithValidRadix(ExecState* exec, double value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return reinterpret_cast&lt;char*&gt;(numberToString(vm, value, radix));
+}
+
</ins><span class="cx"> JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGOperations.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -159,6 +159,13 @@
</span><span class="cx"> 
</span><span class="cx"> JSString* JIT_OPERATION operationToLowerCase(ExecState*, JSString*, uint32_t);
</span><span class="cx"> 
</span><ins>+char* JIT_OPERATION operationInt32ToString(ExecState*, int32_t, int32_t);
+char* JIT_OPERATION operationInt52ToString(ExecState*, int64_t, int32_t);
+char* JIT_OPERATION operationDoubleToString(ExecState*, double, int32_t);
+char* JIT_OPERATION operationInt32ToStringWithValidRadix(ExecState*, int32_t, int32_t);
+char* JIT_OPERATION operationInt52ToStringWithValidRadix(ExecState*, int64_t, int32_t);
+char* JIT_OPERATION operationDoubleToStringWithValidRadix(ExecState*, double, int32_t);
+
</ins><span class="cx"> int32_t JIT_OPERATION operationMapHash(ExecState*, EncodedJSValue input);
</span><span class="cx"> JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
</span><span class="cx"> JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -897,6 +897,7 @@
</span><span class="cx">         case StringCharAt:
</span><span class="cx">         case CallStringConstructor:
</span><span class="cx">         case ToString:
</span><ins>+        case NumberToStringWithRadix:
</ins><span class="cx">         case MakeRope:
</span><span class="cx">         case StrCat: {
</span><span class="cx">             setPrediction(SpecString);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -288,6 +288,7 @@
</span><span class="cx">     case ToPrimitive:
</span><span class="cx">     case ToString:
</span><span class="cx">     case ToNumber:
</span><ins>+    case NumberToStringWithRadix:
</ins><span class="cx">     case SetFunctionName:
</span><span class="cx">     case StrCat:
</span><span class="cx">     case CallStringConstructor:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -7909,9 +7909,10 @@
</span><span class="cx">     return temporary.gpr();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeJIT::compileToStringOrCallStringConstructorOnCell(Node* node)
</del><ins>+void SpeculativeJIT::compileToStringOrCallStringConstructor(Node* node)
</ins><span class="cx"> {
</span><del>-    if (node-&gt;child1().useKind() == NotCellUse) {
</del><ins>+    switch (node-&gt;child1().useKind()) {
+    case NotCellUse: {
</ins><span class="cx">         JSValueOperand op1(this, node-&gt;child1(), ManualOperandSpeculation);
</span><span class="cx">         JSValueRegs op1Regs = op1.jsValueRegs();
</span><span class="cx"> 
</span><span class="lines">@@ -7933,7 +7934,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (node-&gt;child1().useKind() == UntypedUse) {
</del><ins>+    case UntypedUse: {
</ins><span class="cx">         JSValueOperand op1(this, node-&gt;child1());
</span><span class="cx">         JSValueRegs op1Regs = op1.jsValueRegs();
</span><span class="cx">         GPRReg op1PayloadGPR = op1Regs.payloadGPR();
</span><span class="lines">@@ -7965,7 +7966,16 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case Int32Use:
+    case Int52RepUse:
+    case DoubleRepUse:
+        compileToStringOrCallStringConstructorOnNumber(node);
+        return;
</ins><span class="cx"> 
</span><ins>+    default:
+        break;
+    }
+
</ins><span class="cx">     SpeculateCellOperand op1(this, node-&gt;child1());
</span><span class="cx">     GPRReg op1GPR = op1.gpr();
</span><span class="cx">     
</span><span class="lines">@@ -8040,6 +8050,92 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileToStringOrCallStringConstructorOnNumber(Node* node)
+{
+    auto callToString = [&amp;] (auto operation, GPRReg resultGPR, auto valueReg) {
+        flushRegisters();
+        callOperation(operation, resultGPR, valueReg, CCallHelpers::TrustedImm32(10));
+        m_jit.exceptionCheck();
+        cellResult(resultGPR, node);
+    };
+
+    switch (node-&gt;child1().useKind()) {
+    case Int32Use: {
+        SpeculateStrictInt32Operand value(this, node-&gt;child1());
+        GPRFlushedCallResult result(this);
+        callToString(operationInt32ToStringWithValidRadix, result.gpr(), value.gpr());
+        break;
+    }
+
+#if USE(JSVALUE64)
+    case Int52RepUse: {
+        SpeculateStrictInt52Operand value(this, node-&gt;child1());
+        GPRFlushedCallResult result(this);
+        callToString(operationInt52ToStringWithValidRadix, result.gpr(), value.gpr());
+        break;
+    }
+#endif
+
+    case DoubleRepUse: {
+        SpeculateDoubleOperand value(this, node-&gt;child1());
+        GPRFlushedCallResult result(this);
+        callToString(operationDoubleToStringWithValidRadix, result.gpr(), value.fpr());
+        break;
+    }
+
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+}
+
+void SpeculativeJIT::compileNumberToStringWithRadix(Node* node)
+{
+    bool validRadixIsGuaranteed = false;
+    if (node-&gt;child2()-&gt;isInt32Constant()) {
+        int32_t radix = node-&gt;child2()-&gt;asInt32();
+        if (radix &gt;= 2 &amp;&amp; radix &lt;= 36)
+            validRadixIsGuaranteed = true;
+    }
+
+    auto callToString = [&amp;] (auto operation, GPRReg resultGPR, auto valueReg, GPRReg radixGPR) {
+        flushRegisters();
+        callOperation(operation, resultGPR, valueReg, radixGPR);
+        m_jit.exceptionCheck();
+        cellResult(resultGPR, node);
+    };
+
+    switch (node-&gt;child1().useKind()) {
+    case Int32Use: {
+        SpeculateStrictInt32Operand value(this, node-&gt;child1());
+        SpeculateStrictInt32Operand radix(this, node-&gt;child2());
+        GPRFlushedCallResult result(this);
+        callToString(validRadixIsGuaranteed ? operationInt32ToStringWithValidRadix : operationInt32ToString, result.gpr(), value.gpr(), radix.gpr());
+        break;
+    }
+
+#if USE(JSVALUE64)
+    case Int52RepUse: {
+        SpeculateStrictInt52Operand value(this, node-&gt;child1());
+        SpeculateStrictInt32Operand radix(this, node-&gt;child2());
+        GPRFlushedCallResult result(this);
+        callToString(validRadixIsGuaranteed ? operationInt52ToStringWithValidRadix : operationInt52ToString, result.gpr(), value.gpr(), radix.gpr());
+        break;
+    }
+#endif
+
+    case DoubleRepUse: {
+        SpeculateDoubleOperand value(this, node-&gt;child1());
+        SpeculateStrictInt32Operand radix(this, node-&gt;child2());
+        GPRFlushedCallResult result(this);
+        callToString(validRadixIsGuaranteed ? operationDoubleToStringWithValidRadix : operationDoubleToString, result.gpr(), value.fpr(), radix.gpr());
+        break;
+    }
+
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileNewStringObject(Node* node)
</span><span class="cx"> {
</span><span class="cx">     SpeculateCellOperand operand(this, node-&gt;child1());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1377,7 +1377,30 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(P_JITOperation_EZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
</ins><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(P_JITOperation_EZZ operation, GPRReg result, GPRReg arg1, TrustedImm32 arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(P_JITOperation_EDZ operation, GPRReg result, FPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(P_JITOperation_EDZ operation, GPRReg result, FPRReg arg1, TrustedImm32 arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     JITCompiler::Call callOperation(Z_JITOperation_EOJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
</span><span class="cx">     {
</span><span class="lines">@@ -1601,6 +1624,17 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(P_JITOperation_EQZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(P_JITOperation_EQZ operation, GPRReg result, GPRReg arg1, TrustedImm32 arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
</span><span class="lines">@@ -2657,7 +2691,9 @@
</span><span class="cx">     void emitSwitchString(Node*, SwitchData*);
</span><span class="cx">     void emitSwitch(Node*);
</span><span class="cx">     
</span><del>-    void compileToStringOrCallStringConstructorOnCell(Node*);
</del><ins>+    void compileToStringOrCallStringConstructor(Node*);
+    void compileToStringOrCallStringConstructorOnNumber(Node*);
+    void compileNumberToStringWithRadix(Node*);
</ins><span class="cx">     void compileNewStringObject(Node*);
</span><span class="cx">     
</span><span class="cx">     void compileNewTypedArray(Node*);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -2796,6 +2796,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case NumberToStringWithRadix: {
+        compileNumberToStringWithRadix(node);
+        break;
+    }
+
</ins><span class="cx">     case GetByValWithThis: {
</span><span class="cx">         JSValueOperand base(this, node-&gt;child1());
</span><span class="cx">         JSValueRegs baseRegs = base.jsValueRegs();
</span><span class="lines">@@ -3730,7 +3735,7 @@
</span><span class="cx">         
</span><span class="cx">     case ToString:
</span><span class="cx">     case CallStringConstructor: {
</span><del>-        compileToStringOrCallStringConstructorOnCell(node);
</del><ins>+        compileToStringOrCallStringConstructor(node);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -3711,7 +3711,7 @@
</span><span class="cx">         
</span><span class="cx">     case ToString:
</span><span class="cx">     case CallStringConstructor: {
</span><del>-        compileToStringOrCallStringConstructorOnCell(node);
</del><ins>+        compileToStringOrCallStringConstructor(node);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -5007,6 +5007,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case NumberToStringWithRadix: {
+        compileNumberToStringWithRadix(node);
+        break;
+    }
+
</ins><span class="cx">     case IsObject: {
</span><span class="cx">         JSValueOperand value(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, value);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -390,6 +390,37 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case ToString:
+        case CallStringConstructor: {
+            Edge&amp; child1 = m_node-&gt;child1();
+            switch (child1.useKind()) {
+            case Int32Use:
+            case Int52RepUse:
+            case DoubleRepUse: {
+                if (child1-&gt;hasConstant()) {
+                    JSValue value = child1-&gt;constant()-&gt;value();
+                    if (value) {
+                        String result;
+                        if (value.isInt32())
+                            result = String::number(value.asInt32());
+                        else if (value.isNumber())
+                            result = String::numberToStringECMAScript(value.asNumber());
+
+                        if (!result.isNull()) {
+                            m_node-&gt;convertToLazyJSConstant(m_graph, LazyJSValue::newString(m_graph, result));
+                            m_changed = true;
+                        }
+                    }
+                }
+                break;
+            }
+
+            default:
+                break;
+            }
+            break;
+        }
+
</ins><span class="cx">         case GetArrayLength: {
</span><span class="cx">             if (m_node-&gt;arrayMode().type() == Array::Generic
</span><span class="cx">                 || m_node-&gt;arrayMode().type() == Array::String) {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -279,6 +279,7 @@
</span><span class="cx">     case DefineDataProperty:
</span><span class="cx">     case DefineAccessorProperty:
</span><span class="cx">     case ToLowerCase:
</span><ins>+    case NumberToStringWithRadix:
</ins><span class="cx">     case CheckDOM:
</span><span class="cx">     case CallDOM:
</span><span class="cx">     case CallDOMGetter:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -1076,6 +1076,9 @@
</span><span class="cx">         case ToLowerCase:
</span><span class="cx">             compileToLowerCase();
</span><span class="cx">             break;
</span><ins>+        case NumberToStringWithRadix:
+            compileNumberToStringWithRadix();
+            break;
</ins><span class="cx">         case CheckDOM:
</span><span class="cx">             compileCheckDOM();
</span><span class="cx">             break;
</span><span class="lines">@@ -4949,6 +4952,18 @@
</span><span class="cx">             setJSValue(m_out.phi(Int64, simpleResult, convertedResult));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><ins>+
+        case Int32Use:
+            setJSValue(vmCall(Int64, m_out.operation(operationInt32ToStringWithValidRadix), m_callFrame, lowInt32(m_node-&gt;child1()), m_out.constInt32(10)));
+            return;
+
+        case Int52RepUse:
+            setJSValue(vmCall(Int64, m_out.operation(operationInt52ToStringWithValidRadix), m_callFrame, lowStrictInt52(m_node-&gt;child1()), m_out.constInt32(10)));
+            return;
+
+        case DoubleRepUse:
+            setJSValue(vmCall(Int64, m_out.operation(operationDoubleToStringWithValidRadix), m_callFrame, lowDouble(m_node-&gt;child1()), m_out.constInt32(10)));
+            return;
</ins><span class="cx">             
</span><span class="cx">         default:
</span><span class="cx">             DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</span><span class="lines">@@ -9882,6 +9897,30 @@
</span><span class="cx">         setJSValue(m_out.phi(pointerType(), fastResult, slowResult));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileNumberToStringWithRadix()
+    {
+        bool validRadixIsGuaranteed = false;
+        if (m_node-&gt;child2()-&gt;isInt32Constant()) {
+            int32_t radix = m_node-&gt;child2()-&gt;asInt32();
+            if (radix &gt;= 2 &amp;&amp; radix &lt;= 36)
+                validRadixIsGuaranteed = true;
+        }
+
+        switch (m_node-&gt;child1().useKind()) {
+        case Int32Use:
+            setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationInt32ToStringWithValidRadix : operationInt32ToString), m_callFrame, lowInt32(m_node-&gt;child1()), lowInt32(m_node-&gt;child2())));
+            break;
+        case Int52RepUse:
+            setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationInt52ToStringWithValidRadix : operationInt52ToString), m_callFrame, lowStrictInt52(m_node-&gt;child1()), lowInt32(m_node-&gt;child2())));
+            break;
+        case DoubleRepUse:
+            setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationDoubleToStringWithValidRadix : operationDoubleToString), m_callFrame, lowDouble(m_node-&gt;child1()), lowInt32(m_node-&gt;child2())));
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+
</ins><span class="cx">     void compileResolveScope()
</span><span class="cx">     {
</span><span class="cx">         UniquedStringImpl* uid = m_graph.identifiers()[m_node-&gt;identifierNumber()];
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCorejitCCallHelpersh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/CCallHelpers.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/CCallHelpers.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/CCallHelpers.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -868,6 +868,14 @@
</span><span class="cx">         addCallArgument(arg2);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, TrustedImm32 arg2)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><span class="cx">         resetCallArguments();
</span><span class="lines">@@ -1069,6 +1077,20 @@
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, TrustedImm32 arg2)
+    {
+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+        // On Windows, arguments map to designated registers based on the argument positions, even when there are interlaced scalar and floating point arguments.
+        // See http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
+        moveDouble(arg1, FPRInfo::argumentFPR1);
+        move(arg2, GPRInfo::argumentGPR2);
+#else
+        moveDouble(arg1, FPRInfo::argumentFPR0);
+        move(arg2, GPRInfo::argumentGPR1);
+#endif
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><span class="cx"> #if OS(WINDOWS) &amp;&amp; CPU(X86_64)
</span><span class="lines">@@ -1111,6 +1133,13 @@
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, TrustedImm32 arg2)
+    {
+        moveDouble(arg1, FPRInfo::argumentFPR0);
+        move(arg2, GPRInfo::argumentGPR1);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><span class="cx">         moveDouble(arg3, FPRInfo::argumentFPR0);
</span><span class="lines">@@ -1151,6 +1180,13 @@
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, TrustedImm32 arg2)
+    {
+        move(arg2, GPRInfo::argumentGPR3);
+        assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><span class="cx">         setupStubArguments(arg1, arg2);
</span><span class="lines">@@ -1204,6 +1240,13 @@
</span><span class="cx">         poke(arg2, 4);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, TrustedImm32 arg2)
+    {
+        assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+        poke(arg2, 4);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><span class="cx">         setupStubArguments(arg1, arg2);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/JITOperations.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/JITOperations.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/jit/JITOperations.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -311,6 +311,8 @@
</span><span class="cx"> typedef char* (JIT_OPERATION *P_JITOperation_EStZB)(ExecState*, Structure*, int32_t, Butterfly*);
</span><span class="cx"> typedef char* (JIT_OPERATION *P_JITOperation_EStZP)(ExecState*, Structure*, int32_t, char*);
</span><span class="cx"> typedef char* (JIT_OPERATION *P_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
</span><ins>+typedef char* (JIT_OPERATION *P_JITOperation_EQZ)(ExecState*, int64_t, int32_t);
+typedef char* (JIT_OPERATION *P_JITOperation_EDZ)(ExecState*, double, int32_t);
</ins><span class="cx"> typedef SlowPathReturnType (JIT_OPERATION *Sprt_JITOperation_ECli)(ExecState*, CallLinkInfo*);
</span><span class="cx"> typedef StringImpl* (JIT_OPERATION *T_JITOperation_EJss)(ExecState*, JSString*);
</span><span class="cx"> typedef JSString* (JIT_OPERATION *Jss_JITOperation_EZ)(ExecState*, int32_t);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/Intrinsic.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/Intrinsic.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/Intrinsic.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -56,6 +56,8 @@
</span><span class="cx">     StringPrototypeValueOfIntrinsic,
</span><span class="cx">     StringPrototypeReplaceIntrinsic,
</span><span class="cx">     StringPrototypeReplaceRegExpIntrinsic,
</span><ins>+    StringPrototypeToLowerCaseIntrinsic,
+    NumberPrototypeToStringIntrinsic,
</ins><span class="cx">     IMulIntrinsic,
</span><span class="cx">     RandomIntrinsic,
</span><span class="cx">     FRoundIntrinsic,
</span><span class="lines">@@ -78,7 +80,6 @@
</span><span class="cx">     AtomicsWaitIntrinsic,
</span><span class="cx">     AtomicsWakeIntrinsic,
</span><span class="cx">     AtomicsXorIntrinsic,
</span><del>-    ToLowerCaseIntrinsic,
</del><span class="cx">     ParseIntIntrinsic,
</span><span class="cx"> 
</span><span class="cx">     // Getter intrinsics.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeNumberPrototypecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx"> /* Source for NumberPrototype.lut.h
</span><span class="cx"> @begin numberPrototypeTable
</span><del>-  toString          numberProtoFuncToString         DontEnum|Function 1
</del><ins>+  toString          numberProtoFuncToString         DontEnum|Function 1 NumberPrototypeToStringIntrinsic
</ins><span class="cx">   toLocaleString    numberProtoFuncToLocaleString   DontEnum|Function 0
</span><span class="cx">   valueOf           numberProtoFuncValueOf          DontEnum|Function 0
</span><span class="cx">   toFixed           numberProtoFuncToFixed          DontEnum|Function 1
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx"> // Mapping from integers 0..35 to digit identifying this value, for radix 2..36.
</span><span class="cx"> static const char radixDigits[] = &quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;;
</span><span class="cx"> 
</span><del>-static char* int52ToStringWithRadix(char* startOfResultString, int64_t int52Value, unsigned radix)
</del><ins>+static inline char* int52ToStringWithRadix(char* startOfResultString, int64_t int52Value, unsigned radix)
</ins><span class="cx"> {
</span><span class="cx">     bool negative = false;
</span><span class="cx">     uint64_t positiveNumber = int52Value;
</span><span class="lines">@@ -499,25 +499,68 @@
</span><span class="cx">     return radix;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline EncodedJSValue integerValueToString(ExecState* exec, int32_t radix, int32_t value)
</del><ins>+static inline JSString* int32ToStringInternal(VM&amp; vm, int32_t value, int32_t radix)
</ins><span class="cx"> {
</span><ins>+    ASSERT(!(radix &lt; 2 || radix &gt; 36));
</ins><span class="cx">     // A negative value casted to unsigned would be bigger than 36 (the max radix).
</span><span class="cx">     if (static_cast&lt;unsigned&gt;(value) &lt; static_cast&lt;unsigned&gt;(radix)) {
</span><span class="cx">         ASSERT(value &lt;= 36);
</span><span class="cx">         ASSERT(value &gt;= 0);
</span><del>-        VM* vm = &amp;exec-&gt;vm();
-        return JSValue::encode(vm-&gt;smallStrings.singleCharacterString(radixDigits[value]));
</del><ins>+        return vm.smallStrings.singleCharacterString(radixDigits[value]);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (radix == 10) {
</span><del>-        VM* vm = &amp;exec-&gt;vm();
-        return JSValue::encode(jsString(vm, vm-&gt;numericStrings.add(value)));
</del><ins>+        return jsString(&amp;vm, vm.numericStrings.add(value));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return JSValue::encode(jsString(exec, toStringWithRadix(value, radix)));
</del><ins>+    return jsString(&amp;vm, toStringWithRadix(value, radix));
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static ALWAYS_INLINE JSString* numberToStringInternal(VM&amp; vm, double doubleValue, int32_t radix)
+{
+    ASSERT(!(radix &lt; 2 || radix &gt; 36));
+
+    int32_t integerValue = static_cast&lt;int32_t&gt;(doubleValue);
+    if (integerValue == doubleValue)
+        return int32ToStringInternal(vm, integerValue, radix);
+
+    if (radix == 10)
+        return jsString(&amp;vm, vm.numericStrings.add(doubleValue));
+
+    if (!std::isfinite(doubleValue))
+        return jsNontrivialString(&amp;vm, String::numberToStringECMAScript(doubleValue));
+
+    RadixBuffer buffer;
+    return jsString(&amp;vm, toStringWithRadix(buffer, doubleValue, radix));
+}
+
+JSString* int32ToString(VM&amp; vm, int32_t value, int32_t radix)
+{
+    return int32ToStringInternal(vm, value, radix);
+}
+
+JSString* int52ToString(VM&amp; vm, int64_t value, int32_t radix)
+{
+    ASSERT(!(radix &lt; 2 || radix &gt; 36));
+    if (radix == 10)
+        return jsString(&amp;vm, vm.numericStrings.add(static_cast&lt;double&gt;(value)));
+
+    // Position the decimal point at the center of the string, set
+    // the startOfResultString pointer to point at the decimal point.
+    RadixBuffer buffer;
+    char* decimalPoint = buffer + sizeof(buffer) / 2;
+    char* startOfResultString = decimalPoint;
+    *decimalPoint = '\0';
+
+    return jsString(&amp;vm, int52ToStringWithRadix(startOfResultString, value, radix));
+}
+
+JSString* numberToString(VM&amp; vm, double doubleValue, int32_t radix)
+{
+    return numberToStringInternal(vm, doubleValue, radix);
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="lines">@@ -531,18 +574,7 @@
</span><span class="cx">     if (radix &lt; 2 || radix &gt; 36)
</span><span class="cx">         return throwVMError(exec, scope, createRangeError(exec, ASCIILiteral(&quot;toString() radix argument must be between 2 and 36&quot;)));
</span><span class="cx"> 
</span><del>-    int32_t integerValue = static_cast&lt;int32_t&gt;(doubleValue);
-    if (integerValue == doubleValue)
-        return integerValueToString(exec, radix, integerValue);
-
-    if (radix == 10)
-        return JSValue::encode(jsString(&amp;vm, vm.numericStrings.add(doubleValue)));
-
-    if (!std::isfinite(doubleValue))
-        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(doubleValue)));
-
-    RadixBuffer s;
-    return JSValue::encode(jsString(exec, toStringWithRadix(s, doubleValue, radix)));
</del><ins>+    return JSValue::encode(numberToStringInternal(vm, doubleValue, radix));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeNumberPrototypeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.h (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.h        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/NumberPrototype.h        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -51,5 +51,8 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*);
</span><ins>+JSString* int32ToString(VM&amp;, int32_t value, int32_t radix);
+JSString* int52ToString(VM&amp;, int64_t value, int32_t radix);
+JSString* numberToString(VM&amp;, double value, int32_t radix);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/StringPrototype.cpp (214773 => 214774)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/StringPrototype.cpp        2017-04-03 12:32:51 UTC (rev 214773)
+++ releases/WebKitGTK/webkit-2.16/Source/JavaScriptCore/runtime/StringPrototype.cpp        2017-04-03 12:33:21 UTC (rev 214774)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;slice&quot;, stringProtoFuncSlice, DontEnum, 2);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;substr&quot;, stringProtoFuncSubstr, DontEnum, 2);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;substring&quot;, stringProtoFuncSubstring, DontEnum, 2);
</span><del>-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(&quot;toLowerCase&quot;, stringProtoFuncToLowerCase, DontEnum, 0, ToLowerCaseIntrinsic);
</del><ins>+    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(&quot;toLowerCase&quot;, stringProtoFuncToLowerCase, DontEnum, 0, StringPrototypeToLowerCaseIntrinsic);
</ins><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;toUpperCase&quot;, stringProtoFuncToUpperCase, DontEnum, 0);
</span><span class="cx"> #if ENABLE(INTL)
</span><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(&quot;localeCompare&quot;, stringPrototypeLocaleCompareCodeGenerator, DontEnum);
</span></span></pre>
</div>
</div>

</body>
</html>