<!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>[208224] 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/208224">208224</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-11-01 10:20:25 -0700 (Tue, 01 Nov 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/208208">r208208</a> and <a href="http://trac.webkit.org/projects/webkit/changeset/208210">r208210</a>.
https://bugs.webkit.org/show_bug.cgi?id=164276
This change caused 28 JSC test failures. (Requested by
ryanhaddad on #webkit).
Reverted changesets:
"We should be able to eliminate rest parameter allocations"
https://bugs.webkit.org/show_bug.cgi?id=163925
http://trac.webkit.org/changeset/208208
"Fix the EFL build."
http://trac.webkit.org/changeset/208210</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="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsUtilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOperationscpp">trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitSetupVarargsFramecpp">trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkJSTestsmicrobenchmarksrestparameterallocationeliminationjs">trunk/JSTests/microbenchmarks/rest-parameter-allocation-elimination.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/JSTests/ChangeLog        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-11-01 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r208208 and r208210.
+ https://bugs.webkit.org/show_bug.cgi?id=164276
+
+ This change caused 28 JSC test failures. (Requested by
+ ryanhaddad on #webkit).
+
+ Reverted changesets:
+
+ "We should be able to eliminate rest parameter allocations"
+ https://bugs.webkit.org/show_bug.cgi?id=163925
+ http://trac.webkit.org/changeset/208208
+
+ "Fix the EFL build."
+ http://trac.webkit.org/changeset/208210
+
</ins><span class="cx"> 2016-10-31 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> JSC should support SharedArrayBuffer
</span></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksrestparameterallocationeliminationjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/microbenchmarks/rest-parameter-allocation-elimination.js (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/rest-parameter-allocation-elimination.js        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/JSTests/microbenchmarks/rest-parameter-allocation-elimination.js        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1,613 +0,0 @@
</span><del>-function assert(b, m = "") {
- if (!b)
- throw new Error("Bad assertion: " + m);
-}
-noInline(assert);
-
-const iterations = 20000;
-
-function test1() {
- function bar(a, b, ...args) {
- return args.length;
- }
- noInline(bar);
- for (let i = 0; i < iterations; i++) {
- assert(bar() === 0, bar());
- assert(bar(i) === 0);
- assert(bar(i, i) === 0);
- assert(bar(i, i, i) === 1);
- assert(bar(i, i, i, i, i) === 3);
- }
-}
-
-function shallowEq(a, b) {
- if (a.length !== b.length)
- return false;
- for (let i = 0; i < a.length; i++) {
- if (a.length !== b.length)
- return false;
- }
- return true;
-}
-noInline(shallowEq);
-
-function test2() {
- function jaz(a, b, ...args) {
- let result = [];
- for (let i = 0; i < args.length; i++) {
- result.push(args[i]);
- }
- return result;
- }
- noInline(jaz);
-
- function jaz2(...args) {
- function kaz(a, b, ...args) {
- let result = [];
- for (let i = 0; i < args.length; i++) {
- result.push(args[i]);
- }
- return result;
- }
- return kaz.apply(null, args);
- }
- noInline(jaz2);
-
- for (let f of [jaz, jaz2]) {
- for (let i = 0; i < iterations; i++) {
- let r = f();
- assert(!r.length);
-
- r = f(i);
- assert(!r.length);
-
- r = f(i, i)
- assert(!r.length);
-
- r = f(i, i, i)
- assert(r.length === 1);
- assert(shallowEq(r, [i]));
-
- r = f(i, i, i)
- assert(r.length === 1);
- assert(shallowEq(r, [i]));
-
- r = f(i, i, i, i*2, i*4)
- assert(r.length === 3);
- assert(shallowEq(r, [i, i*2, i*4]));
- }
- }
-}
-
-function test3() {
- function foo(...args) {
- return args;
- }
- function baz(a, b, c, ...args) {
- return foo.apply(null, args);
- }
- function jaz(a, b, c, d, e, f) {
- return baz(a, b, c, d, e, f);
- }
- noInline(jaz);
-
- for (let i = 0; i < iterations; i++) {
- let r = jaz();
- assert(r.length === 3);
- assert(shallowEq(r, [undefined, undefined, undefined]));
-
- r = jaz(i, i);
- assert(r.length === 3);
- assert(shallowEq(r, [undefined, undefined, undefined]));
-
- r = jaz(i, i, i);
- assert(r.length === 3);
- assert(shallowEq(r, [undefined, undefined, undefined]));
-
- r = jaz(i, i, i, i);
- assert(r.length === 3);
- assert(shallowEq(r, [i, undefined, undefined]));
-
- r = jaz(i, i, i, i, i, i);
- assert(r.length === 3);
- assert(shallowEq(r, [i, i, i]));
- }
-}
-
-function test4() {
- function baz(...args) {
- return args;
- }
- function jaz(a, b, ...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- for (let i = 0; i < iterations; i++) {
- let r = jaz();
- assert(r.length === 0);
-
- r = jaz(i);
- assert(r.length === 0);
-
- r = jaz(i, i);
- assert(r.length === 0);
-
- r = jaz(i, i, i);
- assert(r.length === 1);
- assert(shallowEq(r, [i]));
-
- r = jaz(i, i, i, i*10);
- assert(r.length === 2);
- assert(shallowEq(r, [i, i*10]));
-
- let o = {};
- r = jaz(i, i, i, i*10, o);
- assert(r.length === 3);
- assert(shallowEq(r, [i, i*10, o]));
- }
-}
-
-function test5() {
- function baz(...args) {
- return args;
- }
- noInline(baz);
- function jaz(a, b, ...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- for (let i = 0; i < iterations; i++) {
- let r = jaz();
- assert(r.length === 0);
-
- r = jaz(i);
- assert(r.length === 0);
-
- r = jaz(i, i);
- assert(r.length === 0);
-
- r = jaz(i, i, i);
- assert(r.length === 1);
- assert(shallowEq(r, [i]));
-
- r = jaz(i, i, i, i*10);
- assert(r.length === 2);
- assert(shallowEq(r, [i, i*10]));
-
- let o = {};
- r = jaz(i, i, i, i*10, o);
- assert(r.length === 3);
- assert(shallowEq(r, [i, i*10, o]));
- }
-}
-
-function test6() {
- "use strict";
- function baz(...args) {
- return args;
- }
- noInline(baz);
- function jaz(a, b, ...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- for (let i = 0; i < iterations; i++) {
- let r = jaz();
- assert(r.length === 0);
-
- r = jaz(i);
- assert(r.length === 0);
-
- r = jaz(i, i);
- assert(r.length === 0);
-
- r = jaz(i, i, i);
- assert(r.length === 1);
- assert(shallowEq(r, [i]));
-
- r = jaz(i, i, i, i*10);
- assert(r.length === 2);
- assert(shallowEq(r, [i, i*10]));
-
- let o = {};
- r = jaz(i, i, i, i*10, o);
- assert(r.length === 3);
- assert(shallowEq(r, [i, i*10, o]));
- }
-}
-
-function test7() {
- let shouldExit = false;
- function baz(...args) {
- if (shouldExit) {
- OSRExit();
- return [args.length, args[0], args[1], args[2]];
- }
- return [args.length, args[0], args[1], args[2]];
- }
- function jaz(a, b, ...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- function check(i) {
- let [length, a, b, c] = jaz();
- assert(length === 0);
- assert(a === undefined);
- assert(b === undefined);
- assert(c === undefined);
-
- [length, a, b, c] = jaz(i);
- assert(length === 0);
- assert(a === undefined);
- assert(b === undefined);
- assert(c === undefined);
-
- [length, a, b, c] = jaz(i, i);
- assert(length === 0);
- assert(a === undefined);
- assert(b === undefined);
- assert(c === undefined);
-
- [length, a, b, c] = jaz(i, i, i);
- assert(length === 1);
- assert(a === i, JSON.stringify(a));
- assert(b === undefined);
- assert(c === undefined);
-
- [length, a, b, c] = jaz(i, i, i, i*10);
- assert(length === 2);
- assert(a === i);
- assert(b === i*10);
- assert(c === undefined);
-
- let o = {oooo:20};
- [length, a, b, c] = jaz(i, i, i, i*10, o);
- assert(length === 3);
- assert(a === i);
- assert(b === i*10);
- assert(c === o);
- }
-
- shouldExit = true;
- for (let i = 0; i < 400; i++) {
- check(i);
- }
-
- shouldExit = false;
- for (let i = 0; i < iterations; i++) {
- check(i);
- }
-
- shouldExit = false;
- check(10);
-}
-
-function test8() {
- let shouldExit = false;
- function baz(...args) {
- if (shouldExit) {
- OSRExit();
- return args;
- }
- return args;
- }
- function jaz(a, b, ...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- function check(i) {
- let args = jaz();
- assert(args.length === 0);
-
- args = jaz(i);
- assert(args.length === 0);
-
- args = jaz(i, i);
- assert(args.length === 0);
-
- args = jaz(i, i, i);
- assert(args.length === 1);
- assert(args[0] === i);
-
- args = jaz(i, i, i, i*10);
- assert(args.length === 2);
- assert(args[0] === i);
- assert(args[1] === i*10);
-
- let o = {oooo:20};
- args = jaz(i, i, i, i*10, o);
- assert(args.length === 3);
- assert(args[0] === i);
- assert(args[1] === i*10);
- assert(args[2] === o);
- }
-
- shouldExit = true;
- for (let i = 0; i < 400; i++) {
- check(i);
- }
-
- shouldExit = false;
- for (let i = 0; i < iterations; i++) {
- check(i);
- }
-
- shouldExit = false;
- check(10);
-}
-
-function test9() {
- let shouldExit = false;
- function baz(a, ...args) {
- if (shouldExit) {
- OSRExit();
- return [args.length, args[0], args[1]];
- }
- return [args.length, args[0], args[1]];
- }
- function jaz(...args) {
- return baz.apply(null, args);
- }
- noInline(jaz);
-
- function check(i) {
- let [length, a, b] = jaz();
- assert(length === 0);
-
- [length, a, b] = jaz(i);
- assert(length === 0);
- assert(a === undefined);
- assert(b === undefined);
-
- [length, a, b] = jaz(i, i + 1);
- assert(length === 1);
- assert(a === i+1);
- assert(b === undefined);
-
- [length, a, b] = jaz(i, i+1, i+2);
- assert(length === 2);
- assert(a === i+1);
- assert(b === i+2);
-
- let o = {oooo:20};
- [length, a, b] = jaz(i, i+1, o);
- assert(length === 2);
- assert(a === i+1);
- assert(b === o);
- }
-
- shouldExit = true;
- for (let i = 0; i < 400; i++) {
- check(i);
- }
-
- shouldExit = false;
- for (let i = 0; i < iterations; i++) {
- check(i);
- }
-
- shouldExit = false;
- check(10);
-}
-
-function test10() {
- function baz(a, b, c, ...args) {
- return [args.length, args[0], args[1], args[2], args[3]];
- }
- function jaz(a, b, c, d, e, f) {
- return baz(a, b, c, d, e, f);
- }
- noInline(jaz);
-
- for (let i = 0; i < iterations; i++) {
- let [length, a, b, c, d] = jaz(1, 2, 3, 4, 5, 6);
- assert(length === 3);
- assert(a === 4);
- assert(b === 5);
- assert(c === 6);
- assert(d === undefined);
- }
-}
-
-function test11() {
- function bar(...args) {
- return args;
- }
- noInline(bar);
-
- function foo(a, b, c, d, ...args) {
- return bar.apply(null, args);
- }
- noInline(foo);
-
- function makeArguments(args) {
- return [1,2,3,4, ...args];
- }
- for (let i = 0; i < iterations; i++) {
- function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
- let a = [{}, 25, 50];
- test();
-
- a = [];
- test();
-
- a = [{foo: 20}];
- test();
-
- a = [10, 20, 30, 40, 50, 60, 70, 80];
- test();
- }
-}
-
-function test12() {
- "use strict";
- let thisValue = {};
- function getThisValue() { return thisValue; }
- noInline(getThisValue);
-
- function bar(...args) {
- assert(this === thisValue);
- return args;
- }
- noInline(bar);
-
- function foo(a, b, c, d, ...args) {
- return bar.apply(getThisValue(), args);
- }
- noInline(foo);
-
- function makeArguments(args) {
- return [1,2,3,4, ...args];
- }
- for (let i = 0; i < iterations; i++) {
- function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
- let a = [{}, 25, 50];
- test();
-
- a = [];
- test();
-
- a = [{foo: 20}];
- test();
-
- a = [10, 20, 30, 40, 50, 60, 70, 80];
- test();
- }
-}
-
-function test13() {
- "use strict";
- function bar(...args) {
- return args;
- }
- noInline(bar);
-
- function top(a, b, c, d, ...args) {
- return bar.apply(null, args);
- }
- function foo(...args) {
- let r = top.apply(null, args);
- return r;
- }
- noInline(foo);
-
- function makeArguments(args) {
- return [1,2,3,4, ...args];
- }
- for (let i = 0; i < iterations; i++) {
- function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
- let a = [{}, 25, 50];
- test();
-
- a = [];
- test();
-
- a = [10, 20, 30, 40, 50, 60, 70, 80];
- test();
- }
-}
-
-function test14() {
- "use strict";
- function bar(...args) {
- return args;
- }
- noInline(bar);
-
- function top(a, b, c, d, ...args) {
- return bar.apply(null, args);
- }
- function foo(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) {
- return top(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17);
- }
- noInline(foo);
-
- function makeArguments(args) {
- let r = [1,2,3,4, ...args];
- while (r.length < foo.length)
- r.push(undefined);
- return r;
- }
- for (let i = 0; i < iterations; i++) {
- function test()
- {
- let args = makeArguments(a);
- assert(shallowEq(args.slice(4), foo.apply(null, args)));
- }
-
- let a = [{}, 25, 50];
- test();
-
- a = [];
- test();
-
- a = [10, 20, 30, 40, 50, 60, 70, 80];
- test();
- }
-}
-
-function test15() {
- "use strict";
- function bar(...args) {
- return args;
- }
- noInline(bar);
-
- function top(a, b, c, d, ...args) {
- return bar.apply(null, args);
- }
- function foo(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) {
- let r = top(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17);
- return r;
- }
- noInline(foo);
-
- function makeArguments(args) {
- let r = [1,2,3,4, ...args];
- while (r.length < foo.length)
- r.push(undefined);
- return r;
- }
- for (let i = 0; i < iterations; i++) {
- function test()
- {
- let args = makeArguments(a);
- assert(shallowEq(args.slice(4), foo.apply(null, args)));
- }
-
- let a = [{}, 25, 50];
- test();
-
- a = [];
- test();
-
- a = [10, 20, 30, 40, 50, 60, 70, 80];
- test();
- }
-}
-
-let start = Date.now();
-test1();
-test2();
-test3();
-test4();
-test5();
-test6();
-test7();
-test8();
-test9();
-test10();
-test11();
-test12();
-test13();
-test14();
-test15();
-const verbose = false;
-if (verbose)
- print(Date.now() - start);
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-11-01 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r208208 and r208210.
+ https://bugs.webkit.org/show_bug.cgi?id=164276
+
+ This change caused 28 JSC test failures. (Requested by
+ ryanhaddad on #webkit).
+
+ Reverted changesets:
+
+ "We should be able to eliminate rest parameter allocations"
+ https://bugs.webkit.org/show_bug.cgi?id=163925
+ http://trac.webkit.org/changeset/208208
+
+ "Fix the EFL build."
+ http://trac.webkit.org/changeset/208210
+
</ins><span class="cx"> 2016-11-01 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Add the support for custom elements
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -2360,13 +2360,6 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case op_create_rest: {
- int numberOfArgumentsToSkip = instructions[i + 3].u.operand;
- ASSERT_UNUSED(numberOfArgumentsToSkip, numberOfArgumentsToSkip >= 0);
- ASSERT_WITH_MESSAGE(numberOfArgumentsToSkip == numParameters() - 1, "We assume that this is true when rematerializing the rest parameter during OSR exit in the FTL JIT.");
- break;
- }
-
</del><span class="cx"> default:
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1665,17 +1665,16 @@
</span><span class="cx"> // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
</span><span class="cx"> // paths as unreachable, or to return undefined. We could implement that eventually.
</span><span class="cx">
</span><del>- unsigned argumentIndex = index.asUInt32() + node->numberOfArgumentsToSkip();
</del><span class="cx"> if (inlineCallFrame) {
</span><del>- if (argumentIndex < inlineCallFrame->arguments.size() - 1) {
</del><ins>+ if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
</ins><span class="cx"> forNode(node) = m_state.variables().operand(
</span><del>- virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset);
</del><ins>+ virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
</ins><span class="cx"> m_state.setFoundConstants(true);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> } else {
</span><del>- if (argumentIndex < m_state.variables().numberOfArguments() - 1) {
- forNode(node) = m_state.variables().argument(argumentIndex + 1);
</del><ins>+ if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
+ forNode(node) = m_state.variables().argument(index.asInt32() + 1);
</ins><span class="cx"> m_state.setFoundConstants(true);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -1686,7 +1685,7 @@
</span><span class="cx"> // We have a bound on the types even though it's random access. Take advantage of this.
</span><span class="cx">
</span><span class="cx"> AbstractValue result;
</span><del>- for (unsigned i = 1 + node->numberOfArgumentsToSkip(); i < inlineCallFrame->arguments.size(); ++i) {
</del><ins>+ for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
</ins><span class="cx"> result.merge(
</span><span class="cx"> m_state.variables().operand(
</span><span class="cx"> virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
</span><span class="lines">@@ -1951,7 +1950,6 @@
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><span class="cx"> case PhantomClonedArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case BottomValue:
</span><span class="cx"> m_state.setDidClobber(true); // Prevent constant folding.
</span><span class="cx"> // This claims to return bottom.
</span><span class="lines">@@ -2867,15 +2865,9 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case CreateRest:
</span><del>- if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
- // This means we're already having a bad time.
</del><ins>+ if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) // This means we're already having a bad time.
</ins><span class="cx"> clobberWorld(node->origin.semantic, clobberLimit);
</span><del>- forNode(node).setType(m_graph, SpecArray);
- break;
- }
- forNode(node).set(
- m_graph,
- m_graph.globalObjectFor(node->origin.semantic)->restParameterStructure());
</del><ins>+ forNode(node).setType(m_graph, SpecArray);
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Check: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -97,17 +97,6 @@
</span><span class="cx"> case CreateClonedArguments:
</span><span class="cx"> m_candidates.add(node);
</span><span class="cx"> break;
</span><del>-
- case CreateRest:
- if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
- // If we're watching the HavingABadTime watchpoint it means that we will be invalidated
- // when it fires (it may or may not have actually fired yet). We don't try to eliminate
- // this allocation when we're not watching the watchpoint because it could entail calling
- // indexed accessors (and probably more crazy things) on out of bound accesses to the
- // rest parameter. It's also much easier to reason about this way.
- m_candidates.add(node);
- }
- break;
</del><span class="cx">
</span><span class="cx"> case CreateScopedArguments:
</span><span class="cx"> // FIXME: We could handle this if it wasn't for the fact that scoped arguments are
</span><span class="lines">@@ -145,7 +134,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Array::Contiguous: {
</span><del>- if (edge->op() != CreateClonedArguments && edge->op() != CreateRest) {
</del><ins>+ if (edge->op() != CreateClonedArguments) {
</ins><span class="cx"> escape(edge, source);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -233,32 +222,6 @@
</span><span class="cx"> escapeBasedOnArrayMode(node->arrayMode(), node->child1(), node);
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case CheckStructure: {
- if (!m_candidates.contains(node->child1().node()))
- break;
-
- Structure* structure = nullptr;
- JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1().node()->origin.semantic);
- switch (node->child1().node()->op()) {
- case CreateDirectArguments:
- structure = globalObject->directArgumentsStructure();
- break;
- case CreateClonedArguments:
- structure = globalObject->clonedArgumentsStructure();
- break;
- case CreateRest:
- ASSERT(m_graph.isWatchingHavingABadTimeWatchpoint(node));
- structure = globalObject->restParameterStructure();
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- ASSERT(structure);
-
- if (!node->structureSet().contains(structure))
- escape(node->child1(), node);
- break;
- }
</del><span class="cx">
</span><span class="cx"> // FIXME: We should be able to handle GetById/GetByOffset on callee.
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=143075
</span><span class="lines">@@ -432,7 +395,7 @@
</span><span class="cx"> {
</span><span class="cx"> InsertionSet insertionSet(m_graph);
</span><span class="cx">
</span><del>- for (BasicBlock* block : m_graph.blocksInPreOrder()) {
</del><ins>+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
</ins><span class="cx"> for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
</span><span class="cx"> Node* node = block->at(nodeIndex);
</span><span class="cx">
</span><span class="lines">@@ -440,16 +403,6 @@
</span><span class="cx"> return emitCodeToGetArgumentsArrayLength(
</span><span class="cx"> insertionSet, candidate, nodeIndex, node->origin);
</span><span class="cx"> };
</span><del>-
- auto isEliminatedAllocation = [&] (Node* candidate) -> bool {
- if (!m_candidates.contains(candidate))
- return false;
- // We traverse in such a way that we are guaranteed to see a def before a use.
- // Therefore, we should have already transformed the allocation before the use
- // of an allocation.
- ASSERT(candidate->op() == PhantomCreateRest || candidate->op() == PhantomDirectArguments || candidate->op() == PhantomClonedArguments);
- return true;
- };
</del><span class="cx">
</span><span class="cx"> switch (node->op()) {
</span><span class="cx"> case CreateDirectArguments:
</span><span class="lines">@@ -458,16 +411,6 @@
</span><span class="cx">
</span><span class="cx"> node->setOpAndDefaultFlags(PhantomDirectArguments);
</span><span class="cx"> break;
</span><del>-
- case CreateRest:
- if (!m_candidates.contains(node))
- break;
-
- node->setOpAndDefaultFlags(PhantomCreateRest);
- // We don't need this parameter for OSR exit, we can find out all the information
- // we need via the static parameter count and the dynamic argument count.
- node->child1() = Edge();
- break;
</del><span class="cx">
</span><span class="cx"> case CreateClonedArguments:
</span><span class="cx"> if (!m_candidates.contains(node))
</span><span class="lines">@@ -478,11 +421,13 @@
</span><span class="cx">
</span><span class="cx"> case GetFromArguments: {
</span><span class="cx"> Node* candidate = node->child1().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> DFG_ASSERT(
</span><del>- m_graph, node, node->child1()->op() == PhantomDirectArguments);
</del><ins>+ m_graph, node,
+ node->child1()->op() == CreateDirectArguments
+ || node->child1()->op() == PhantomDirectArguments);
</ins><span class="cx"> VirtualRegister reg =
</span><span class="cx"> virtualRegisterForArgument(node->capturedArgumentsOffset().offset() + 1) +
</span><span class="cx"> node->origin.semantic.stackOffset();
</span><span class="lines">@@ -493,10 +438,10 @@
</span><span class="cx">
</span><span class="cx"> case GetByOffset: {
</span><span class="cx"> Node* candidate = node->child2().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- if (node->child2()->op() != PhantomClonedArguments)
</del><ins>+ if (node->child2()->op() != PhantomClonedArguments && node->child2()->op() != CreateClonedArguments)
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> ASSERT(node->storageAccessData().offset == clonedArgumentsLengthPropertyOffset);
</span><span class="lines">@@ -509,7 +454,7 @@
</span><span class="cx">
</span><span class="cx"> case GetArrayLength: {
</span><span class="cx"> Node* candidate = node->child1().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> // Meh, this is kind of hackish - we use an Identity so that we can reuse the
</span><span class="lines">@@ -527,18 +472,13 @@
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=143076
</span><span class="cx">
</span><span class="cx"> Node* candidate = node->child1().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><del>-
- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
</del><span class="cx">
</span><span class="cx"> Node* result = nullptr;
</span><span class="cx"> if (node->child2()->isInt32Constant()) {
</span><span class="cx"> unsigned index = node->child2()->asUInt32();
</span><span class="cx"> InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
</span><del>- index += numberOfArgumentsToSkip;
</del><span class="cx">
</span><span class="cx"> bool safeToGetStack;
</span><span class="cx"> if (inlineCallFrame)
</span><span class="lines">@@ -572,10 +512,10 @@
</span><span class="cx"> else
</span><span class="cx"> op = GetMyArgumentByValOutOfBounds;
</span><span class="cx"> result = insertionSet.insertNode(
</span><del>- nodeIndex, node->prediction(), op, node->origin, OpInfo(numberOfArgumentsToSkip),
</del><ins>+ nodeIndex, node->prediction(), op, node->origin,
</ins><span class="cx"> node->child1(), node->child2());
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> // Need to do this because we may have a data format conversion here.
</span><span class="cx"> node->convertToIdentityOn(result);
</span><span class="cx"> break;
</span><span class="lines">@@ -583,95 +523,83 @@
</span><span class="cx">
</span><span class="cx"> case LoadVarargs: {
</span><span class="cx"> Node* candidate = node->child1().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> LoadVarargsData* varargsData = node->loadVarargsData();
</span><del>- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
- varargsData->offset += numberOfArgumentsToSkip;
-
</del><span class="cx"> InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
</span><del>-
</del><span class="cx"> if (inlineCallFrame
</span><del>- && !inlineCallFrame->isVarargs()) {
-
- unsigned argumentCountIncludingThis = inlineCallFrame->arguments.size();
- if (argumentCountIncludingThis > varargsData->offset)
- argumentCountIncludingThis -= varargsData->offset;
- else
- argumentCountIncludingThis = 1;
- RELEASE_ASSERT(argumentCountIncludingThis >= 1);
-
- if (argumentCountIncludingThis <= varargsData->limit) {
- // LoadVarargs can exit, so it better be exitOK.
- DFG_ASSERT(m_graph, node, node->origin.exitOK);
- bool canExit = true;
</del><ins>+ && !inlineCallFrame->isVarargs()
+ && inlineCallFrame->arguments.size() - varargsData->offset <= varargsData->limit) {
+
+ // LoadVarargs can exit, so it better be exitOK.
+ DFG_ASSERT(m_graph, node, node->origin.exitOK);
+ bool canExit = true;
+
+ Node* argumentCount = insertionSet.insertConstant(
+ nodeIndex, node->origin.withExitOK(canExit),
+ jsNumber(inlineCallFrame->arguments.size() - varargsData->offset));
+ insertionSet.insertNode(
+ nodeIndex, SpecNone, MovHint, node->origin.takeValidExit(canExit),
+ OpInfo(varargsData->count.offset()), Edge(argumentCount));
+ insertionSet.insertNode(
+ nodeIndex, SpecNone, PutStack, node->origin.withExitOK(canExit),
+ OpInfo(m_graph.m_stackAccessData.add(varargsData->count, FlushedInt32)),
+ Edge(argumentCount, KnownInt32Use));
+
+ DFG_ASSERT(m_graph, node, varargsData->limit - 1 >= varargsData->mandatoryMinimum);
+ // Define our limit to not include "this", since that's a bit easier to reason about.
+ unsigned limit = varargsData->limit - 1;
+ Node* undefined = nullptr;
+ for (unsigned storeIndex = 0; storeIndex < limit; ++storeIndex) {
+ // First determine if we have an element we can load, and load it if
+ // possible.
</ins><span class="cx">
</span><del>- Node* argumentCountIncludingThisNode = insertionSet.insertConstant(
- nodeIndex, node->origin.withExitOK(canExit),
- jsNumber(argumentCountIncludingThis));
- insertionSet.insertNode(
- nodeIndex, SpecNone, MovHint, node->origin.takeValidExit(canExit),
- OpInfo(varargsData->count.offset()), Edge(argumentCountIncludingThisNode));
- insertionSet.insertNode(
- nodeIndex, SpecNone, PutStack, node->origin.withExitOK(canExit),
- OpInfo(m_graph.m_stackAccessData.add(varargsData->count, FlushedInt32)),
- Edge(argumentCountIncludingThisNode, KnownInt32Use));
</del><ins>+ unsigned loadIndex = storeIndex + varargsData->offset;
</ins><span class="cx">
</span><del>- DFG_ASSERT(m_graph, node, varargsData->limit - 1 >= varargsData->mandatoryMinimum);
- // Define our limit to exclude "this", since that's a bit easier to reason about.
- unsigned limit = varargsData->limit - 1;
- Node* undefined = nullptr;
- for (unsigned storeIndex = 0; storeIndex < limit; ++storeIndex) {
- // First determine if we have an element we can load, and load it if
- // possible.
</del><ins>+ Node* value;
+ if (loadIndex + 1 < inlineCallFrame->arguments.size()) {
+ VirtualRegister reg =
+ virtualRegisterForArgument(loadIndex + 1) +
+ inlineCallFrame->stackOffset;
+ StackAccessData* data = m_graph.m_stackAccessData.add(
+ reg, FlushedJSValue);
</ins><span class="cx">
</span><del>- unsigned loadIndex = storeIndex + varargsData->offset;
</del><ins>+ value = insertionSet.insertNode(
+ nodeIndex, SpecNone, GetStack, node->origin.withExitOK(canExit),
+ OpInfo(data));
+ } else {
+ // FIXME: We shouldn't have to store anything if
+ // storeIndex >= varargsData->mandatoryMinimum, but we will still
+ // have GetStacks in that range. So if we don't do the stores, we'll
+ // have degenerate IR: we'll have GetStacks of something that didn't
+ // have PutStacks.
+ // https://bugs.webkit.org/show_bug.cgi?id=147434
</ins><span class="cx">
</span><del>- Node* value;
- if (loadIndex + 1 < inlineCallFrame->arguments.size()) {
- VirtualRegister reg = virtualRegisterForArgument(loadIndex + 1) + inlineCallFrame->stackOffset;
- StackAccessData* data = m_graph.m_stackAccessData.add(
- reg, FlushedJSValue);
-
- value = insertionSet.insertNode(
- nodeIndex, SpecNone, GetStack, node->origin.withExitOK(canExit),
- OpInfo(data));
- } else {
- // FIXME: We shouldn't have to store anything if
- // storeIndex >= varargsData->mandatoryMinimum, but we will still
- // have GetStacks in that range. So if we don't do the stores, we'll
- // have degenerate IR: we'll have GetStacks of something that didn't
- // have PutStacks.
- // https://bugs.webkit.org/show_bug.cgi?id=147434
-
- if (!undefined) {
- undefined = insertionSet.insertConstant(
- nodeIndex, node->origin.withExitOK(canExit), jsUndefined());
- }
- value = undefined;
</del><ins>+ if (!undefined) {
+ undefined = insertionSet.insertConstant(
+ nodeIndex, node->origin.withExitOK(canExit), jsUndefined());
</ins><span class="cx"> }
</span><del>-
- // Now that we have a value, store it.
-
- VirtualRegister reg = varargsData->start + storeIndex;
- StackAccessData* data =
- m_graph.m_stackAccessData.add(reg, FlushedJSValue);
-
- insertionSet.insertNode(
- nodeIndex, SpecNone, MovHint, node->origin.takeValidExit(canExit),
- OpInfo(reg.offset()), Edge(value));
- insertionSet.insertNode(
- nodeIndex, SpecNone, PutStack, node->origin.withExitOK(canExit),
- OpInfo(data), Edge(value));
</del><ins>+ value = undefined;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- node->remove();
- node->origin.exitOK = canExit;
- break;
</del><ins>+ // Now that we have a value, store it.
+
+ VirtualRegister reg = varargsData->start + storeIndex;
+ StackAccessData* data =
+ m_graph.m_stackAccessData.add(reg, FlushedJSValue);
+
+ insertionSet.insertNode(
+ nodeIndex, SpecNone, MovHint, node->origin.takeValidExit(canExit),
+ OpInfo(reg.offset()), Edge(value));
+ insertionSet.insertNode(
+ nodeIndex, SpecNone, PutStack, node->origin.withExitOK(canExit),
+ OpInfo(data), Edge(value));
</ins><span class="cx"> }
</span><ins>+
+ node->remove();
+ node->origin.exitOK = canExit;
+ break;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> node->setOpAndDefaultFlags(ForwardVarargs);
</span><span class="lines">@@ -683,15 +611,10 @@
</span><span class="cx"> case TailCallVarargs:
</span><span class="cx"> case TailCallVarargsInlinedCaller: {
</span><span class="cx"> Node* candidate = node->child3().node();
</span><del>- if (!isEliminatedAllocation(candidate))
</del><ins>+ if (!m_candidates.contains(candidate))
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
</del><span class="cx"> CallVarargsData* varargsData = node->callVarargsData();
</span><del>- varargsData->firstVarArgOffset += numberOfArgumentsToSkip;
-
</del><span class="cx"> InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
</span><span class="cx"> if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
</span><span class="cx"> Vector<Node*> arguments;
</span><span class="lines">@@ -754,18 +677,11 @@
</span><span class="cx">
</span><span class="cx"> case CheckArray:
</span><span class="cx"> case GetButterfly: {
</span><del>- if (!isEliminatedAllocation(node->child1().node()))
</del><ins>+ if (!m_candidates.contains(node->child1().node()))
</ins><span class="cx"> break;
</span><span class="cx"> node->remove();
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case CheckStructure:
- if (!isEliminatedAllocation(node->child1().node()))
- break;
- node->child1() = Edge(); // Remove the cell check since we've proven it's not needed and FTL lowering might botch this.
- node->remove();
- break;
</del><span class="cx">
</span><span class="cx"> default:
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArgumentsUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -64,23 +64,14 @@
</span><span class="cx"> DFG_ASSERT(
</span><span class="cx"> graph, arguments,
</span><span class="cx"> arguments->op() == CreateDirectArguments || arguments->op() == CreateScopedArguments
</span><del>- || arguments->op() == CreateClonedArguments || arguments->op() == CreateRest
- || arguments->op() == PhantomDirectArguments || arguments->op() == PhantomClonedArguments || arguments->op() == PhantomCreateRest);
</del><ins>+ || arguments->op() == CreateClonedArguments || arguments->op() == PhantomDirectArguments
+ || arguments->op() == PhantomClonedArguments);
</ins><span class="cx">
</span><span class="cx"> InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
</span><del>-
- unsigned numberOfArgumentsToSkip = 0;
- if (arguments->op() == CreateRest || arguments->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = arguments->numberOfArgumentsToSkip();
</del><span class="cx">
</span><span class="cx"> if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
</span><del>- unsigned argumentsSize = inlineCallFrame->arguments.size() - 1;
- if (argumentsSize >= numberOfArgumentsToSkip)
- argumentsSize -= numberOfArgumentsToSkip;
- else
- argumentsSize = 0;
</del><span class="cx"> return insertionSet.insertConstant(
</span><del>- nodeIndex, origin, jsNumber(argumentsSize));
</del><ins>+ nodeIndex, origin, jsNumber(inlineCallFrame->arguments.size() - 1));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Node* argumentCount;
</span><span class="lines">@@ -93,23 +84,12 @@
</span><span class="cx"> nodeIndex, SpecInt32Only, GetStack, origin,
</span><span class="cx"> OpInfo(graph.m_stackAccessData.add(argumentCountRegister, FlushedInt32)));
</span><span class="cx"> }
</span><del>-
- Node* result = insertionSet.insertNode(
</del><ins>+
+ return insertionSet.insertNode(
</ins><span class="cx"> nodeIndex, SpecInt32Only, ArithSub, origin, OpInfo(Arith::Unchecked),
</span><span class="cx"> Edge(argumentCount, Int32Use),
</span><span class="cx"> insertionSet.insertConstantForUse(
</span><del>- nodeIndex, origin, jsNumber(1 + numberOfArgumentsToSkip), Int32Use));
-
- if (numberOfArgumentsToSkip) {
- // The above subtraction may produce a negative number if this number is non-zero. We correct that here.
- result = insertionSet.insertNode(
- nodeIndex, SpecInt32Only, ArithMax, origin,
- Edge(result, Int32Use),
- insertionSet.insertConstantForUse(nodeIndex, origin, jsNumber(0), Int32Use));
- result->setResult(NodeResultInt32);
- }
-
- return result;
</del><ins>+ nodeIndex, origin, jsNumber(1), Int32Use));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -477,12 +477,6 @@
</span><span class="cx"> write(HeapObjectCount);
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- case PhantomCreateRest:
- // Even though it's phantom, it still has the property that one can't be replaced with another.
- read(HeapObjectCount);
- write(HeapObjectCount);
- return;
-
</del><span class="cx"> case CallObjectConstructor:
</span><span class="cx"> case ToThis:
</span><span class="cx"> case CreateThis:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -314,11 +314,9 @@
</span><span class="cx">
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds: {
</span><del>- JSValue indexValue = m_state.forNode(node->child2()).value();
- if (!indexValue || !indexValue.isInt32())
</del><ins>+ JSValue index = m_state.forNode(node->child2()).value();
+ if (!index || !index.isInt32())
</ins><span class="cx"> break;
</span><del>-
- unsigned index = indexValue.asUInt32() + node->numberOfArgumentsToSkip();
</del><span class="cx">
</span><span class="cx"> Node* arguments = node->child1().node();
</span><span class="cx"> InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
</span><span class="lines">@@ -337,10 +335,10 @@
</span><span class="cx"> // GetMyArgumentByVal in such statically-out-of-bounds accesses; we just lose CFA unless
</span><span class="cx"> // GCSE removes the access entirely.
</span><span class="cx"> if (inlineCallFrame) {
</span><del>- if (index >= inlineCallFrame->arguments.size() - 1)
</del><ins>+ if (index.asUInt32() >= inlineCallFrame->arguments.size() - 1)
</ins><span class="cx"> break;
</span><span class="cx"> } else {
</span><del>- if (index >= m_state.variables().numberOfArguments() - 1)
</del><ins>+ if (index.asUInt32() >= m_state.variables().numberOfArguments() - 1)
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -351,14 +349,15 @@
</span><span class="cx"> data = m_graph.m_stackAccessData.add(
</span><span class="cx"> VirtualRegister(
</span><span class="cx"> inlineCallFrame->stackOffset +
</span><del>- CallFrame::argumentOffset(index)),
</del><ins>+ CallFrame::argumentOffset(index.asInt32())),
</ins><span class="cx"> FlushedJSValue);
</span><span class="cx"> } else {
</span><span class="cx"> data = m_graph.m_stackAccessData.add(
</span><del>- virtualRegisterForArgument(index + 1), FlushedJSValue);
</del><ins>+ virtualRegisterForArgument(index.asInt32() + 1), FlushedJSValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (inlineCallFrame && !inlineCallFrame->isVarargs() && index < inlineCallFrame->arguments.size() - 1) {
</del><ins>+ if (inlineCallFrame && !inlineCallFrame->isVarargs()
+ && index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
</ins><span class="cx"> node->convertToGetStack(data);
</span><span class="cx"> eliminated = true;
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -246,7 +246,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1399,7 +1399,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -458,7 +458,6 @@
</span><span class="cx">
</span><span class="cx"> case PhantomDirectArguments:
</span><span class="cx"> case PhantomClonedArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> // These pretend to be the empty value constant for the benefit of the DFG backend, which
</span><span class="cx"> // otherwise wouldn't take kindly to a node that doesn't compute a value.
</span><span class="cx"> return true;
</span><span class="lines">@@ -472,7 +471,7 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(hasConstant());
</span><span class="cx">
</span><del>- if (op() == PhantomDirectArguments || op() == PhantomClonedArguments || op() == PhantomCreateRest) {
</del><ins>+ if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
</ins><span class="cx"> // These pretend to be the empty value constant for the benefit of the DFG backend, which
</span><span class="cx"> // otherwise wouldn't take kindly to a node that doesn't compute a value.
</span><span class="cx"> return FrozenValue::emptySingleton();
</span><span class="lines">@@ -1746,7 +1745,6 @@
</span><span class="cx"> switch (op()) {
</span><span class="cx"> case PhantomNewObject:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case PhantomNewFunction:
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="lines">@@ -2390,7 +2388,7 @@
</span><span class="cx">
</span><span class="cx"> unsigned numberOfArgumentsToSkip()
</span><span class="cx"> {
</span><del>- ASSERT(op() == CreateRest || op() == GetRestLength || op() == GetMyArgumentByVal || op() == GetMyArgumentByValOutOfBounds);
</del><ins>+ ASSERT(op() == CreateRest || op() == GetRestLength);
</ins><span class="cx"> return m_opInfo.as<unsigned>();
</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 (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -342,7 +342,6 @@
</span><span class="cx"> \
</span><span class="cx"> macro(CreateDirectArguments, NodeResultJS) \
</span><span class="cx"> macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
</span><del>- macro(PhantomCreateRest, NodeResultJS | NodeMustGenerate) \
</del><span class="cx"> macro(CreateScopedArguments, NodeResultJS) \
</span><span class="cx"> macro(CreateClonedArguments, NodeResultJS) \
</span><span class="cx"> macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -165,7 +165,6 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomDirectArguments:
</span><span class="cx"> case PhantomClonedArguments: {
</span><span class="cx"> InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
</span><span class="lines">@@ -174,10 +173,6 @@
</span><span class="cx"> // given that we can read them from the stack.
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- unsigned numberOfArgumentsToSkip = 0;
- if (node->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = node->numberOfArgumentsToSkip();
</del><span class="cx">
</span><span class="cx"> if (inlineCallFrame->isVarargs()) {
</span><span class="cx"> // Record how to read each argument and the argument count.
</span><span class="lines">@@ -193,7 +188,7 @@
</span><span class="cx"> m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- for (unsigned i = numberOfArgumentsToSkip; i < inlineCallFrame->arguments.size() - 1; ++i) {
</del><ins>+ for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
</ins><span class="cx"> Availability argument = m_availability.m_locals.operand(
</span><span class="cx"> inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1358,7 +1358,7 @@
</span><span class="cx"> NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx">
</span><span class="cx"> JSGlobalObject* globalObject = exec->lexicalGlobalObject();
</span><del>- Structure* structure = globalObject->restParameterStructure();
</del><ins>+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
</ins><span class="cx"> static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
</span><span class="cx"> JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
</span><span class="cx"> return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -120,24 +120,15 @@
</span><span class="cx"> inlineCallFrame = m_node->argumentsChild()->origin.semantic.inlineCallFrame;
</span><span class="cx"> else
</span><span class="cx"> inlineCallFrame = m_node->origin.semantic.inlineCallFrame;
</span><del>-
- unsigned numberOfArgumentsToSkip = 0;
- if (m_node->op() == GetMyArgumentByVal || m_node->op() == GetMyArgumentByValOutOfBounds) {
- // The value of numberOfArgumentsToSkip guarantees that GetMyArgumentByVal* will never
- // read any arguments below the number of arguments to skip. For example, if numberOfArgumentsToSkip is 2,
- // we will never read argument 0 or argument 1.
- numberOfArgumentsToSkip = m_node->numberOfArgumentsToSkip();
- }
-
</del><span class="cx"> if (!inlineCallFrame) {
</span><span class="cx"> // Read the outermost arguments and argument count.
</span><del>- for (unsigned i = 1 + numberOfArgumentsToSkip; i < static_cast<unsigned>(m_graph.m_codeBlock->numParameters()); i++)
</del><ins>+ for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
</ins><span class="cx"> m_read(virtualRegisterForArgument(i));
</span><span class="cx"> m_read(VirtualRegister(CallFrameSlot::argumentCount));
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- for (unsigned i = 1 + numberOfArgumentsToSkip; i < inlineCallFrame->arguments.size(); i++)
</del><ins>+ for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
</ins><span class="cx"> m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
</span><span class="cx"> if (inlineCallFrame->isVarargs())
</span><span class="cx"> m_read(VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1004,7 +1004,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -354,7 +354,6 @@
</span><span class="cx"> case MaterializeNewObject:
</span><span class="cx"> case MaterializeCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -6852,7 +6852,6 @@
</span><span class="cx"> GPRReg arrayResultGPR = arrayResult.gpr();
</span><span class="cx">
</span><span class="cx"> bool shouldAllowForArrayStorageStructureForLargeArrays = false;
</span><del>- ASSERT(m_jit.graph().globalObjectFor(node->origin.semantic)->restParameterStructure()->indexingType() == ArrayWithContiguous);
</del><span class="cx"> compileAllocateNewArrayWithSize(m_jit.graph().globalObjectFor(node->origin.semantic), arrayResultGPR, arrayLengthGPR, ArrayWithContiguous, shouldAllowForArrayStorageStructureForLargeArrays);
</span><span class="cx">
</span><span class="cx"> GPRTemporary argumentsStart(this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -5601,7 +5601,6 @@
</span><span class="cx"> case GetStack:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -5818,7 +5818,6 @@
</span><span class="cx"> case PutStack:
</span><span class="cx"> case KillStack:
</span><span class="cx"> case GetStack:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> DFG_CRASH(m_jit.graph(), node, "Unexpected node");
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -118,14 +118,6 @@
</span><span class="cx"> registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case CreateRest: {
- if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
- JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
- registerStructure(globalObject->restParameterStructure());
- }
- break;
- }
</del><span class="cx">
</span><span class="cx"> case NewTypedArray:
</span><span class="cx"> registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(node->typedArrayType()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -670,7 +670,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case MovHint:
</span><span class="cx"> case Upsilon:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -230,7 +230,6 @@
</span><span class="cx"> case MaterializeNewObject:
</span><span class="cx"> case MaterializeCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case GetMyArgumentByVal:
</span><span class="cx"> case GetMyArgumentByValOutOfBounds:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -1074,7 +1074,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomCreateActivation:
</span><span class="cx"> case PhantomDirectArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> case PutHint:
</span><span class="cx"> case BottomValue:
</span><span class="lines">@@ -3435,8 +3434,6 @@
</span><span class="cx"> InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
</span><span class="cx">
</span><span class="cx"> LValue index = lowInt32(m_node->child2());
</span><del>- if (m_node->numberOfArgumentsToSkip())
- index = m_out.add(index, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
</del><span class="cx">
</span><span class="cx"> LValue limit;
</span><span class="cx"> if (inlineCallFrame && !inlineCallFrame->isVarargs())
</span><span class="lines">@@ -4160,7 +4157,7 @@
</span><span class="cx"> LValue arrayLength = lowInt32(m_node->child1());
</span><span class="cx"> LBasicBlock loopStart = m_out.newBlock();
</span><span class="cx"> JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
</span><del>- Structure* structure = globalObject->restParameterStructure();
</del><ins>+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
</ins><span class="cx"> ArrayValues arrayValues = allocateUninitializedContiguousJSArray(arrayLength, structure);
</span><span class="cx"> LValue array = arrayValues.array;
</span><span class="cx"> LValue butterfly = arrayValues.butterfly;
</span><span class="lines">@@ -6288,39 +6285,10 @@
</span><span class="cx"> inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
</span><span class="cx"> else
</span><span class="cx"> inlineCallFrame = m_node->origin.semantic.inlineCallFrame;
</span><del>-
- LValue length = nullptr;
- LValue lengthIncludingThis = nullptr;
- ArgumentsLength argumentsLength = getArgumentsLength(inlineCallFrame);
- if (argumentsLength.isKnown) {
- unsigned knownLength = argumentsLength.known;
- if (knownLength >= data->offset)
- knownLength = knownLength - data->offset;
- else
- knownLength = 0;
- length = m_out.constInt32(knownLength);
- lengthIncludingThis = m_out.constInt32(knownLength + 1);
- } else {
- // We need to perform the same logical operation as the code above, but through dynamic operations.
- if (!data->offset)
- length = argumentsLength.value;
- else {
- LBasicBlock isLarger = m_out.newBlock();
- LBasicBlock continuation = m_out.newBlock();
-
- ValueFromBlock smallerOrEqualLengthResult = m_out.anchor(m_out.constInt32(0));
- m_out.branch(
- m_out.above(argumentsLength.value, m_out.constInt32(data->offset)), unsure(isLarger), unsure(continuation));
- LBasicBlock lastNext = m_out.appendTo(isLarger, continuation);
- ValueFromBlock largerLengthResult = m_out.anchor(m_out.sub(argumentsLength.value, m_out.constInt32(data->offset)));
- m_out.jump(continuation);
-
- m_out.appendTo(continuation, lastNext);
- length = m_out.phi(Int32, smallerOrEqualLengthResult, largerLengthResult);
- }
- lengthIncludingThis = m_out.add(length, m_out.constInt32(1));
- }
-
</del><ins>+
+ LValue length = getArgumentsLength(inlineCallFrame).value;
+ LValue lengthIncludingThis = m_out.add(length, m_out.constInt32(1 - data->offset));
+
</ins><span class="cx"> speculate(
</span><span class="cx"> VarargsOverflow, noValue(), nullptr,
</span><span class="cx"> m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
</span><span class="lines">@@ -6327,8 +6295,7 @@
</span><span class="cx">
</span><span class="cx"> m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
</span><span class="cx">
</span><del>- unsigned numberOfArgumentsToSkip = data->offset;
- LValue sourceStart = getArgumentsStart(inlineCallFrame, numberOfArgumentsToSkip);
</del><ins>+ LValue sourceStart = getArgumentsStart(inlineCallFrame);
</ins><span class="cx"> LValue targetStart = addressFor(data->machineStart).value();
</span><span class="cx">
</span><span class="cx"> LBasicBlock undefinedLoop = m_out.newBlock();
</span><span class="lines">@@ -6361,7 +6328,9 @@
</span><span class="cx"> previousIndex = m_out.phi(pointerType(), loopBound);
</span><span class="cx"> currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
</span><span class="cx"> LValue value = m_out.load64(
</span><del>- m_out.baseIndex(m_heaps.variables, sourceStart, currentIndex));
</del><ins>+ m_out.baseIndex(
+ m_heaps.variables, sourceStart,
+ m_out.add(currentIndex, m_out.constIntPtr(data->offset))));
</ins><span class="cx"> m_out.store64(value, m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
</span><span class="cx"> nextIndex = m_out.anchor(currentIndex);
</span><span class="cx"> m_out.addIncomingToPhi(previousIndex, nextIndex);
</span><span class="lines">@@ -8407,9 +8376,9 @@
</span><span class="cx"> return m_out.loadPtr(addressFor(CallFrameSlot::callee));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- LValue getArgumentsStart(InlineCallFrame* inlineCallFrame, unsigned offset = 0)
</del><ins>+ LValue getArgumentsStart(InlineCallFrame* inlineCallFrame)
</ins><span class="cx"> {
</span><del>- VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame) + offset;
</del><ins>+ VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame);
</ins><span class="cx"> return addressFor(start).value();
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -83,7 +83,6 @@
</span><span class="cx"> case PhantomNewGeneratorFunction:
</span><span class="cx"> case PhantomDirectArguments:
</span><span class="cx"> case PhantomClonedArguments:
</span><del>- case PhantomCreateRest:
</del><span class="cx"> // Those are completely handled by operationMaterializeObjectInOSR
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -235,7 +234,6 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PhantomCreateRest:
</del><span class="cx"> case PhantomDirectArguments:
</span><span class="cx"> case PhantomClonedArguments: {
</span><span class="cx"> if (!materialization->origin().inlineCallFrame) {
</span><span class="lines">@@ -244,17 +242,6 @@
</span><span class="cx"> return DirectArguments::createByCopying(exec);
</span><span class="cx"> case PhantomClonedArguments:
</span><span class="cx"> return ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned);
</span><del>- case PhantomCreateRest: {
- CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(
- materialization->origin(), exec->codeBlock());
-
- unsigned numberOfArgumentsToSkip = codeBlock->numParameters() - 1;
- JSGlobalObject* globalObject = codeBlock->globalObject();
- Structure* structure = globalObject->restParameterStructure();
- JSValue* argumentsToCopyRegion = exec->addressOfArgumentsStart() + numberOfArgumentsToSkip;
- unsigned arraySize = exec->argumentCount() > numberOfArgumentsToSkip ? exec->argumentCount() - numberOfArgumentsToSkip : 0;
- return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
- }
</del><span class="cx"> default:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> return nullptr;
</span><span class="lines">@@ -268,12 +255,14 @@
</span><span class="cx"> const ExitPropertyValue& property = materialization->properties()[i];
</span><span class="cx"> if (property.location() != PromotedLocationDescriptor(ArgumentCountPLoc))
</span><span class="cx"> continue;
</span><ins>+
</ins><span class="cx"> argumentCount = JSValue::decode(values[i]).asUInt32();
</span><ins>+ RELEASE_ASSERT(argumentCount);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ RELEASE_ASSERT(argumentCount);
</ins><span class="cx"> } else
</span><span class="cx"> argumentCount = materialization->origin().inlineCallFrame->arguments.size();
</span><del>- RELEASE_ASSERT(argumentCount);
</del><span class="cx">
</span><span class="cx"> JSFunction* callee = nullptr;
</span><span class="cx"> if (materialization->origin().inlineCallFrame->isClosureCall) {
</span><span class="lines">@@ -341,56 +330,6 @@
</span><span class="cx">
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><del>- case PhantomCreateRest: {
- unsigned numberOfArgumentsToSkip = codeBlock->numParameters() - 1;
- JSGlobalObject* globalObject = codeBlock->globalObject();
- Structure* structure = globalObject->restParameterStructure();
- ASSERT(argumentCount > 0);
- unsigned arraySize = (argumentCount - 1) > numberOfArgumentsToSkip ? argumentCount - 1 - numberOfArgumentsToSkip : 0;
- JSArray* array = JSArray::tryCreateUninitialized(vm, structure, arraySize);
- RELEASE_ASSERT(array);
-
- for (unsigned i = materialization->properties().size(); i--;) {
- const ExitPropertyValue& property = materialization->properties()[i];
- if (property.location().kind() != ArgumentPLoc)
- continue;
-
- unsigned argIndex = property.location().info();
- if (numberOfArgumentsToSkip > argIndex)
- continue;
- unsigned arrayIndex = argIndex - numberOfArgumentsToSkip;
- if (arrayIndex >= arraySize)
- continue;
- array->initializeIndex(vm, arrayIndex, JSValue::decode(values[i]));
- }
-
- if (!ASSERT_DISABLED) {
- // We avoid this O(n^2) loop when asserts are disabled, but the condition checked here
- // must hold to ensure the correctness of the above loop because of how we allocate the array.
- for (unsigned targetIndex = 0; targetIndex < arraySize; ++targetIndex) {
- bool found = false;
- for (unsigned i = materialization->properties().size(); i--;) {
- const ExitPropertyValue& property = materialization->properties()[i];
- if (property.location().kind() != ArgumentPLoc)
- continue;
-
- unsigned argIndex = property.location().info();
- if (numberOfArgumentsToSkip > argIndex)
- continue;
- unsigned arrayIndex = argIndex - numberOfArgumentsToSkip;
- if (arrayIndex >= arraySize)
- continue;
- if (arrayIndex == targetIndex) {
- found = true;
- break;
- }
- }
- ASSERT_UNUSED(found, found);
- }
- }
-
- return array;
- }
</del><span class="cx"> default:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> return nullptr;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitSetupVarargsFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), resultGPR);
</span><span class="cx">
</span><span class="cx"> jit.addPtr(lengthGPR, resultGPR);
</span><del>- jit.addPtr(CCallHelpers::TrustedImm32(CallFrame::headerSizeInRegisters + (lengthIncludesThis ? 0 : 1)), resultGPR);
</del><ins>+ jit.addPtr(CCallHelpers::TrustedImm32(CallFrame::headerSizeInRegisters + (lengthIncludesThis? 0 : 1)), resultGPR);
</ins><span class="cx">
</span><span class="cx"> // resultGPR now has the required frame size in Register units
</span><span class="cx"> // Round resultGPR to next multiple of stackAlignmentRegisters()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -851,7 +851,7 @@
</span><span class="cx"> BEGIN();
</span><span class="cx"> unsigned arraySize = OP_C(2).jsValue().asUInt32();
</span><span class="cx"> JSGlobalObject* globalObject = exec->lexicalGlobalObject();
</span><del>- Structure* structure = globalObject->restParameterStructure();
</del><ins>+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
</ins><span class="cx"> unsigned numParamsToSkip = pc[3].u.unsignedValue;
</span><span class="cx"> JSValue* argumentsToCopyRegion = exec->addressOfArgumentsStart() + numParamsToSkip;
</span><span class="cx"> RETURN(constructArray(exec, structure, argumentsToCopyRegion, arraySize));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (208223 => 208224)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2016-11-01 17:20:25 UTC (rev 208224)
</span><span class="lines">@@ -623,7 +623,6 @@
</span><span class="cx"> Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(); }
</span><span class="cx"> Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); }
</span><span class="cx"> Structure* moduleLoaderStructure() const { return m_moduleLoaderStructure.get(); }
</span><del>- Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); }
</del><span class="cx">
</span><span class="cx"> JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
</span><span class="cx"> JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;
</span></span></pre>
</div>
</div>
</body>
</html>