<!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 <utatane.tea@gmail.com>
+
+ [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 <sbarati@apple.com>
</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 = "0123456789abcdefghijklmnopqrstuvwxyz";
+ let result = "";
+ let negative = false;
+ if (num < 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 < 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 < 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 < 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 = "0123456789abcdefghijklmnopqrstuvwxyz";
+ let result = "";
+ let negative = false;
+ if (num < 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 < 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 < 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 < 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 = "0123456789abcdefghijklmnopqrstuvwxyz";
+ let result = "";
+ let negative = false;
+ if (num < 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 < 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 < 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 < 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 <utatane.tea@gmail.com>
+
+ [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 <sbarati@apple.com>
</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 "pure" operation (modulo resolving a rope).
</span><ins>+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::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->origin.semantic)->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->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->structure()->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 && argumentCountIncludingThis != 2)
+ return false;
+
+ if (m_inlineStackTop->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->child1()->shouldSpeculateInt32())
+ fixEdge<Int32Use>(node->child1());
+ else if (enableInt52() && node->child1()->shouldSpeculateAnyInt())
+ fixEdge<Int52RepUse>(node->child1());
+ else
+ fixEdge<DoubleRepUse>(node->child1());
+ fixEdge<Int32Use>(node->child2());
+ break;
+ }
+
</ins><span class="cx"> case DefineAccessorProperty: {
</span><span class="cx"> fixEdge<CellUse>(m_graph.varArgChild(node, 0));
</span><span class="cx"> Edge& 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->child1()->shouldSpeculateInt32()) {
+ fixEdge<Int32Use>(node->child1());
+ node->clearFlags(NodeMustGenerate);
+ return;
+ }
+
+ if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
+ fixEdge<Int52RepUse>(node->child1());
+ node->clearFlags(NodeMustGenerate);
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateNumber()) {
+ fixEdge<DoubleRepUse>(node->child1());
+ node->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& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (radix < 2 || radix > 36) {
+ throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
+ return nullptr;
+ }
+
+ return reinterpret_cast<char*>(int32ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt52ToString(ExecState* exec, int64_t value, int32_t radix)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (radix < 2 || radix > 36) {
+ throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
+ return nullptr;
+ }
+
+ return reinterpret_cast<char*>(int52ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationDoubleToString(ExecState* exec, double value, int32_t radix)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (radix < 2 || radix > 36) {
+ throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
+ return nullptr;
+ }
+
+ return reinterpret_cast<char*>(numberToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt32ToStringWithValidRadix(ExecState* exec, int32_t value, int32_t radix)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return reinterpret_cast<char*>(int32ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationInt52ToStringWithValidRadix(ExecState* exec, int64_t value, int32_t radix)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return reinterpret_cast<char*>(int52ToString(vm, value, radix));
+}
+
+char* JIT_OPERATION operationDoubleToStringWithValidRadix(ExecState* exec, double value, int32_t radix)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return reinterpret_cast<char*>(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& vm = exec->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->child1().useKind() == NotCellUse) {
</del><ins>+ switch (node->child1().useKind()) {
+ case NotCellUse: {
</ins><span class="cx"> JSValueOperand op1(this, node->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->child1().useKind() == UntypedUse) {
</del><ins>+ case UntypedUse: {
</ins><span class="cx"> JSValueOperand op1(this, node->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->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 = [&] (auto operation, GPRReg resultGPR, auto valueReg) {
+ flushRegisters();
+ callOperation(operation, resultGPR, valueReg, CCallHelpers::TrustedImm32(10));
+ m_jit.exceptionCheck();
+ cellResult(resultGPR, node);
+ };
+
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateStrictInt32Operand value(this, node->child1());
+ GPRFlushedCallResult result(this);
+ callToString(operationInt32ToStringWithValidRadix, result.gpr(), value.gpr());
+ break;
+ }
+
+#if USE(JSVALUE64)
+ case Int52RepUse: {
+ SpeculateStrictInt52Operand value(this, node->child1());
+ GPRFlushedCallResult result(this);
+ callToString(operationInt52ToStringWithValidRadix, result.gpr(), value.gpr());
+ break;
+ }
+#endif
+
+ case DoubleRepUse: {
+ SpeculateDoubleOperand value(this, node->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->child2()->isInt32Constant()) {
+ int32_t radix = node->child2()->asInt32();
+ if (radix >= 2 && radix <= 36)
+ validRadixIsGuaranteed = true;
+ }
+
+ auto callToString = [&] (auto operation, GPRReg resultGPR, auto valueReg, GPRReg radixGPR) {
+ flushRegisters();
+ callOperation(operation, resultGPR, valueReg, radixGPR);
+ m_jit.exceptionCheck();
+ cellResult(resultGPR, node);
+ };
+
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateStrictInt32Operand value(this, node->child1());
+ SpeculateStrictInt32Operand radix(this, node->child2());
+ GPRFlushedCallResult result(this);
+ callToString(validRadixIsGuaranteed ? operationInt32ToStringWithValidRadix : operationInt32ToString, result.gpr(), value.gpr(), radix.gpr());
+ break;
+ }
+
+#if USE(JSVALUE64)
+ case Int52RepUse: {
+ SpeculateStrictInt52Operand value(this, node->child1());
+ SpeculateStrictInt32Operand radix(this, node->child2());
+ GPRFlushedCallResult result(this);
+ callToString(validRadixIsGuaranteed ? operationInt52ToStringWithValidRadix : operationInt52ToString, result.gpr(), value.gpr(), radix.gpr());
+ break;
+ }
+#endif
+
+ case DoubleRepUse: {
+ SpeculateDoubleOperand value(this, node->child1());
+ SpeculateStrictInt32Operand radix(this, node->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->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->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->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& child1 = m_node->child1();
+ switch (child1.useKind()) {
+ case Int32Use:
+ case Int52RepUse:
+ case DoubleRepUse: {
+ if (child1->hasConstant()) {
+ JSValue value = child1->constant()->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->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->arrayMode().type() == Array::Generic
</span><span class="cx"> || m_node->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->child1()), m_out.constInt32(10)));
+ return;
+
+ case Int52RepUse:
+ setJSValue(vmCall(Int64, m_out.operation(operationInt52ToStringWithValidRadix), m_callFrame, lowStrictInt52(m_node->child1()), m_out.constInt32(10)));
+ return;
+
+ case DoubleRepUse:
+ setJSValue(vmCall(Int64, m_out.operation(operationDoubleToStringWithValidRadix), m_callFrame, lowDouble(m_node->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, "Bad use kind");
</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->child2()->isInt32Constant()) {
+ int32_t radix = m_node->child2()->asInt32();
+ if (radix >= 2 && radix <= 36)
+ validRadixIsGuaranteed = true;
+ }
+
+ switch (m_node->child1().useKind()) {
+ case Int32Use:
+ setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationInt32ToStringWithValidRadix : operationInt32ToString), m_callFrame, lowInt32(m_node->child1()), lowInt32(m_node->child2())));
+ break;
+ case Int52RepUse:
+ setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationInt52ToStringWithValidRadix : operationInt52ToString), m_callFrame, lowStrictInt52(m_node->child1()), lowInt32(m_node->child2())));
+ break;
+ case DoubleRepUse:
+ setJSValue(vmCall(pointerType(), m_out.operation(validRadixIsGuaranteed ? operationDoubleToStringWithValidRadix : operationDoubleToString), m_callFrame, lowDouble(m_node->child1()), lowInt32(m_node->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->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) && 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) && 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[] = "0123456789abcdefghijklmnopqrstuvwxyz";
</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& vm, int32_t value, int32_t radix)
</ins><span class="cx"> {
</span><ins>+ ASSERT(!(radix < 2 || radix > 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<unsigned>(value) < static_cast<unsigned>(radix)) {
</span><span class="cx"> ASSERT(value <= 36);
</span><span class="cx"> ASSERT(value >= 0);
</span><del>- VM* vm = &exec->vm();
- return JSValue::encode(vm->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 = &exec->vm();
- return JSValue::encode(jsString(vm, vm->numericStrings.add(value)));
</del><ins>+ return jsString(&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(&vm, toStringWithRadix(value, radix));
</ins><span class="cx">
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static ALWAYS_INLINE JSString* numberToStringInternal(VM& vm, double doubleValue, int32_t radix)
+{
+ ASSERT(!(radix < 2 || radix > 36));
+
+ int32_t integerValue = static_cast<int32_t>(doubleValue);
+ if (integerValue == doubleValue)
+ return int32ToStringInternal(vm, integerValue, radix);
+
+ if (radix == 10)
+ return jsString(&vm, vm.numericStrings.add(doubleValue));
+
+ if (!std::isfinite(doubleValue))
+ return jsNontrivialString(&vm, String::numberToStringECMAScript(doubleValue));
+
+ RadixBuffer buffer;
+ return jsString(&vm, toStringWithRadix(buffer, doubleValue, radix));
+}
+
+JSString* int32ToString(VM& vm, int32_t value, int32_t radix)
+{
+ return int32ToStringInternal(vm, value, radix);
+}
+
+JSString* int52ToString(VM& vm, int64_t value, int32_t radix)
+{
+ ASSERT(!(radix < 2 || radix > 36));
+ if (radix == 10)
+ return jsString(&vm, vm.numericStrings.add(static_cast<double>(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(&vm, int52ToStringWithRadix(startOfResultString, value, radix));
+}
+
+JSString* numberToString(VM& 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& vm = exec->vm();
</span><span class="lines">@@ -531,18 +574,7 @@
</span><span class="cx"> if (radix < 2 || radix > 36)
</span><span class="cx"> return throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
</span><span class="cx">
</span><del>- int32_t integerValue = static_cast<int32_t>(doubleValue);
- if (integerValue == doubleValue)
- return integerValueToString(exec, radix, integerValue);
-
- if (radix == 10)
- return JSValue::encode(jsString(&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&, int32_t value, int32_t radix);
+JSString* int52ToString(VM&, int64_t value, int32_t radix);
+JSString* numberToString(VM&, 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("slice", stringProtoFuncSlice, DontEnum, 2);
</span><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("substr", stringProtoFuncSubstr, DontEnum, 2);
</span><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("substring", stringProtoFuncSubstring, DontEnum, 2);
</span><del>- JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("toLowerCase", stringProtoFuncToLowerCase, DontEnum, 0, ToLowerCaseIntrinsic);
</del><ins>+ JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("toLowerCase", stringProtoFuncToLowerCase, DontEnum, 0, StringPrototypeToLowerCaseIntrinsic);
</ins><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toUpperCase", stringProtoFuncToUpperCase, DontEnum, 0);
</span><span class="cx"> #if ENABLE(INTL)
</span><span class="cx"> JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringPrototypeLocaleCompareCodeGenerator, DontEnum);
</span></span></pre>
</div>
</div>
</body>
</html>