Diff
Modified: trunk/JSTests/ChangeLog (208223 => 208224)
--- trunk/JSTests/ChangeLog 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/JSTests/ChangeLog 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1,3 +1,20 @@
+2016-11-01 Commit Queue <commit-qu...@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
+
2016-10-31 Filip Pizlo <fpi...@apple.com>
JSC should support SharedArrayBuffer
Deleted: trunk/JSTests/microbenchmarks/rest-parameter-allocation-elimination.js (208223 => 208224)
--- 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)
@@ -1,613 +0,0 @@
-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);
-
Modified: trunk/Source/_javascript_Core/ChangeLog (208223 => 208224)
--- trunk/Source/_javascript_Core/ChangeLog 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1,3 +1,20 @@
+2016-11-01 Commit Queue <commit-qu...@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
+
2016-11-01 Ryosuke Niwa <rn...@webkit.org>
Web Inspector: Add the support for custom elements
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -2360,13 +2360,6 @@
break;
}
- 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;
- }
-
default:
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1665,17 +1665,16 @@
// that's the conservative thing to do. Otherwise we'd need to write more code to mark such
// paths as unreachable, or to return undefined. We could implement that eventually.
- unsigned argumentIndex = index.asUInt32() + node->numberOfArgumentsToSkip();
if (inlineCallFrame) {
- if (argumentIndex < inlineCallFrame->arguments.size() - 1) {
+ if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
forNode(node) = m_state.variables().operand(
- virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset);
+ virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
m_state.setFoundConstants(true);
break;
}
} else {
- if (argumentIndex < m_state.variables().numberOfArguments() - 1) {
- forNode(node) = m_state.variables().argument(argumentIndex + 1);
+ if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
+ forNode(node) = m_state.variables().argument(index.asInt32() + 1);
m_state.setFoundConstants(true);
break;
}
@@ -1686,7 +1685,7 @@
// We have a bound on the types even though it's random access. Take advantage of this.
AbstractValue result;
- for (unsigned i = 1 + node->numberOfArgumentsToSkip(); i < inlineCallFrame->arguments.size(); ++i) {
+ for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
result.merge(
m_state.variables().operand(
virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
@@ -1951,7 +1950,6 @@
case PhantomCreateActivation:
case PhantomDirectArguments:
case PhantomClonedArguments:
- case PhantomCreateRest:
case BottomValue:
m_state.setDidClobber(true); // Prevent constant folding.
// This claims to return bottom.
@@ -2867,15 +2865,9 @@
break;
case CreateRest:
- if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
- // This means we're already having a bad time.
+ if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) // This means we're already having a bad time.
clobberWorld(node->origin.semantic, clobberLimit);
- forNode(node).setType(m_graph, SpecArray);
- break;
- }
- forNode(node).set(
- m_graph,
- m_graph.globalObjectFor(node->origin.semantic)->restParameterStructure());
+ forNode(node).setType(m_graph, SpecArray);
break;
case Check: {
Modified: trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGArgumentsEliminationPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -97,17 +97,6 @@
case CreateClonedArguments:
m_candidates.add(node);
break;
-
- 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;
case CreateScopedArguments:
// FIXME: We could handle this if it wasn't for the fact that scoped arguments are
@@ -145,7 +134,7 @@
break;
case Array::Contiguous: {
- if (edge->op() != CreateClonedArguments && edge->op() != CreateRest) {
+ if (edge->op() != CreateClonedArguments) {
escape(edge, source);
return;
}
@@ -233,32 +222,6 @@
escapeBasedOnArrayMode(node->arrayMode(), node->child1(), node);
break;
- 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;
- }
// FIXME: We should be able to handle GetById/GetByOffset on callee.
// https://bugs.webkit.org/show_bug.cgi?id=143075
@@ -432,7 +395,7 @@
{
InsertionSet insertionSet(m_graph);
- for (BasicBlock* block : m_graph.blocksInPreOrder()) {
+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
Node* node = block->at(nodeIndex);
@@ -440,16 +403,6 @@
return emitCodeToGetArgumentsArrayLength(
insertionSet, candidate, nodeIndex, node->origin);
};
-
- 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;
- };
switch (node->op()) {
case CreateDirectArguments:
@@ -458,16 +411,6 @@
node->setOpAndDefaultFlags(PhantomDirectArguments);
break;
-
- 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;
case CreateClonedArguments:
if (!m_candidates.contains(node))
@@ -478,11 +421,13 @@
case GetFromArguments: {
Node* candidate = node->child1().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
DFG_ASSERT(
- m_graph, node, node->child1()->op() == PhantomDirectArguments);
+ m_graph, node,
+ node->child1()->op() == CreateDirectArguments
+ || node->child1()->op() == PhantomDirectArguments);
VirtualRegister reg =
virtualRegisterForArgument(node->capturedArgumentsOffset().offset() + 1) +
node->origin.semantic.stackOffset();
@@ -493,10 +438,10 @@
case GetByOffset: {
Node* candidate = node->child2().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
- if (node->child2()->op() != PhantomClonedArguments)
+ if (node->child2()->op() != PhantomClonedArguments && node->child2()->op() != CreateClonedArguments)
break;
ASSERT(node->storageAccessData().offset == clonedArgumentsLengthPropertyOffset);
@@ -509,7 +454,7 @@
case GetArrayLength: {
Node* candidate = node->child1().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
// Meh, this is kind of hackish - we use an Identity so that we can reuse the
@@ -527,18 +472,13 @@
// https://bugs.webkit.org/show_bug.cgi?id=143076
Node* candidate = node->child1().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
-
- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
Node* result = nullptr;
if (node->child2()->isInt32Constant()) {
unsigned index = node->child2()->asUInt32();
InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
- index += numberOfArgumentsToSkip;
bool safeToGetStack;
if (inlineCallFrame)
@@ -572,10 +512,10 @@
else
op = GetMyArgumentByValOutOfBounds;
result = insertionSet.insertNode(
- nodeIndex, node->prediction(), op, node->origin, OpInfo(numberOfArgumentsToSkip),
+ nodeIndex, node->prediction(), op, node->origin,
node->child1(), node->child2());
}
-
+
// Need to do this because we may have a data format conversion here.
node->convertToIdentityOn(result);
break;
@@ -583,95 +523,83 @@
case LoadVarargs: {
Node* candidate = node->child1().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
LoadVarargsData* varargsData = node->loadVarargsData();
- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
- varargsData->offset += numberOfArgumentsToSkip;
-
InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
-
if (inlineCallFrame
- && !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;
+ && !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.
- 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));
+ unsigned loadIndex = storeIndex + varargsData->offset;
- 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.
+ Node* value;
+ if (loadIndex + 1 < inlineCallFrame->arguments.size()) {
+ VirtualRegister reg =
+ virtualRegisterForArgument(loadIndex + 1) +
+ inlineCallFrame->stackOffset;
+ StackAccessData* data = ""
+ reg, FlushedJSValue);
- unsigned loadIndex = storeIndex + varargsData->offset;
+ 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
- Node* value;
- if (loadIndex + 1 < inlineCallFrame->arguments.size()) {
- VirtualRegister reg = virtualRegisterForArgument(loadIndex + 1) + inlineCallFrame->stackOffset;
- StackAccessData* data = ""
- 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;
+ if (!undefined) {
+ undefined = insertionSet.insertConstant(
+ nodeIndex, node->origin.withExitOK(canExit), jsUndefined());
}
-
- // 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));
+ value = undefined;
}
- node->remove();
- node->origin.exitOK = canExit;
- break;
+ // 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));
}
+
+ node->remove();
+ node->origin.exitOK = canExit;
+ break;
}
node->setOpAndDefaultFlags(ForwardVarargs);
@@ -683,15 +611,10 @@
case TailCallVarargs:
case TailCallVarargsInlinedCaller: {
Node* candidate = node->child3().node();
- if (!isEliminatedAllocation(candidate))
+ if (!m_candidates.contains(candidate))
break;
- unsigned numberOfArgumentsToSkip = 0;
- if (candidate->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip();
CallVarargsData* varargsData = node->callVarargsData();
- varargsData->firstVarArgOffset += numberOfArgumentsToSkip;
-
InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
Vector<Node*> arguments;
@@ -754,18 +677,11 @@
case CheckArray:
case GetButterfly: {
- if (!isEliminatedAllocation(node->child1().node()))
+ if (!m_candidates.contains(node->child1().node()))
break;
node->remove();
break;
}
-
- 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;
default:
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGArgumentsUtilities.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGArgumentsUtilities.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGArgumentsUtilities.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -64,23 +64,14 @@
DFG_ASSERT(
graph, arguments,
arguments->op() == CreateDirectArguments || arguments->op() == CreateScopedArguments
- || arguments->op() == CreateClonedArguments || arguments->op() == CreateRest
- || arguments->op() == PhantomDirectArguments || arguments->op() == PhantomClonedArguments || arguments->op() == PhantomCreateRest);
+ || arguments->op() == CreateClonedArguments || arguments->op() == PhantomDirectArguments
+ || arguments->op() == PhantomClonedArguments);
InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
-
- unsigned numberOfArgumentsToSkip = 0;
- if (arguments->op() == CreateRest || arguments->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = arguments->numberOfArgumentsToSkip();
if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
- unsigned argumentsSize = inlineCallFrame->arguments.size() - 1;
- if (argumentsSize >= numberOfArgumentsToSkip)
- argumentsSize -= numberOfArgumentsToSkip;
- else
- argumentsSize = 0;
return insertionSet.insertConstant(
- nodeIndex, origin, jsNumber(argumentsSize));
+ nodeIndex, origin, jsNumber(inlineCallFrame->arguments.size() - 1));
}
Node* argumentCount;
@@ -93,23 +84,12 @@
nodeIndex, SpecInt32Only, GetStack, origin,
OpInfo(graph.m_stackAccessData.add(argumentCountRegister, FlushedInt32)));
}
-
- Node* result = insertionSet.insertNode(
+
+ return insertionSet.insertNode(
nodeIndex, SpecInt32Only, ArithSub, origin, OpInfo(Arith::Unchecked),
Edge(argumentCount, Int32Use),
insertionSet.insertConstantForUse(
- 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;
+ nodeIndex, origin, jsNumber(1), Int32Use));
}
} } // namespace JSC::DFG
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -477,12 +477,6 @@
write(HeapObjectCount);
return;
- 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;
-
case CallObjectConstructor:
case ToThis:
case CreateThis:
Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -314,11 +314,9 @@
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds: {
- JSValue indexValue = m_state.forNode(node->child2()).value();
- if (!indexValue || !indexValue.isInt32())
+ JSValue index = m_state.forNode(node->child2()).value();
+ if (!index || !index.isInt32())
break;
-
- unsigned index = indexValue.asUInt32() + node->numberOfArgumentsToSkip();
Node* arguments = node->child1().node();
InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
@@ -337,10 +335,10 @@
// GetMyArgumentByVal in such statically-out-of-bounds accesses; we just lose CFA unless
// GCSE removes the access entirely.
if (inlineCallFrame) {
- if (index >= inlineCallFrame->arguments.size() - 1)
+ if (index.asUInt32() >= inlineCallFrame->arguments.size() - 1)
break;
} else {
- if (index >= m_state.variables().numberOfArguments() - 1)
+ if (index.asUInt32() >= m_state.variables().numberOfArguments() - 1)
break;
}
@@ -351,14 +349,15 @@
data = ""
VirtualRegister(
inlineCallFrame->stackOffset +
- CallFrame::argumentOffset(index)),
+ CallFrame::argumentOffset(index.asInt32())),
FlushedJSValue);
} else {
data = ""
- virtualRegisterForArgument(index + 1), FlushedJSValue);
+ virtualRegisterForArgument(index.asInt32() + 1), FlushedJSValue);
}
- if (inlineCallFrame && !inlineCallFrame->isVarargs() && index < inlineCallFrame->arguments.size() - 1) {
+ if (inlineCallFrame && !inlineCallFrame->isVarargs()
+ && index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
node->convertToGetStack(data);
eliminated = true;
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -246,7 +246,6 @@
case PhantomNewGeneratorFunction:
case PhantomCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1399,7 +1399,6 @@
case PhantomNewGeneratorFunction:
case PhantomCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -458,7 +458,6 @@
case PhantomDirectArguments:
case PhantomClonedArguments:
- case PhantomCreateRest:
// These pretend to be the empty value constant for the benefit of the DFG backend, which
// otherwise wouldn't take kindly to a node that doesn't compute a value.
return true;
@@ -472,7 +471,7 @@
{
ASSERT(hasConstant());
- if (op() == PhantomDirectArguments || op() == PhantomClonedArguments || op() == PhantomCreateRest) {
+ if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
// These pretend to be the empty value constant for the benefit of the DFG backend, which
// otherwise wouldn't take kindly to a node that doesn't compute a value.
return FrozenValue::emptySingleton();
@@ -1746,7 +1745,6 @@
switch (op()) {
case PhantomNewObject:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case PhantomNewFunction:
case PhantomNewGeneratorFunction:
@@ -2390,7 +2388,7 @@
unsigned numberOfArgumentsToSkip()
{
- ASSERT(op() == CreateRest || op() == GetRestLength || op() == GetMyArgumentByVal || op() == GetMyArgumentByValOutOfBounds);
+ ASSERT(op() == CreateRest || op() == GetRestLength);
return m_opInfo.as<unsigned>();
}
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -342,7 +342,6 @@
\
macro(CreateDirectArguments, NodeResultJS) \
macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
- macro(PhantomCreateRest, NodeResultJS | NodeMustGenerate) \
macro(CreateScopedArguments, NodeResultJS) \
macro(CreateClonedArguments, NodeResultJS) \
macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGOSRAvailabilityAnalysisPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRAvailabilityAnalysisPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -165,7 +165,6 @@
break;
}
- case PhantomCreateRest:
case PhantomDirectArguments:
case PhantomClonedArguments: {
InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
@@ -174,10 +173,6 @@
// given that we can read them from the stack.
break;
}
-
- unsigned numberOfArgumentsToSkip = 0;
- if (node->op() == PhantomCreateRest)
- numberOfArgumentsToSkip = node->numberOfArgumentsToSkip();
if (inlineCallFrame->isVarargs()) {
// Record how to read each argument and the argument count.
@@ -193,7 +188,7 @@
m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
}
- for (unsigned i = numberOfArgumentsToSkip; i < inlineCallFrame->arguments.size() - 1; ++i) {
+ for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
Availability argument = m_availability.m_locals.operand(
inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1358,7 +1358,7 @@
NativeCallFrameTracer tracer(vm, exec);
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- Structure* structure = globalObject->restParameterStructure();
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
Modified: trunk/Source/_javascript_Core/dfg/DFGPreciseLocalClobberize.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGPreciseLocalClobberize.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGPreciseLocalClobberize.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -120,24 +120,15 @@
inlineCallFrame = m_node->argumentsChild()->origin.semantic.inlineCallFrame;
else
inlineCallFrame = m_node->origin.semantic.inlineCallFrame;
-
- 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();
- }
-
if (!inlineCallFrame) {
// Read the outermost arguments and argument count.
- for (unsigned i = 1 + numberOfArgumentsToSkip; i < static_cast<unsigned>(m_graph.m_codeBlock->numParameters()); i++)
+ for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
m_read(virtualRegisterForArgument(i));
m_read(VirtualRegister(CallFrameSlot::argumentCount));
break;
}
- for (unsigned i = 1 + numberOfArgumentsToSkip; i < inlineCallFrame->arguments.size(); i++)
+ for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
if (inlineCallFrame->isVarargs())
m_read(VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount));
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1004,7 +1004,6 @@
case PhantomNewGeneratorFunction:
case PhantomCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -354,7 +354,6 @@
case MaterializeNewObject:
case MaterializeCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -6852,7 +6852,6 @@
GPRReg arrayResultGPR = arrayResult.gpr();
bool shouldAllowForArrayStorageStructureForLargeArrays = false;
- ASSERT(m_jit.graph().globalObjectFor(node->origin.semantic)->restParameterStructure()->indexingType() == ArrayWithContiguous);
compileAllocateNewArrayWithSize(m_jit.graph().globalObjectFor(node->origin.semantic), arrayResultGPR, arrayLengthGPR, ArrayWithContiguous, shouldAllowForArrayStorageStructureForLargeArrays);
GPRTemporary argumentsStart(this);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -5601,7 +5601,6 @@
case GetStack:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
- case PhantomCreateRest:
DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -5818,7 +5818,6 @@
case PutStack:
case KillStack:
case GetStack:
- case PhantomCreateRest:
DFG_CRASH(m_jit.graph(), node, "Unexpected node");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGStructureRegistrationPhase.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGStructureRegistrationPhase.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGStructureRegistrationPhase.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -118,14 +118,6 @@
registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
break;
}
-
- case CreateRest: {
- if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
- JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
- registerStructure(globalObject->restParameterStructure());
- }
- break;
- }
case NewTypedArray:
registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(node->typedArrayType()));
Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -670,7 +670,6 @@
case PhantomNewGeneratorFunction:
case PhantomCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case MovHint:
case Upsilon:
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -230,7 +230,6 @@
case MaterializeNewObject:
case MaterializeCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case GetMyArgumentByVal:
case GetMyArgumentByValOutOfBounds:
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -1074,7 +1074,6 @@
case PhantomNewGeneratorFunction:
case PhantomCreateActivation:
case PhantomDirectArguments:
- case PhantomCreateRest:
case PhantomClonedArguments:
case PutHint:
case BottomValue:
@@ -3435,8 +3434,6 @@
InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
LValue index = lowInt32(m_node->child2());
- if (m_node->numberOfArgumentsToSkip())
- index = m_out.add(index, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
LValue limit;
if (inlineCallFrame && !inlineCallFrame->isVarargs())
@@ -4160,7 +4157,7 @@
LValue arrayLength = lowInt32(m_node->child1());
LBasicBlock loopStart = m_out.newBlock();
JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
- Structure* structure = globalObject->restParameterStructure();
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
ArrayValues arrayValues = allocateUninitializedContiguousJSArray(arrayLength, structure);
LValue array = arrayValues.array;
LValue butterfly = arrayValues.butterfly;
@@ -6288,39 +6285,10 @@
inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
else
inlineCallFrame = m_node->origin.semantic.inlineCallFrame;
-
- 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));
- }
-
+
+ LValue length = getArgumentsLength(inlineCallFrame).value;
+ LValue lengthIncludingThis = m_out.add(length, m_out.constInt32(1 - data->offset));
+
speculate(
VarargsOverflow, noValue(), nullptr,
m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
@@ -6327,8 +6295,7 @@
m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
- unsigned numberOfArgumentsToSkip = data->offset;
- LValue sourceStart = getArgumentsStart(inlineCallFrame, numberOfArgumentsToSkip);
+ LValue sourceStart = getArgumentsStart(inlineCallFrame);
LValue targetStart = addressFor(data->machineStart).value();
LBasicBlock undefinedLoop = m_out.newBlock();
@@ -6361,7 +6328,9 @@
previousIndex = m_out.phi(pointerType(), loopBound);
currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
LValue value = m_out.load64(
- m_out.baseIndex(m_heaps.variables, sourceStart, currentIndex));
+ m_out.baseIndex(
+ m_heaps.variables, sourceStart,
+ m_out.add(currentIndex, m_out.constIntPtr(data->offset))));
m_out.store64(value, m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
nextIndex = m_out.anchor(currentIndex);
m_out.addIncomingToPhi(previousIndex, nextIndex);
@@ -8407,9 +8376,9 @@
return m_out.loadPtr(addressFor(CallFrameSlot::callee));
}
- LValue getArgumentsStart(InlineCallFrame* inlineCallFrame, unsigned offset = 0)
+ LValue getArgumentsStart(InlineCallFrame* inlineCallFrame)
{
- VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame) + offset;
+ VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame);
return addressFor(start).value();
}
Modified: trunk/Source/_javascript_Core/ftl/FTLOperations.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -83,7 +83,6 @@
case PhantomNewGeneratorFunction:
case PhantomDirectArguments:
case PhantomClonedArguments:
- case PhantomCreateRest:
// Those are completely handled by operationMaterializeObjectInOSR
break;
@@ -235,7 +234,6 @@
return result;
}
- case PhantomCreateRest:
case PhantomDirectArguments:
case PhantomClonedArguments: {
if (!materialization->origin().inlineCallFrame) {
@@ -244,17 +242,6 @@
return DirectArguments::createByCopying(exec);
case PhantomClonedArguments:
return ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned);
- 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);
- }
default:
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
@@ -268,12 +255,14 @@
const ExitPropertyValue& property = materialization->properties()[i];
if (property.location() != PromotedLocationDescriptor(ArgumentCountPLoc))
continue;
+
argumentCount = JSValue::decode(values[i]).asUInt32();
+ RELEASE_ASSERT(argumentCount);
break;
}
+ RELEASE_ASSERT(argumentCount);
} else
argumentCount = materialization->origin().inlineCallFrame->arguments.size();
- RELEASE_ASSERT(argumentCount);
JSFunction* callee = nullptr;
if (materialization->origin().inlineCallFrame->isClosureCall) {
@@ -341,56 +330,6 @@
return result;
}
- 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;
- }
default:
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
Modified: trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -47,7 +47,7 @@
jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), resultGPR);
jit.addPtr(lengthGPR, resultGPR);
- jit.addPtr(CCallHelpers::TrustedImm32(CallFrame::headerSizeInRegisters + (lengthIncludesThis ? 0 : 1)), resultGPR);
+ jit.addPtr(CCallHelpers::TrustedImm32(CallFrame::headerSizeInRegisters + (lengthIncludesThis? 0 : 1)), resultGPR);
// resultGPR now has the required frame size in Register units
// Round resultGPR to next multiple of stackAlignmentRegisters()
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (208223 => 208224)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2016-11-01 17:20:25 UTC (rev 208224)
@@ -851,7 +851,7 @@
BEGIN();
unsigned arraySize = OP_C(2).jsValue().asUInt32();
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- Structure* structure = globalObject->restParameterStructure();
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
unsigned numParamsToSkip = pc[3].u.unsignedValue;
JSValue* argumentsToCopyRegion = exec->addressOfArgumentsStart() + numParamsToSkip;
RETURN(constructArray(exec, structure, argumentsToCopyRegion, arraySize));
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (208223 => 208224)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2016-11-01 16:44:36 UTC (rev 208223)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2016-11-01 17:20:25 UTC (rev 208224)
@@ -623,7 +623,6 @@
Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(); }
Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); }
Structure* moduleLoaderStructure() const { return m_moduleLoaderStructure.get(); }
- Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); }
JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;