<!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>[205974] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/205974">205974</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-09-15 09:51:12 -0700 (Thu, 15 Sep 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/205931">r205931</a>.
https://bugs.webkit.org/show_bug.cgi?id=162021
Tests for this change fail on 32-bit JSC bots (Requested by
ryanhaddad on #webkit).
Reverted changeset:
"[JSC] Make the rounding-related nodes support any type"
https://bugs.webkit.org/show_bug.cgi?id=161895
http://trac.webkit.org/changeset/205931</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressarithceilonvarioustypesjs">trunk/JSTests/stress/arith-ceil-on-various-types.js</a></li>
<li><a href="#trunkJSTestsstressarithflooronvarioustypesjs">trunk/JSTests/stress/arith-floor-on-various-types.js</a></li>
<li><a href="#trunkJSTestsstressarithroundonvarioustypesjs">trunk/JSTests/stress/arith-round-on-various-types.js</a></li>
<li><a href="#trunkJSTestsstressarithtrunconvarioustypesjs">trunk/JSTests/stress/arith-trunc-on-various-types.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/JSTests/ChangeLog        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-09-15 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r205931.
+ https://bugs.webkit.org/show_bug.cgi?id=162021
+
+ Tests for this change fail on 32-bit JSC bots (Requested by
+ ryanhaddad on #webkit).
+
+ Reverted changeset:
+
+ "[JSC] Make the rounding-related nodes support any type"
+ https://bugs.webkit.org/show_bug.cgi?id=161895
+ http://trac.webkit.org/changeset/205931
+
</ins><span class="cx"> 2016-09-15 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> test262: Should be a SyntaxError for duplicate parameter names in function with default parameters
</span></span></pre></div>
<a id="trunkJSTestsstressarithceilonvarioustypesjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/arith-ceil-on-various-types.js (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/arith-ceil-on-various-types.js        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/JSTests/stress/arith-ceil-on-various-types.js        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,295 +0,0 @@
</span><del>-"use strict";
-
-let validInputTestCases = [
- // input as string, expected result as string.
- ["undefined", "NaN"],
- ["null", "0"],
- ["0", "0"],
- ["-0.", "-0"],
- ["0.5", "1"],
- ["-0.5", "-0"],
- ["4", "4"],
- ["42.1", "43"],
- ["42.5", "43"],
- ["42.9", "43"],
- ["-42.1", "-42"],
- ["-42.5", "-42"],
- ["-42.9", "-42"],
- ["Math.PI", "4"],
- ["Infinity", "Infinity"],
- ["-Infinity", "-Infinity"],
- ["NaN", "NaN"],
- ["\"WebKit\"", "NaN"],
- ["\"4\"", "4"],
- ["\"42.5\"", "43"],
- ["{ valueOf: () => { return 4; } }", "4"],
- ["{ valueOf: () => { return 0; } }", "0"],
- ["{ valueOf: () => { return -0; } }", "-0"],
- ["{ valueOf: () => { return 0.5; } }", "1"],
- ["{ valueOf: () => { return -0.5; } }", "-0"],
- ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
- ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
- ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
- ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
- ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
- ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483648"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
- if (expected === expected) {
- if (result !== expected)
- return false;
- if (!expected && (1 / expected) !== (1 / result))
- return false;
-
- return true;
- }
- return result !== result;
-}
-
-
-// Test Math.ceil() without arguments.
-function opaqueCeilNoArgument() {
- return Math.ceil();
-}
-noInline(opaqueCeilNoArgument);
-noOSRExitFuzzing(opaqueCeilNoArgument);
-
-function testNoArgument() {
- for (let i = 0; i < 1e4; ++i) {
- let output = opaqueCeilNoArgument();
- if (!isIdentical(output, NaN)) {
- throw "Failed opaqueCeilNoArgument";
- }
- }
- if (numberOfDFGCompiles(opaqueCeilNoArgument) > 1)
- throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.ceil() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesCeil(argument) {
- return Math.ceil(argument);
-}
-noInline(opaqueAllTypesCeil);
-noOSRExitFuzzing(opaqueAllTypesCeil);
-
-function testAllTypesCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesCeil(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1]))
- throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesCeil) > 3)
- throw "We should have detected ceil() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesCeilWithoutNegativeZero(argument) {
- return Math.ceil(argument) + 0;
-}
-noInline(opaqueAllTypesCeilWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesCeilWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesCeilWithoutNegativeZero(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1] + 0))
- throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesCeil) > 3)
- throw "We should have detected ceil() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.ceil() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueCeil(argument) {
- return Math.ceil(argument);
- }
- noInline(opaqueCeil);
- noOSRExitFuzzing(opaqueCeil);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueCeil(${testCaseInput[0]}), ${testCaseInput[1]})) {
- throw "Failed testSingleTypeCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueCeil) > 1)
- throw "We should have compiled a single ceil for the expected type.";
- `);
- }
-}
-testSingleTypeCall();
-
-
-// Test Math.ceil() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueCeil(argument) {
- return Math.ceil(argument) + 0;
- }
- noInline(opaqueCeil);
- noOSRExitFuzzing(opaqueCeil);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueCeil(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
- throw "Failed testSingleTypeWithoutNegativeZeroCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueCeil) > 1)
- throw "We should have compiled a single ceil for the expected type.";
- `);
- }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.ceil() on constants
-function testConstant() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueCeilOnConstant() {
- return Math.ceil(${testCaseInput[0]});
- }
- noInline(opaqueCeilOnConstant);
- noOSRExitFuzzing(opaqueCeilOnConstant);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueCeilOnConstant(), ${testCaseInput[1]})) {
- throw "Failed testConstant()";
- }
- }
- if (numberOfDFGCompiles(opaqueCeilOnConstant) > 1)
- throw "We should have compiled a single ceil for the expected type.";
- `);
- }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueCeilForSideEffects(argument) {
- return Math.ceil(argument);
-}
-noInline(opaqueCeilForSideEffects);
-noOSRExitFuzzing(opaqueCeilForSideEffects);
-
-function testSideEffect() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let ceil16 = Math.ceil(16);
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueCeilForSideEffects(testObject) !== ceil16)
- throw "Incorrect result in testSideEffect()";
- }
- if (testObject.counter !== 1e4)
- throw "Failed testSideEffect()";
- if (numberOfDFGCompiles(opaqueCeilForSideEffects) > 1)
- throw "opaqueCeilForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify ceil() is not subject to CSE if the argument has side effects.
-function opaqueCeilForCSE(argument) {
- return Math.ceil(argument) + Math.ceil(argument) + Math.ceil(argument);
-}
-noInline(opaqueCeilForCSE);
-noOSRExitFuzzing(opaqueCeilForCSE);
-
-function testCSE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let ceil16 = Math.ceil(16);
- let threeCeil16 = ceil16 + ceil16 + ceil16;
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueCeilForCSE(testObject) !== threeCeil16)
- throw "Incorrect result in testCSE()";
- }
- if (testObject.counter !== 3e4)
- throw "Failed testCSE()";
- if (numberOfDFGCompiles(opaqueCeilForCSE) > 1)
- throw "opaqueCeilForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify ceil() is not subject to DCE if the argument has side effects.
-function opaqueCeilForDCE(argument) {
- Math.ceil(argument);
-}
-noInline(opaqueCeilForDCE);
-noOSRExitFuzzing(opaqueCeilForDCE);
-
-function testDCE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- for (let i = 0; i < 1e4; ++i) {
- opaqueCeilForDCE(testObject);
- }
- if (testObject.counter !== 1e4)
- throw "Failed testDCE()";
- if (numberOfDFGCompiles(opaqueCeilForDCE) > 1)
- throw "opaqueCeilForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
- let counter = 0;
- function opaqueCeilWithException(argument) {
- let result = Math.ceil(argument);
- ++counter;
- return result;
- }
- noInline(opaqueCeilWithException);
-
- let testObject = { valueOf: () => { return 64; } };
- let ceil64 = Math.ceil(64);
-
- // Warm up without exception.
- for (let i = 0; i < 1e3; ++i) {
- if (opaqueCeilWithException(testObject) !== ceil64)
- throw "Incorrect result in opaqueCeilWithException()";
- }
-
- let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
- for (let i = 0; i < 1e2; ++i) {
- try {
- if (opaqueCeilWithException(testThrowObject) !== 8)
- throw "This code should not be reached!!";
- } catch (e) {
- if (e !== testObject) {
- throw "Wrong object thrown from opaqueCeilWithException."
- }
- }
- }
-
- if (counter !== 1e3) {
- throw "Invalid count in testException()";
- }
-}
-testException();
</del></span></pre></div>
<a id="trunkJSTestsstressarithflooronvarioustypesjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/arith-floor-on-various-types.js (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/arith-floor-on-various-types.js        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/JSTests/stress/arith-floor-on-various-types.js        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,295 +0,0 @@
</span><del>-"use strict";
-
-let validInputTestCases = [
- // input as string, expected result as string.
- ["undefined", "NaN"],
- ["null", "0"],
- ["0", "0"],
- ["-0.", "-0"],
- ["0.5", "0"],
- ["-0.5", "-1"],
- ["4", "4"],
- ["42.1", "42"],
- ["42.5", "42"],
- ["42.9", "42"],
- ["-42.1", "-43"],
- ["-42.5", "-43"],
- ["-42.9", "-43"],
- ["Math.PI", "3"],
- ["Infinity", "Infinity"],
- ["-Infinity", "-Infinity"],
- ["NaN", "NaN"],
- ["\"WebKit\"", "NaN"],
- ["\"4\"", "4"],
- ["\"42.5\"", "42"],
- ["{ valueOf: () => { return 4; } }", "4"],
- ["{ valueOf: () => { return 0; } }", "0"],
- ["{ valueOf: () => { return -0; } }", "-0"],
- ["{ valueOf: () => { return 0.5; } }", "0"],
- ["{ valueOf: () => { return -0.5; } }", "-1"],
- ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
- ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
- ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
- ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
- ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483649"],
- ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483647"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
- if (expected === expected) {
- if (result !== expected)
- return false;
- if (!expected && (1 / expected) !== (1 / result))
- return false;
-
- return true;
- }
- return result !== result;
-}
-
-
-// Test Math.floor() without arguments.
-function opaqueFloorNoArgument() {
- return Math.floor();
-}
-noInline(opaqueFloorNoArgument);
-noOSRExitFuzzing(opaqueFloorNoArgument);
-
-function testNoArgument() {
- for (let i = 0; i < 1e4; ++i) {
- let output = opaqueFloorNoArgument();
- if (!isIdentical(output, NaN)) {
- throw "Failed opaqueFloorNoArgument";
- }
- }
- if (numberOfDFGCompiles(opaqueFloorNoArgument) > 1)
- throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.floor() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesFloor(argument) {
- return Math.floor(argument);
-}
-noInline(opaqueAllTypesFloor);
-noOSRExitFuzzing(opaqueAllTypesFloor);
-
-function testAllTypesCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesFloor(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1]))
- throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesFloor) > 3)
- throw "We should have detected floor() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesFloorWithoutNegativeZero(argument) {
- return Math.floor(argument) + 0;
-}
-noInline(opaqueAllTypesFloorWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesFloorWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesFloorWithoutNegativeZero(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1] + 0))
- throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesFloor) > 3)
- throw "We should have detected floor() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.floor() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueFloor(argument) {
- return Math.floor(argument);
- }
- noInline(opaqueFloor);
- noOSRExitFuzzing(opaqueFloor);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueFloor(${testCaseInput[0]}), ${testCaseInput[1]})) {
- throw "Failed testSingleTypeCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueFloor) > 1)
- throw "We should have compiled a single floor for the expected type.";
- `);
- }
-}
-testSingleTypeCall();
-
-
-// Test Math.floor() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueFloor(argument) {
- return Math.floor(argument) + 0;
- }
- noInline(opaqueFloor);
- noOSRExitFuzzing(opaqueFloor);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueFloor(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
- throw "Failed testSingleTypeWithoutNegativeZeroCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueFloor) > 1)
- throw "We should have compiled a single floor for the expected type.";
- `);
- }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.floor() on constants
-function testConstant() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueFloorOnConstant() {
- return Math.floor(${testCaseInput[0]});
- }
- noInline(opaqueFloorOnConstant);
- noOSRExitFuzzing(opaqueFloorOnConstant);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueFloorOnConstant(), ${testCaseInput[1]})) {
- throw "Failed testConstant()";
- }
- }
- if (numberOfDFGCompiles(opaqueFloorOnConstant) > 1)
- throw "We should have compiled a single floor for the expected type.";
- `);
- }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueFloorForSideEffects(argument) {
- return Math.floor(argument);
-}
-noInline(opaqueFloorForSideEffects);
-noOSRExitFuzzing(opaqueFloorForSideEffects);
-
-function testSideEffect() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let floor16 = Math.floor(16);
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueFloorForSideEffects(testObject) !== floor16)
- throw "Incorrect result in testSideEffect()";
- }
- if (testObject.counter !== 1e4)
- throw "Failed testSideEffect()";
- if (numberOfDFGCompiles(opaqueFloorForSideEffects) > 1)
- throw "opaqueFloorForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify floor() is not subject to CSE if the argument has side effects.
-function opaqueFloorForCSE(argument) {
- return Math.floor(argument) + Math.floor(argument) + Math.floor(argument);
-}
-noInline(opaqueFloorForCSE);
-noOSRExitFuzzing(opaqueFloorForCSE);
-
-function testCSE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let floor16 = Math.floor(16);
- let threeFloor16 = floor16 + floor16 + floor16;
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueFloorForCSE(testObject) !== threeFloor16)
- throw "Incorrect result in testCSE()";
- }
- if (testObject.counter !== 3e4)
- throw "Failed testCSE()";
- if (numberOfDFGCompiles(opaqueFloorForCSE) > 1)
- throw "opaqueFloorForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify floor() is not subject to DCE if the argument has side effects.
-function opaqueFloorForDCE(argument) {
- Math.floor(argument);
-}
-noInline(opaqueFloorForDCE);
-noOSRExitFuzzing(opaqueFloorForDCE);
-
-function testDCE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- for (let i = 0; i < 1e4; ++i) {
- opaqueFloorForDCE(testObject);
- }
- if (testObject.counter !== 1e4)
- throw "Failed testDCE()";
- if (numberOfDFGCompiles(opaqueFloorForDCE) > 1)
- throw "opaqueFloorForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
- let counter = 0;
- function opaqueFloorWithException(argument) {
- let result = Math.floor(argument);
- ++counter;
- return result;
- }
- noInline(opaqueFloorWithException);
-
- let testObject = { valueOf: () => { return 64; } };
- let floor64 = Math.floor(64);
-
- // Warm up without exception.
- for (let i = 0; i < 1e3; ++i) {
- if (opaqueFloorWithException(testObject) !== floor64)
- throw "Incorrect result in opaqueFloorWithException()";
- }
-
- let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
- for (let i = 0; i < 1e2; ++i) {
- try {
- if (opaqueFloorWithException(testThrowObject) !== 8)
- throw "This code should not be reached!!";
- } catch (e) {
- if (e !== testObject) {
- throw "Wrong object thrown from opaqueFloorWithException."
- }
- }
- }
-
- if (counter !== 1e3) {
- throw "Invalid count in testException()";
- }
-}
-testException();
</del></span></pre></div>
<a id="trunkJSTestsstressarithroundonvarioustypesjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/arith-round-on-various-types.js (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/arith-round-on-various-types.js        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/JSTests/stress/arith-round-on-various-types.js        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,295 +0,0 @@
</span><del>-"use strict";
-
-let validInputTestCases = [
- // input as string, expected result as string.
- ["undefined", "NaN"],
- ["null", "0"],
- ["0", "0"],
- ["-0.", "-0"],
- ["0.5", "1"],
- ["-0.5", "-0"],
- ["4", "4"],
- ["42.1", "42"],
- ["42.5", "43"],
- ["42.9", "43"],
- ["-42.1", "-42"],
- ["-42.5", "-42"],
- ["-42.9", "-43"],
- ["Math.PI", "3"],
- ["Infinity", "Infinity"],
- ["-Infinity", "-Infinity"],
- ["NaN", "NaN"],
- ["\"WebKit\"", "NaN"],
- ["\"4\"", "4"],
- ["\"42.5\"", "43"],
- ["{ valueOf: () => { return 4; } }", "4"],
- ["{ valueOf: () => { return 0; } }", "0"],
- ["{ valueOf: () => { return -0; } }", "-0"],
- ["{ valueOf: () => { return 0.5; } }", "1"],
- ["{ valueOf: () => { return -0.5; } }", "-0"],
- ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
- ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
- ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
- ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
- ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
- ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483648"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
- if (expected === expected) {
- if (result !== expected)
- return false;
- if (!expected && (1 / expected) !== (1 / result))
- return false;
-
- return true;
- }
- return result !== result;
-}
-
-
-// Test Math.round() without arguments.
-function opaqueRoundNoArgument() {
- return Math.round();
-}
-noInline(opaqueRoundNoArgument);
-noOSRExitFuzzing(opaqueRoundNoArgument);
-
-function testNoArgument() {
- for (let i = 0; i < 1e4; ++i) {
- let output = opaqueRoundNoArgument();
- if (!isIdentical(output, NaN)) {
- throw "Failed opaqueRoundNoArgument";
- }
- }
- if (numberOfDFGCompiles(opaqueRoundNoArgument) > 1)
- throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.round() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesRound(argument) {
- return Math.round(argument);
-}
-noInline(opaqueAllTypesRound);
-noOSRExitFuzzing(opaqueAllTypesRound);
-
-function testAllTypesCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesRound(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1]))
- throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesRound) > 3)
- throw "We should have detected round() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesRoundWithoutNegativeZero(argument) {
- return Math.round(argument) + 0;
-}
-noInline(opaqueAllTypesRoundWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesRoundWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesRoundWithoutNegativeZero(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1] + 0))
- throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesRound) > 3)
- throw "We should have detected round() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.round() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueRound(argument) {
- return Math.round(argument);
- }
- noInline(opaqueRound);
- noOSRExitFuzzing(opaqueRound);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueRound(${testCaseInput[0]}), ${testCaseInput[1]})) {
- throw "Failed testSingleTypeCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueRound) > 1)
- throw "We should have compiled a single round for the expected type.";
- `);
- }
-}
-testSingleTypeCall();
-
-
-// Test Math.round() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueRound(argument) {
- return Math.round(argument) + 0;
- }
- noInline(opaqueRound);
- noOSRExitFuzzing(opaqueRound);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueRound(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
- throw "Failed testSingleTypeWithoutNegativeZeroCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueRound) > 1)
- throw "We should have compiled a single round for the expected type.";
- `);
- }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.round() on constants
-function testConstant() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueRoundOnConstant() {
- return Math.round(${testCaseInput[0]});
- }
- noInline(opaqueRoundOnConstant);
- noOSRExitFuzzing(opaqueRoundOnConstant);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueRoundOnConstant(), ${testCaseInput[1]})) {
- throw "Failed testConstant()";
- }
- }
- if (numberOfDFGCompiles(opaqueRoundOnConstant) > 1)
- throw "We should have compiled a single round for the expected type.";
- `);
- }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueRoundForSideEffects(argument) {
- return Math.round(argument);
-}
-noInline(opaqueRoundForSideEffects);
-noOSRExitFuzzing(opaqueRoundForSideEffects);
-
-function testSideEffect() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let round16 = Math.round(16);
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueRoundForSideEffects(testObject) !== round16)
- throw "Incorrect result in testSideEffect()";
- }
- if (testObject.counter !== 1e4)
- throw "Failed testSideEffect()";
- if (numberOfDFGCompiles(opaqueRoundForSideEffects) > 1)
- throw "opaqueRoundForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify round() is not subject to CSE if the argument has side effects.
-function opaqueRoundForCSE(argument) {
- return Math.round(argument) + Math.round(argument) + Math.round(argument);
-}
-noInline(opaqueRoundForCSE);
-noOSRExitFuzzing(opaqueRoundForCSE);
-
-function testCSE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let round16 = Math.round(16);
- let threeRound16 = round16 + round16 + round16;
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueRoundForCSE(testObject) !== threeRound16)
- throw "Incorrect result in testCSE()";
- }
- if (testObject.counter !== 3e4)
- throw "Failed testCSE()";
- if (numberOfDFGCompiles(opaqueRoundForCSE) > 1)
- throw "opaqueRoundForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify round() is not subject to DCE if the argument has side effects.
-function opaqueRoundForDCE(argument) {
- Math.round(argument);
-}
-noInline(opaqueRoundForDCE);
-noOSRExitFuzzing(opaqueRoundForDCE);
-
-function testDCE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- for (let i = 0; i < 1e4; ++i) {
- opaqueRoundForDCE(testObject);
- }
- if (testObject.counter !== 1e4)
- throw "Failed testDCE()";
- if (numberOfDFGCompiles(opaqueRoundForDCE) > 1)
- throw "opaqueRoundForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
- let counter = 0;
- function opaqueRoundWithException(argument) {
- let result = Math.round(argument);
- ++counter;
- return result;
- }
- noInline(opaqueRoundWithException);
-
- let testObject = { valueOf: () => { return 64; } };
- let round64 = Math.round(64);
-
- // Warm up without exception.
- for (let i = 0; i < 1e3; ++i) {
- if (opaqueRoundWithException(testObject) !== round64)
- throw "Incorrect result in opaqueRoundWithException()";
- }
-
- let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
- for (let i = 0; i < 1e2; ++i) {
- try {
- if (opaqueRoundWithException(testThrowObject) !== 8)
- throw "This code should not be reached!!";
- } catch (e) {
- if (e !== testObject) {
- throw "Wrong object thrown from opaqueRoundWithException."
- }
- }
- }
-
- if (counter !== 1e3) {
- throw "Invalid count in testException()";
- }
-}
-testException();
</del></span></pre></div>
<a id="trunkJSTestsstressarithtrunconvarioustypesjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/arith-trunc-on-various-types.js (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/arith-trunc-on-various-types.js        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/JSTests/stress/arith-trunc-on-various-types.js        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,295 +0,0 @@
</span><del>-"use strict";
-
-let validInputTestCases = [
- // input as string, expected result as string.
- ["undefined", "NaN"],
- ["null", "0"],
- ["0", "0"],
- ["-0.", "-0"],
- ["0.5", "0"],
- ["-0.5", "-0"],
- ["4", "4"],
- ["42.1", "42"],
- ["42.5", "42"],
- ["42.9", "42"],
- ["-42.1", "-42"],
- ["-42.5", "-42"],
- ["-42.9", "-42"],
- ["Math.PI", "3"],
- ["Infinity", "Infinity"],
- ["-Infinity", "-Infinity"],
- ["NaN", "NaN"],
- ["\"WebKit\"", "NaN"],
- ["\"4\"", "4"],
- ["\"42.5\"", "42"],
- ["{ valueOf: () => { return 4; } }", "4"],
- ["{ valueOf: () => { return 0; } }", "0"],
- ["{ valueOf: () => { return -0; } }", "-0"],
- ["{ valueOf: () => { return 0.5; } }", "0"],
- ["{ valueOf: () => { return -0.5; } }", "-0"],
- ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
- ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
- ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
- ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
- ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
- ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483647"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
- if (expected === expected) {
- if (result !== expected)
- return false;
- if (!expected && (1 / expected) !== (1 / result))
- return false;
-
- return true;
- }
- return result !== result;
-}
-
-
-// Test Math.trunc() without arguments.
-function opaqueTruncNoArgument() {
- return Math.trunc();
-}
-noInline(opaqueTruncNoArgument);
-noOSRExitFuzzing(opaqueTruncNoArgument);
-
-function testNoArgument() {
- for (let i = 0; i < 1e4; ++i) {
- let output = opaqueTruncNoArgument();
- if (!isIdentical(output, NaN)) {
- throw "Failed opaqueTruncNoArgument";
- }
- }
- if (numberOfDFGCompiles(opaqueTruncNoArgument) > 1)
- throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.trunc() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesTrunc(argument) {
- return Math.trunc(argument);
-}
-noInline(opaqueAllTypesTrunc);
-noOSRExitFuzzing(opaqueAllTypesTrunc);
-
-function testAllTypesCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesTrunc(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1]))
- throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesTrunc) > 3)
- throw "We should have detected trunc() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesTruncWithoutNegativeZero(argument) {
- return Math.trunc(argument) + 0;
-}
-noInline(opaqueAllTypesTruncWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesTruncWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
- for (let i = 0; i < 1e3; ++i) {
- for (let testCaseInput of validInputTypedTestCases) {
- let output = opaqueAllTypesTruncWithoutNegativeZero(testCaseInput[0]);
- if (!isIdentical(output, testCaseInput[1] + 0))
- throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
- }
- }
- if (numberOfDFGCompiles(opaqueAllTypesTrunc) > 3)
- throw "We should have detected trunc() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.trunc() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueTrunc(argument) {
- return Math.trunc(argument);
- }
- noInline(opaqueTrunc);
- noOSRExitFuzzing(opaqueTrunc);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueTrunc(${testCaseInput[0]}), ${testCaseInput[1]})) {
- throw "Failed testSingleTypeCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueTrunc) > 1)
- throw "We should have compiled a single trunc for the expected type.";
- `);
- }
-}
-testSingleTypeCall();
-
-
-// Test Math.trunc() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueTrunc(argument) {
- return Math.trunc(argument) - 0;
- }
- noInline(opaqueTrunc);
- noOSRExitFuzzing(opaqueTrunc);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueTrunc(${testCaseInput[0]}), ${testCaseInput[1]} - 0)) {
- throw "Failed testSingleTypeWithoutNegativeZeroCall()";
- }
- }
- if (numberOfDFGCompiles(opaqueTrunc) > 1)
- throw "We should have compiled a single trunc for the expected type.";
- `);
- }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.trunc() on constants
-function testConstant() {
- for (let testCaseInput of validInputTestCases) {
- eval(`
- function opaqueTruncOnConstant() {
- return Math.trunc(${testCaseInput[0]});
- }
- noInline(opaqueTruncOnConstant);
- noOSRExitFuzzing(opaqueTruncOnConstant);
-
- for (let i = 0; i < 1e4; ++i) {
- if (!isIdentical(opaqueTruncOnConstant(), ${testCaseInput[1]})) {
- throw "Failed testConstant()";
- }
- }
- if (numberOfDFGCompiles(opaqueTruncOnConstant) > 1)
- throw "We should have compiled a single trunc for the expected type.";
- `);
- }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueTruncForSideEffects(argument) {
- return Math.trunc(argument);
-}
-noInline(opaqueTruncForSideEffects);
-noOSRExitFuzzing(opaqueTruncForSideEffects);
-
-function testSideEffect() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let trunc16 = Math.trunc(16);
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueTruncForSideEffects(testObject) !== trunc16)
- throw "Incorrect result in testSideEffect()";
- }
- if (testObject.counter !== 1e4)
- throw "Failed testSideEffect()";
- if (numberOfDFGCompiles(opaqueTruncForSideEffects) > 1)
- throw "opaqueTruncForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify trunc() is not subject to CSE if the argument has side effects.
-function opaqueTruncForCSE(argument) {
- return Math.trunc(argument) + Math.trunc(argument) + Math.trunc(argument);
-}
-noInline(opaqueTruncForCSE);
-noOSRExitFuzzing(opaqueTruncForCSE);
-
-function testCSE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- let trunc16 = Math.trunc(16);
- let threeTrunc16 = trunc16 + trunc16 + trunc16;
- for (let i = 0; i < 1e4; ++i) {
- if (opaqueTruncForCSE(testObject) !== threeTrunc16)
- throw "Incorrect result in testCSE()";
- }
- if (testObject.counter !== 3e4)
- throw "Failed testCSE()";
- if (numberOfDFGCompiles(opaqueTruncForCSE) > 1)
- throw "opaqueTruncForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify trunc() is not subject to DCE if the argument has side effects.
-function opaqueTruncForDCE(argument) {
- Math.trunc(argument);
-}
-noInline(opaqueTruncForDCE);
-noOSRExitFuzzing(opaqueTruncForDCE);
-
-function testDCE() {
- let testObject = {
- counter: 0,
- valueOf: function() { ++this.counter; return 16; }
- };
- for (let i = 0; i < 1e4; ++i) {
- opaqueTruncForDCE(testObject);
- }
- if (testObject.counter !== 1e4)
- throw "Failed testDCE()";
- if (numberOfDFGCompiles(opaqueTruncForDCE) > 1)
- throw "opaqueTruncForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
- let counter = 0;
- function opaqueTruncWithException(argument) {
- let result = Math.trunc(argument);
- ++counter;
- return result;
- }
- noInline(opaqueTruncWithException);
-
- let testObject = { valueOf: () => { return 64; } };
- let trunc64 = Math.trunc(64);
-
- // Warm up without exception.
- for (let i = 0; i < 1e3; ++i) {
- if (opaqueTruncWithException(testObject) !== trunc64)
- throw "Incorrect result in opaqueTruncWithException()";
- }
-
- let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
- for (let i = 0; i < 1e2; ++i) {
- try {
- if (opaqueTruncWithException(testThrowObject) !== 8)
- throw "This code should not be reached!!";
- } catch (e) {
- if (e !== testObject) {
- throw "Wrong object thrown from opaqueTruncWithException."
- }
- }
- }
-
- if (counter !== 1e3) {
- throw "Invalid count in testException()";
- }
-}
-testException();
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-09-15 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r205931.
+ https://bugs.webkit.org/show_bug.cgi?id=162021
+
+ Tests for this change fail on 32-bit JSC bots (Requested by
+ ryanhaddad on #webkit).
+
+ Reverted changeset:
+
+ "[JSC] Make the rounding-related nodes support any type"
+ https://bugs.webkit.org/show_bug.cgi?id=161895
+ http://trac.webkit.org/changeset/205931
+
</ins><span class="cx"> 2016-09-15 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> test262: Should be a SyntaxError for duplicate parameter names in function with default parameters
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -905,23 +905,19 @@
</span><span class="cx"> case ArithCeil:
</span><span class="cx"> case ArithTrunc: {
</span><span class="cx"> JSValue operand = forNode(node->child1()).value();
</span><del>- if (Optional<double> number = operand.toNumberFromPrimitive()) {
</del><ins>+ if (operand && operand.isNumber()) {
</ins><span class="cx"> double roundedValue = 0;
</span><span class="cx"> if (node->op() == ArithRound)
</span><del>- roundedValue = jsRound(*number);
</del><ins>+ roundedValue = jsRound(operand.asNumber());
</ins><span class="cx"> else if (node->op() == ArithFloor)
</span><del>- roundedValue = floor(*number);
</del><ins>+ roundedValue = floor(operand.asNumber());
</ins><span class="cx"> else if (node->op() == ArithCeil)
</span><del>- roundedValue = ceil(*number);
</del><ins>+ roundedValue = ceil(operand.asNumber());
</ins><span class="cx"> else {
</span><span class="cx"> ASSERT(node->op() == ArithTrunc);
</span><del>- roundedValue = trunc(*number);
</del><ins>+ roundedValue = trunc(operand.asNumber());
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (node->child1().useKind() == UntypedUse) {
- setConstant(node, jsNumber(roundedValue));
- break;
- }
</del><span class="cx"> if (producesInteger(node->arithRoundingMode())) {
</span><span class="cx"> int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
</span><span class="cx"> if (roundedValueAsInt32 == roundedValue) {
</span><span class="lines">@@ -940,15 +936,10 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- if (node->child1().useKind() == DoubleRepUse) {
- if (producesInteger(node->arithRoundingMode()))
- forNode(node).setType(SpecInt32Only);
- else if (node->child1().useKind() == DoubleRepUse)
- forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
- } else {
- DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse);
- forNode(node).setType(SpecFullNumber);
- }
</del><ins>+ if (producesInteger(node->arithRoundingMode()))
+ forNode(node).setType(SpecInt32Only);
+ else
+ forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -2450,22 +2450,25 @@
</span><span class="cx"> set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><del>- insertChecks();
- Node* operand = get(virtualRegisterForArgument(1, registerOffset));
- NodeType op;
- if (intrinsic == RoundIntrinsic)
- op = ArithRound;
- else if (intrinsic == FloorIntrinsic)
- op = ArithFloor;
- else if (intrinsic == CeilIntrinsic)
- op = ArithCeil;
- else {
- ASSERT(intrinsic == TruncIntrinsic);
- op = ArithTrunc;
</del><ins>+ if (argumentCountIncludingThis == 2) {
+ insertChecks();
+ Node* operand = get(virtualRegisterForArgument(1, registerOffset));
+ NodeType op;
+ if (intrinsic == RoundIntrinsic)
+ op = ArithRound;
+ else if (intrinsic == FloorIntrinsic)
+ op = ArithFloor;
+ else if (intrinsic == CeilIntrinsic)
+ op = ArithCeil;
+ else {
+ ASSERT(intrinsic == TruncIntrinsic);
+ op = ArithTrunc;
+ }
+ Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
+ set(VirtualRegister(resultOperand), roundNode);
+ return true;
</ins><span class="cx"> }
</span><del>- Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
- set(VirtualRegister(resultOperand), roundNode);
- return true;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx"> case IMulIntrinsic: {
</span><span class="cx"> if (argumentCountIncludingThis != 3)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -358,12 +358,7 @@
</span><span class="cx"> case ArithFloor:
</span><span class="cx"> case ArithCeil:
</span><span class="cx"> case ArithTrunc:
</span><del>- if (node->child1().useKind() == DoubleRepUse)
- def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
- else {
- read(World);
- write(Heap);
- }
</del><ins>+ def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> case CheckCell:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -376,28 +376,24 @@
</span><span class="cx"> case ArithFloor:
</span><span class="cx"> case ArithCeil:
</span><span class="cx"> case ArithTrunc: {
</span><del>- if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
</del><ins>+ if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
</ins><span class="cx"> fixIntOrBooleanEdge(node->child1());
</span><span class="cx"> insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
</span><span class="cx"> node->convertToIdentity();
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>- if (node->child1()->shouldSpeculateNotCell()) {
- fixDoubleOrBooleanEdge(node->child1());
</del><ins>+ fixDoubleOrBooleanEdge(node->child1());
</ins><span class="cx">
</span><del>- if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
- node->setResult(NodeResultInt32);
- if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
- node->setArithRoundingMode(Arith::RoundingMode::Int32);
- else
- node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
- } else {
- node->setResult(NodeResultDouble);
- node->setArithRoundingMode(Arith::RoundingMode::Double);
- }
- node->clearFlags(NodeMustGenerate);
- } else
- fixEdge<UntypedUse>(node->child1());
</del><ins>+ if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
+ node->setResult(NodeResultInt32);
+ if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithRoundingMode(Arith::RoundingMode::Int32);
+ else
+ node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
+ } else {
+ node->setResult(NodeResultDouble);
+ node->setArithRoundingMode(Arith::RoundingMode::Double);
+ }
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -155,10 +155,10 @@
</span><span class="cx"> macro(ArithFRound, NodeResultDouble | NodeMustGenerate) \
</span><span class="cx"> macro(ArithPow, NodeResultDouble) \
</span><span class="cx"> macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
</span><del>- macro(ArithRound, NodeResultNumber | NodeMustGenerate) \
- macro(ArithFloor, NodeResultNumber | NodeMustGenerate) \
- macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
- macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
</del><ins>+ macro(ArithRound, NodeResultNumber) \
+ macro(ArithFloor, NodeResultNumber) \
+ macro(ArithCeil, NodeResultNumber) \
+ macro(ArithTrunc, NodeResultNumber) \
</ins><span class="cx"> macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
</span><span class="cx"> macro(ArithSin, NodeResultDouble | NodeMustGenerate) \
</span><span class="cx"> macro(ArithCos, NodeResultDouble | NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -442,58 +442,6 @@
</span><span class="cx"> return tan(a);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
-{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
- auto scope = DECLARE_THROW_SCOPE(*vm);
-
- JSValue argument = JSValue::decode(encodedArgument);
- double valueOfArgument = argument.toNumber(exec);
- if (UNLIKELY(scope.exception()))
- return JSValue::encode(JSValue());
- return JSValue::encode(jsNumber(jsRound(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithFloor(ExecState* exec, EncodedJSValue encodedArgument)
-{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
- auto scope = DECLARE_THROW_SCOPE(*vm);
-
- JSValue argument = JSValue::decode(encodedArgument);
- double valueOfArgument = argument.toNumber(exec);
- if (UNLIKELY(scope.exception()))
- return JSValue::encode(JSValue());
- return JSValue::encode(jsNumber(floor(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithCeil(ExecState* exec, EncodedJSValue encodedArgument)
-{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
- auto scope = DECLARE_THROW_SCOPE(*vm);
-
- JSValue argument = JSValue::decode(encodedArgument);
- double valueOfArgument = argument.toNumber(exec);
- if (UNLIKELY(scope.exception()))
- return JSValue::encode(JSValue());
- return JSValue::encode(jsNumber(ceil(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState* exec, EncodedJSValue encodedArgument)
-{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
- auto scope = DECLARE_THROW_SCOPE(*vm);
-
- JSValue argument = JSValue::decode(encodedArgument);
- double truncatedValueOfArgument = argument.toIntegerPreserveNaN(exec);
- if (UNLIKELY(scope.exception()))
- return JSValue::encode(JSValue());
- return JSValue::encode(jsNumber(truncatedValueOfArgument));
-}
-
</del><span class="cx"> static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
</span><span class="cx"> {
</span><span class="cx"> VM& vm = exec->vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -61,10 +61,6 @@
</span><span class="cx"> double JIT_OPERATION operationArithLog(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><span class="cx"> double JIT_OPERATION operationArithSin(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><span class="cx"> double JIT_OPERATION operationArithSqrt(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationArithRound(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithFloor(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithCeil(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState*, EncodedJSValue) WTF_INTERNAL;
</del><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState*, JSCell*, EncodedJSValue encodedProperty) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState*, JSArray*, int32_t) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -318,6 +318,17 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case ArithRound:
+ case ArithFloor:
+ case ArithCeil:
+ case ArithTrunc: {
+ if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass))
+ changed |= setPrediction(SpecInt32Only);
+ else
+ changed |= setPrediction(SpecBytecodeDouble);
+ break;
+ }
+
</ins><span class="cx"> case ArithAbs: {
</span><span class="cx"> SpeculatedType childPrediction = node->child1()->prediction();
</span><span class="cx"> if (isInt32OrBooleanSpeculation(childPrediction)
</span><span class="lines">@@ -765,18 +776,6 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case ArithRound:
- case ArithFloor:
- case ArithCeil:
- case ArithTrunc: {
- if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
- && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
- setPrediction(SpecInt32Only);
- else
- setPrediction(SpecBytecodeDouble);
- break;
- }
-
</del><span class="cx"> case ArithRandom: {
</span><span class="cx"> setPrediction(SpecDoubleReal);
</span><span class="cx"> break;
</span><span class="lines">@@ -951,6 +950,10 @@
</span><span class="cx"> case ArithMul:
</span><span class="cx"> case ArithDiv:
</span><span class="cx"> case ArithMod:
</span><ins>+ case ArithRound:
+ case ArithFloor:
+ case ArithCeil:
+ case ArithTrunc:
</ins><span class="cx"> case ArithAbs:
</span><span class="cx"> case GetByVal:
</span><span class="cx"> case ToThis:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -4910,129 +4910,101 @@
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::compileArithRounding(Node* node)
</span><span class="cx"> {
</span><del>- if (node->child1().useKind() == DoubleRepUse) {
- SpeculateDoubleOperand value(this, node->child1());
- FPRReg valueFPR = value.fpr();
</del><ins>+ ASSERT(node->child1().useKind() == DoubleRepUse);
</ins><span class="cx">
</span><del>- auto setResult = [&] (FPRReg resultFPR) {
- if (producesInteger(node->arithRoundingMode())) {
- GPRTemporary roundedResultAsInt32(this);
- FPRTemporary scratch(this);
- FPRReg scratchFPR = scratch.fpr();
- GPRReg resultGPR = roundedResultAsInt32.gpr();
- JITCompiler::JumpList failureCases;
- m_jit.branchConvertDoubleToInt32(resultFPR, resultGPR, failureCases, scratchFPR, shouldCheckNegativeZero(node->arithRoundingMode()));
- speculationCheck(Overflow, JSValueRegs(), node, failureCases);
</del><ins>+ SpeculateDoubleOperand value(this, node->child1());
+ FPRReg valueFPR = value.fpr();
</ins><span class="cx">
</span><del>- int32Result(resultGPR, node);
- } else
- doubleResult(resultFPR, node);
- };
</del><ins>+ auto setResult = [&] (FPRReg resultFPR) {
+ if (producesInteger(node->arithRoundingMode())) {
+ GPRTemporary roundedResultAsInt32(this);
+ FPRTemporary scratch(this);
+ FPRReg scratchFPR = scratch.fpr();
+ GPRReg resultGPR = roundedResultAsInt32.gpr();
+ JITCompiler::JumpList failureCases;
+ m_jit.branchConvertDoubleToInt32(resultFPR, resultGPR, failureCases, scratchFPR, shouldCheckNegativeZero(node->arithRoundingMode()));
+ speculationCheck(Overflow, JSValueRegs(), node, failureCases);
</ins><span class="cx">
</span><del>- if (m_jit.supportsFloatingPointRounding()) {
- switch (node->op()) {
- case ArithRound: {
- FPRTemporary result(this);
- FPRReg resultFPR = result.fpr();
- if (producesInteger(node->arithRoundingMode()) && !shouldCheckNegativeZero(node->arithRoundingMode())) {
- static const double halfConstant = 0.5;
- m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), resultFPR);
- m_jit.addDouble(valueFPR, resultFPR);
- m_jit.floorDouble(resultFPR, resultFPR);
- } else {
- m_jit.ceilDouble(valueFPR, resultFPR);
- FPRTemporary realPart(this);
- FPRReg realPartFPR = realPart.fpr();
- m_jit.subDouble(resultFPR, valueFPR, realPartFPR);
</del><ins>+ int32Result(resultGPR, node);
+ } else
+ doubleResult(resultFPR, node);
+ };
</ins><span class="cx">
</span><del>- FPRTemporary scratch(this);
- FPRReg scratchFPR = scratch.fpr();
- static const double halfConstant = 0.5;
- m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), scratchFPR);
</del><ins>+ if (m_jit.supportsFloatingPointRounding()) {
+ switch (node->op()) {
+ case ArithRound: {
+ FPRTemporary result(this);
+ FPRReg resultFPR = result.fpr();
+ if (producesInteger(node->arithRoundingMode()) && !shouldCheckNegativeZero(node->arithRoundingMode())) {
+ static const double halfConstant = 0.5;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), resultFPR);
+ m_jit.addDouble(valueFPR, resultFPR);
+ m_jit.floorDouble(resultFPR, resultFPR);
+ } else {
+ m_jit.ceilDouble(valueFPR, resultFPR);
+ FPRTemporary realPart(this);
+ FPRReg realPartFPR = realPart.fpr();
+ m_jit.subDouble(resultFPR, valueFPR, realPartFPR);
</ins><span class="cx">
</span><del>- JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
- static const double oneConstant = -1.0;
- m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), scratchFPR);
- m_jit.addDouble(scratchFPR, resultFPR);
- shouldUseCeiled.link(&m_jit);
- }
- setResult(resultFPR);
- return;
- }
</del><ins>+ FPRTemporary scratch(this);
+ FPRReg scratchFPR = scratch.fpr();
+ static const double halfConstant = 0.5;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), scratchFPR);
</ins><span class="cx">
</span><del>- case ArithFloor: {
- FPRTemporary rounded(this);
- FPRReg resultFPR = rounded.fpr();
- m_jit.floorDouble(valueFPR, resultFPR);
- setResult(resultFPR);
- return;
</del><ins>+ JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
+ static const double oneConstant = -1.0;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), scratchFPR);
+ m_jit.addDouble(scratchFPR, resultFPR);
+ shouldUseCeiled.link(&m_jit);
</ins><span class="cx"> }
</span><ins>+ setResult(resultFPR);
+ return;
+ }
</ins><span class="cx">
</span><del>- case ArithCeil: {
- FPRTemporary rounded(this);
- FPRReg resultFPR = rounded.fpr();
- m_jit.ceilDouble(valueFPR, resultFPR);
- setResult(resultFPR);
- return;
- }
</del><ins>+ case ArithFloor: {
+ FPRTemporary rounded(this);
+ FPRReg resultFPR = rounded.fpr();
+ m_jit.floorDouble(valueFPR, resultFPR);
+ setResult(resultFPR);
+ return;
+ }
</ins><span class="cx">
</span><del>- case ArithTrunc: {
- FPRTemporary rounded(this);
- FPRReg resultFPR = rounded.fpr();
- m_jit.roundTowardZeroDouble(valueFPR, resultFPR);
- setResult(resultFPR);
- return;
- }
</del><ins>+ case ArithCeil: {
+ FPRTemporary rounded(this);
+ FPRReg resultFPR = rounded.fpr();
+ m_jit.ceilDouble(valueFPR, resultFPR);
+ setResult(resultFPR);
+ return;
+ }
</ins><span class="cx">
</span><del>- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- } else {
- flushRegisters();
- FPRResult roundedResultAsDouble(this);
- FPRReg resultFPR = roundedResultAsDouble.fpr();
- if (node->op() == ArithRound)
- callOperation(jsRound, resultFPR, valueFPR);
- else if (node->op() == ArithFloor)
- callOperation(floor, resultFPR, valueFPR);
- else if (node->op() == ArithCeil)
- callOperation(ceil, resultFPR, valueFPR);
- else {
- ASSERT(node->op() == ArithTrunc);
- callOperation(trunc, resultFPR, valueFPR);
- }
</del><ins>+ case ArithTrunc: {
+ FPRTemporary rounded(this);
+ FPRReg resultFPR = rounded.fpr();
+ m_jit.roundTowardZeroDouble(valueFPR, resultFPR);
</ins><span class="cx"> setResult(resultFPR);
</span><ins>+ return;
</ins><span class="cx"> }
</span><del>- return;
- }
</del><span class="cx">
</span><del>- DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
-
- JSValueOperand argument(this, node->child1());
- JSValueRegs argumentRegs = argument.jsValueRegs();
-#if USE(JSVALUE64)
- GPRTemporary result(this);
- JSValueRegs resultRegs = JSValueRegs(result.gpr());
-#else
- GPRTemporary resultTag(this);
- GPRTemporary resultPayload(this);
- JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
-#endif
- flushRegisters();
- J_JITOperation_EJ operation = nullptr;
- if (node->op() == ArithRound)
- operation = operationArithRound;
- else if (node->op() == ArithFloor)
- operation = operationArithFloor;
- else if (node->op() == ArithCeil)
- operation = operationArithCeil;
- else {
- ASSERT(node->op() == ArithTrunc);
- operation = operationArithTrunc;
</del><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ } else {
+ flushRegisters();
+ FPRResult roundedResultAsDouble(this);
+ FPRReg resultFPR = roundedResultAsDouble.fpr();
+ if (node->op() == ArithRound)
+ callOperation(jsRound, resultFPR, valueFPR);
+ else if (node->op() == ArithFloor)
+ callOperation(floor, resultFPR, valueFPR);
+ else if (node->op() == ArithCeil)
+ callOperation(ceil, resultFPR, valueFPR);
+ else {
+ ASSERT(node->op() == ArithTrunc);
+ callOperation(trunc, resultFPR, valueFPR);
+ }
+ m_jit.exceptionCheck();
+ setResult(resultFPR);
</ins><span class="cx"> }
</span><del>- callOperation(operation, resultRegs, argumentRegs);
- m_jit.exceptionCheck();
- jsValueResult(resultRegs, node);
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::compileArithSin(Node* node)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (205973 => 205974)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-09-15 16:32:15 UTC (rev 205973)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-09-15 16:51:12 UTC (rev 205974)
</span><span class="lines">@@ -2266,91 +2266,67 @@
</span><span class="cx">
</span><span class="cx"> void compileArithRound()
</span><span class="cx"> {
</span><del>- if (m_node->child1().useKind() == DoubleRepUse) {
- LValue result = nullptr;
- if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
- LValue value = lowDouble(m_node->child1());
- result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
- } else {
- LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
- LBasicBlock continuation = m_out.newBlock();
</del><ins>+ LValue result = nullptr;
</ins><span class="cx">
</span><del>- LValue value = lowDouble(m_node->child1());
- LValue integerValue = m_out.doubleCeil(value);
- ValueFromBlock integerValueResult = m_out.anchor(integerValue);
</del><ins>+ if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
+ LValue value = lowDouble(m_node->child1());
+ result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
+ } else {
+ LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
+ LBasicBlock continuation = m_out.newBlock();
</ins><span class="cx">
</span><del>- LValue realPart = m_out.doubleSub(integerValue, value);
</del><ins>+ LValue value = lowDouble(m_node->child1());
+ LValue integerValue = m_out.doubleCeil(value);
+ ValueFromBlock integerValueResult = m_out.anchor(integerValue);
</ins><span class="cx">
</span><del>- m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
</del><ins>+ LValue realPart = m_out.doubleSub(integerValue, value);
</ins><span class="cx">
</span><del>- LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
- LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
- ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
- m_out.jump(continuation);
- m_out.appendTo(continuation, lastNext);
</del><ins>+ m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
</ins><span class="cx">
</span><del>- result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
- }
</del><ins>+ LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
+ LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
+ ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
+ m_out.jump(continuation);
+ m_out.appendTo(continuation, lastNext);
</ins><span class="cx">
</span><del>- if (producesInteger(m_node->arithRoundingMode())) {
- LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
- setInt32(integerValue);
- } else
- setDouble(result);
- return;
</del><ins>+ result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
- LValue argument = lowJSValue(m_node->child1());
- setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
</del><ins>+ if (producesInteger(m_node->arithRoundingMode())) {
+ LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
+ setInt32(integerValue);
+ } else
+ setDouble(result);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileArithFloor()
</span><span class="cx"> {
</span><del>- if (m_node->child1().useKind() == DoubleRepUse) {
- LValue value = lowDouble(m_node->child1());
- LValue integerValue = m_out.doubleFloor(value);
- if (producesInteger(m_node->arithRoundingMode()))
- setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
- else
- setDouble(integerValue);
- return;
- }
- DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
- LValue argument = lowJSValue(m_node->child1());
- setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
</del><ins>+ LValue value = lowDouble(m_node->child1());
+ LValue integerValue = m_out.doubleFloor(value);
+ if (producesInteger(m_node->arithRoundingMode()))
+ setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+ else
+ setDouble(integerValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileArithCeil()
</span><span class="cx"> {
</span><del>- if (m_node->child1().useKind() == DoubleRepUse) {
- LValue value = lowDouble(m_node->child1());
- LValue integerValue = m_out.doubleCeil(value);
- if (producesInteger(m_node->arithRoundingMode()))
- setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
- else
- setDouble(integerValue);
- return;
- }
- DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
- LValue argument = lowJSValue(m_node->child1());
- setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
</del><ins>+ LValue value = lowDouble(m_node->child1());
+ LValue integerValue = m_out.doubleCeil(value);
+ if (producesInteger(m_node->arithRoundingMode()))
+ setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+ else
+ setDouble(integerValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileArithTrunc()
</span><span class="cx"> {
</span><del>- if (m_node->child1().useKind() == DoubleRepUse) {
- LValue value = lowDouble(m_node->child1());
- LValue result = m_out.doubleTrunc(value);
- if (producesInteger(m_node->arithRoundingMode()))
- setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
- else
- setDouble(result);
- return;
- }
- DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
- LValue argument = lowJSValue(m_node->child1());
- setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
</del><ins>+ LValue value = lowDouble(m_node->child1());
+ LValue result = m_out.doubleTrunc(value);
+ if (producesInteger(m_node->arithRoundingMode()))
+ setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+ else
+ setDouble(result);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileArithSqrt()
</span></span></pre>
</div>
</div>
</body>
</html>