e16dd13d6d
Introduce a new JSGlobalSpecialization advanced reducer that runs during the initial inlining and context specialization, and specializes the graph to the globals of the native context. Currently we assume that we do not inline cross native context, but long-term we will grab the global object from the JSLoadGlobal/JSStoreGlobal feedback (with the new global load/store ICs that are currently in the workings), and then this whole specialization will be fully compositional even across cross-context inlining. Note that we cannot really handle most of the stores to global object property cells because TurboFan doesn't have a mechanism to enforce certain representations. Also note that we cannot yet fully benefit from the type feedback collected on the global object property cells, because the type system cannot deal with maps in a reasonable way. CQ_INCLUDE_TRYBOTS=tryserver.v8:v8_linux_nosnap_rel R=jarin@chromium.org BUG=v8:4470 LOG=n Committed: https://crrev.com/6fbf7903f94924ea066af481719898bd9667b6eb Cr-Commit-Position: refs/heads/master@{#31139} Review URL: https://codereview.chromium.org/1387393002 Cr-Commit-Position: refs/heads/master@{#31148}
83 lines
2.1 KiB
JavaScript
83 lines
2.1 KiB
JavaScript
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --allow-natives-syntax --nostress-opt --turbo
|
|
// Flags: --nonative-context-specialization
|
|
|
|
var p0 = new Object();
|
|
var p1 = new Object();
|
|
var p2 = new Object();
|
|
|
|
// Ensure 1 parameter passed straight-through is handled correctly
|
|
var count1 = 100000;
|
|
tailee1 = function() {
|
|
"use strict";
|
|
if (count1-- == 0) {
|
|
return this;
|
|
}
|
|
return %_CallFunction(this, tailee1);
|
|
};
|
|
|
|
%OptimizeFunctionOnNextCall(tailee1);
|
|
assertEquals(p0, tailee1.call(p0));
|
|
|
|
// Ensure 2 parameters passed straight-through trigger a tail call are handled
|
|
// correctly and don't cause a stack overflow.
|
|
var count2 = 100000;
|
|
tailee2 = function(px) {
|
|
"use strict";
|
|
assertEquals(p2, px);
|
|
assertEquals(p1, this);
|
|
count2 = ((count2 | 0) - 1) | 0;
|
|
if ((count2 | 0) === 0) {
|
|
return this;
|
|
}
|
|
return %_CallFunction(this, px, tailee2);
|
|
};
|
|
|
|
%OptimizeFunctionOnNextCall(tailee2);
|
|
assertEquals(p1, tailee2.call(p1, p2));
|
|
|
|
// Ensure swapped 2 parameters don't trigger a tail call (parameter swizzling
|
|
// for the tail call isn't supported yet).
|
|
var count3 = 100000;
|
|
tailee3 = function(px) {
|
|
"use strict";
|
|
if (count3-- == 0) {
|
|
return this;
|
|
}
|
|
return %_CallFunction(px, this, tailee3);
|
|
};
|
|
|
|
%OptimizeFunctionOnNextCall(tailee3);
|
|
assertThrows(function() { tailee3.call(p1, p2); });
|
|
|
|
// Ensure too many parameters defeats the tail call optimization (currently
|
|
// unsupported).
|
|
var count4 = 1000000;
|
|
tailee4 = function(px) {
|
|
"use strict";
|
|
if (count4-- == 0) {
|
|
return this;
|
|
}
|
|
return %_CallFunction(this, px, undefined, tailee4);
|
|
};
|
|
|
|
%OptimizeFunctionOnNextCall(tailee4);
|
|
assertThrows(function() { tailee4.call(p1, p2); });
|
|
|
|
// Ensure too few parameters defeats the tail call optimization (currently
|
|
// unsupported).
|
|
var count5 = 1000000;
|
|
tailee5 = function(px) {
|
|
"use strict";
|
|
if (count5-- == 0) {
|
|
return this;
|
|
}
|
|
return %_CallFunction(this, tailee5);
|
|
};
|
|
|
|
%OptimizeFunctionOnNextCall(tailee5);
|
|
assertThrows(function() { tailee5.call(p1, p2); });
|