| Index: test/mjsunit/es6/tail-call-megatest.js
|
| diff --git a/test/mjsunit/es6/tail-call-megatest.js b/test/mjsunit/es6/tail-call-megatest.js
|
| index 005796195a84cdf319d71ee0bf1b3e145967c232..4f12ff4394b1f2aa843f90b2f1c98a5ff88bdd3c 100644
|
| --- a/test/mjsunit/es6/tail-call-megatest.js
|
| +++ b/test/mjsunit/es6/tail-call-megatest.js
|
| @@ -3,6 +3,8 @@
|
| // found in the LICENSE file.
|
|
|
| // Flags: --allow-natives-syntax --harmony-tailcalls --no-turbo-inlining
|
| +// TODO(v8:4698), TODO(ishell): support these cases.
|
| +// Flags: --no-turbo --nostress-opt
|
|
|
|
|
| Error.prepareStackTrace = (error,stack) => {
|
| @@ -11,23 +13,15 @@ Error.prepareStackTrace = (error,stack) => {
|
| }
|
|
|
|
|
| -function CheckStackTrace(expected) {
|
| +function checkStackTrace(expected) {
|
| var e = new Error();
|
| e.stack; // prepare stack trace
|
| var stack = e.strace;
|
| - assertEquals("CheckStackTrace", stack[0].getFunctionName());
|
| + assertEquals("checkStackTrace", stack[0].getFunctionName());
|
| for (var i = 0; i < expected.length; i++) {
|
| assertEquals(expected[i].name, stack[i + 1].getFunctionName());
|
| }
|
| }
|
| -%NeverOptimizeFunction(CheckStackTrace);
|
| -
|
| -
|
| -function CheckArguments(expected, args) {
|
| - args = Array.prototype.slice.call(args);
|
| - assertEquals(expected, args);
|
| -}
|
| -%NeverOptimizeFunction(CheckArguments);
|
|
|
|
|
| var CAN_INLINE_COMMENT = "// Let it be inlined.";
|
| @@ -45,28 +39,44 @@ function ident_source(source, ident) {
|
| return ident + source.replace(/\n/gi, "\n" + ident);
|
| }
|
|
|
| -var global = Function('return this')();
|
| -var the_receiver = {receiver: 1};
|
|
|
| function run_tests() {
|
| function inlinable_comment(inlinable) {
|
| return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
|
| }
|
|
|
| + // Check arguments manually to avoid bailing out with reason "bad value
|
| + // context for arguments value".
|
| + function check_arguments_template(expected_name) {
|
| + var lines = [
|
| + ` assertEquals_(${expected_name}.length, arguments.length);`,
|
| + ` for (var i = 0; i < ${expected_name}.length; i++) {`,
|
| + ` assertEquals_(${expected_name}[i], arguments[i]);`,
|
| + ` }`,
|
| + ];
|
| + return lines.join("\n");
|
| + }
|
| + var check_arguments = check_arguments_template("expected_args");
|
| +
|
| var f_cfg_sloppy = {
|
| func_name: 'f',
|
| source_template: function(cfg) {
|
| var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
|
| : "global";
|
| + var do_checks = [
|
| + ` assertEquals_(${receiver}, this);`,
|
| + ` assertEquals_(undefined, new.target);`,
|
| + check_arguments,
|
| + ` checkStackTrace_([f, test]);`,
|
| + ].join("\n");
|
| +
|
| var lines = [
|
| `function f(a) {`,
|
| ` ${inlinable_comment(cfg.f_inlinable)}`,
|
| - ` assertEquals(${receiver}, this);`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + ` var expected_args = [${cfg.f_args}];`,
|
| + do_checks,
|
| ` %DeoptimizeNow();`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + do_checks,
|
| ` return 42;`,
|
| `}`,
|
| ];
|
| @@ -79,16 +89,21 @@ function run_tests() {
|
| source_template: function(cfg) {
|
| var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
|
| : "undefined";
|
| + var do_checks = [
|
| + ` assertEquals_(${receiver}, this);`,
|
| + ` assertEquals_(undefined, new.target);`,
|
| + check_arguments,
|
| + ` checkStackTrace_([f, test]);`,
|
| + ].join("\n");
|
| +
|
| var lines = [
|
| `function f(a) {`,
|
| ` "use strict";`,
|
| ` ${inlinable_comment(cfg.f_inlinable)}`,
|
| - ` assertEquals(${receiver}, this);`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + ` var expected_args = [${cfg.f_args}];`,
|
| + do_checks,
|
| ` %DeoptimizeNow();`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + do_checks,
|
| ` return 42;`,
|
| `}`,
|
| ];
|
| @@ -101,15 +116,20 @@ function run_tests() {
|
| source_template: function(cfg) {
|
| var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
|
| : "global";
|
| + var do_checks = [
|
| + ` assertEquals_(${receiver}, this);`,
|
| + ` assertEquals_(undefined, new.target);`,
|
| + check_arguments,
|
| + ` checkStackTrace_([f, test]);`,
|
| + ].join("\n");
|
| +
|
| var lines = [
|
| `function f(a) {`,
|
| ` ${inlinable_comment(cfg.f_inlinable)}`,
|
| - ` assertEquals(${receiver}, this);`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + ` var expected_args = [${cfg.f_args}];`,
|
| + do_checks,
|
| ` %DeoptimizeNow();`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + do_checks,
|
| ` return 42;`,
|
| `}`,
|
| `var eval = f;`,
|
| @@ -121,16 +141,21 @@ function run_tests() {
|
| var f_cfg_bound = {
|
| func_name: 'bound',
|
| source_template: function(cfg) {
|
| + var do_checks = [
|
| + ` assertEquals_(receiver, this);`,
|
| + ` assertEquals_(undefined, new.target);`,
|
| + check_arguments,
|
| + ` checkStackTrace_([f, test]);`,
|
| + ].join("\n");
|
| +
|
| var lines = [
|
| `function f(a) {`,
|
| ` "use strict";`,
|
| ` ${inlinable_comment(cfg.f_inlinable)}`,
|
| - ` assertEquals(receiver, this);`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + ` var expected_args = [${cfg.f_args}];`,
|
| + do_checks,
|
| ` %DeoptimizeNow();`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + do_checks,
|
| ` return 42;`,
|
| `}`,
|
| `var receiver = {a: 153};`,
|
| @@ -145,15 +170,20 @@ function run_tests() {
|
| source_template: function(cfg) {
|
| var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
|
| : "global";
|
| + var do_checks = [
|
| + ` assertEquals_(${receiver}, this);`,
|
| + ` assertEquals_(undefined, new.target);`,
|
| + check_arguments,
|
| + ` checkStackTrace_([f, test]);`,
|
| + ].join("\n");
|
| +
|
| var lines = [
|
| `function f(a) {`,
|
| ` ${inlinable_comment(cfg.f_inlinable)}`,
|
| - ` assertEquals(${receiver}, this);`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + ` var expected_args = [${cfg.f_args}];`,
|
| + do_checks,
|
| ` %DeoptimizeNow();`,
|
| - ` CheckArguments([${cfg.f_args}], arguments);`,
|
| - ` CheckStackTrace([f, test]);`,
|
| + do_checks,
|
| ` return 42;`,
|
| `}`,
|
| `var p = new Proxy(f, {});`,
|
| @@ -169,7 +199,8 @@ function run_tests() {
|
| `function g(a) {`,
|
| ` "use strict";`,
|
| ` ${inlinable_comment(cfg.g_inlinable)}`,
|
| - ` CheckArguments([${cfg.g_args}], arguments);`,
|
| + ` var expected_args = [${cfg.g_args}];`,
|
| + check_arguments,
|
| ` return ${cfg.f_name}(${cfg.f_args});`,
|
| `}`,
|
| ];
|
| @@ -185,7 +216,8 @@ function run_tests() {
|
| `function g(a) {`,
|
| ` "use strict";`,
|
| ` ${inlinable_comment(cfg.g_inlinable)}`,
|
| - ` CheckArguments([${cfg.g_args}], arguments);`,
|
| + ` var expected_args = [${cfg.g_args}];`,
|
| + check_arguments,
|
| ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`,
|
| `}`,
|
| ];
|
| @@ -194,6 +226,24 @@ function run_tests() {
|
| };
|
|
|
|
|
| + var g_cfg_function_apply_arguments_object = {
|
| + receiver: "the_receiver",
|
| + source_template: function(cfg) {
|
| + cfg.f_args = cfg.g_args;
|
| + var lines = [
|
| + `function g(a) {`,
|
| + ` "use strict";`,
|
| + ` ${inlinable_comment(cfg.g_inlinable)}`,
|
| + ` var expected_args = [${cfg.g_args}];`,
|
| + check_arguments,
|
| + ` return ${cfg.f_name}.apply(the_receiver, arguments);`,
|
| + `}`,
|
| + ];
|
| + return lines.join("\n");
|
| + },
|
| + };
|
| +
|
| +
|
| var g_cfg_function_call = {
|
| receiver: "the_receiver",
|
| source_template: function(cfg) {
|
| @@ -205,7 +255,8 @@ function run_tests() {
|
| `function g(a) {`,
|
| ` "use strict";`,
|
| ` ${inlinable_comment(cfg.g_inlinable)}`,
|
| - ` CheckArguments([${cfg.g_args}], arguments);`,
|
| + ` var expected_args = [${cfg.g_args}];`,
|
| + check_arguments,
|
| ` return ${cfg.f_name}.call(${f_args});`,
|
| `}`,
|
| ];
|
| @@ -215,23 +266,35 @@ function run_tests() {
|
|
|
|
|
| function test_template(cfg) {
|
| - var f_source = cfg.f_source_template(cfg);
|
| + // Note: g_source_template modifies cfg.f_args in some cases.
|
| var g_source = cfg.g_source_template(cfg);
|
| - f_source = ident_source(f_source, 2);
|
| g_source = ident_source(g_source, 2);
|
|
|
| + var f_source = cfg.f_source_template(cfg);
|
| + f_source = ident_source(f_source, 2);
|
| +
|
| var lines = [
|
| `(function() {`,
|
| + ` // Avoid bailing out because of "Reference to a variable which requires dynamic lookup".`,
|
| + ` var assertEquals_ = assertEquals;`,
|
| + ` var checkStackTrace_ = checkStackTrace;`,
|
| + ` var undefined = void 0;`,
|
| + ` var global = Function('return this')();`,
|
| + ` var the_receiver = {receiver: 1};`,
|
| + ``,
|
| + ` // Don't inline helper functions`,
|
| + ` %NeverOptimizeFunction(assertEquals);`,
|
| + ` %NeverOptimizeFunction(checkStackTrace);`,
|
| + ``,
|
| f_source,
|
| g_source,
|
| ` function test() {`,
|
| ` "use strict";`,
|
| - ` assertEquals(42, g(${cfg.g_args}));`,
|
| + ` assertEquals_(42, g(${cfg.g_args}));`,
|
| ` }`,
|
| ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`,
|
| ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`,
|
| - ``,
|
| - ` test();`,
|
| + ` ${"test();".repeat(cfg.test_warmup_count)}`,
|
| ` %OptimizeFunctionOnNextCall(test);`,
|
| ` %OptimizeFunctionOnNextCall(f);`,
|
| ` %OptimizeFunctionOnNextCall(g);`,
|
| @@ -245,9 +308,9 @@ function run_tests() {
|
|
|
| // TODO(v8:4698), TODO(ishell): support all commented cases.
|
| var f_args_variants = ["", "1", "1, 2"];
|
| - var g_args_variants = [/*"",*/ "10", /*"10, 20"*/];
|
| + var g_args_variants = ["", "10", "10, 20"];
|
| var f_inlinable_variants = [/*true,*/ false];
|
| - var g_inlinable_variants = [true, false];
|
| + var g_inlinable_variants = [/*true,*/ false];
|
| var f_variants = [
|
| f_cfg_sloppy,
|
| f_cfg_strict,
|
| @@ -259,7 +322,9 @@ function run_tests() {
|
| g_cfg_normal,
|
| g_cfg_function_call,
|
| g_cfg_function_apply,
|
| + g_cfg_function_apply_arguments_object,
|
| ];
|
| + var test_warmup_counts = [0, 1, 2];
|
|
|
| f_variants.forEach((f_cfg) => {
|
| g_variants.forEach((g_cfg) => {
|
| @@ -267,20 +332,23 @@ function run_tests() {
|
| g_args_variants.forEach((g_args) => {
|
| f_inlinable_variants.forEach((f_inlinable) => {
|
| g_inlinable_variants.forEach((g_inlinable) => {
|
| - var cfg = {
|
| - f_source_template: f_cfg.source_template,
|
| - f_inlinable,
|
| - f_args,
|
| - f_name: f_cfg.func_name,
|
| - f_receiver: g_cfg.receiver,
|
| - g_source_template: g_cfg.source_template,
|
| - g_inlinable,
|
| - g_args,
|
| - };
|
| - var source = test_template(cfg);
|
| - print("====================");
|
| - print(source);
|
| - eval(source);
|
| + test_warmup_counts.forEach((test_warmup_count) => {
|
| + var cfg = {
|
| + f_source_template: f_cfg.source_template,
|
| + f_inlinable,
|
| + f_args,
|
| + f_name: f_cfg.func_name,
|
| + f_receiver: g_cfg.receiver,
|
| + g_source_template: g_cfg.source_template,
|
| + g_inlinable,
|
| + g_args,
|
| + test_warmup_count,
|
| + };
|
| + var source = test_template(cfg);
|
| + print("====================");
|
| + print(source);
|
| + eval(source);
|
| + });
|
| });
|
| });
|
| });
|
|
|