Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: test/mjsunit/es6/tail-call-megatest.js

Issue 1780043004: [crankshaft] Fixing ES6 tail call elimination. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebasing Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/mjsunit/es6/tail-call.js ('k') | test/mjsunit/es6/tail-call-megatest-shard0.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --allow-natives-syntax --harmony-tailcalls 5 // Flags: --allow-natives-syntax --harmony-tailcalls
6 // TODO(v8:4698), TODO(ishell): support these cases.
7 // Flags: --turbo --nostress-opt
8 6
9 7
10 Error.prepareStackTrace = (error,stack) => { 8 Error.prepareStackTrace = (error,stack) => {
11 error.strace = stack; 9 error.strace = stack;
12 return error.message + "\n at " + stack.join("\n at "); 10 return error.message + "\n at " + stack.join("\n at ");
13 } 11 }
14 12
15 13
16 function checkStackTrace(expected) { 14 function checkStackTrace(expected) {
17 var e = new Error(); 15 var e = new Error();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 var lines = [ 50 var lines = [
53 ` assertEquals_(${expected_name}.length, arguments.length);`, 51 ` assertEquals_(${expected_name}.length, arguments.length);`,
54 ` for (var i = 0; i < ${expected_name}.length; i++) {`, 52 ` for (var i = 0; i < ${expected_name}.length; i++) {`,
55 ` assertEquals_(${expected_name}[i], arguments[i]);`, 53 ` assertEquals_(${expected_name}[i], arguments[i]);`,
56 ` }`, 54 ` }`,
57 ]; 55 ];
58 return lines.join("\n"); 56 return lines.join("\n");
59 } 57 }
60 var check_arguments = check_arguments_template("expected_args"); 58 var check_arguments = check_arguments_template("expected_args");
61 59
60 function deopt_template(deopt_mode) {
61 switch(deopt_mode) {
62 case "none":
63 return " // Don't deoptimize";
64 case "f":
65 case "g":
66 case "test":
67 return ` %DeoptimizeFunction(${deopt_mode});`;
68 default:
69 assertUnreachable();
70 }
71 }
72
62 var f_cfg_sloppy = { 73 var f_cfg_sloppy = {
63 func_name: 'f', 74 func_name: 'f',
64 source_template: function(cfg) { 75 source_template: function(cfg) {
65 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver 76 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
66 : "global"; 77 : "global";
67 var do_checks = [ 78 var do_checks = [
68 ` assertEquals_(${receiver}, this);`, 79 ` assertEquals_(${receiver}, this);`,
69 ` assertEquals_(undefined, new.target);`, 80 ` ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.tar get);`,
70 check_arguments, 81 check_arguments,
71 ` checkStackTrace_([f, test]);`, 82 ` checkStackTrace_([f, test]);`,
72 ].join("\n"); 83 ].join("\n");
73 84
74 var lines = [ 85 var lines = [
75 `function f(a) {`, 86 `function f(a) {`,
76 ` ${inlinable_comment(cfg.f_inlinable)}`, 87 ` ${inlinable_comment(cfg.f_inlinable)}`,
88 ` counter++;`,
77 ` var expected_args = [${cfg.f_args}];`, 89 ` var expected_args = [${cfg.f_args}];`,
78 do_checks, 90 do_checks,
79 ` %DeoptimizeNow();`, 91 deopt_template(cfg.deopt_mode),
80 do_checks, 92 do_checks,
81 ` return 42;`, 93 ` return 42;`,
82 `}`, 94 `}`,
83 ]; 95 ];
84 return lines.join("\n"); 96 return lines.join("\n");
85 }, 97 },
86 }; 98 };
87 99
88 var f_cfg_strict = { 100 var f_cfg_strict = {
89 func_name: 'f', 101 func_name: 'f',
90 source_template: function(cfg) { 102 source_template: function(cfg) {
91 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver 103 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
92 : "undefined"; 104 : "undefined";
93 var do_checks = [ 105 var do_checks = [
94 ` assertEquals_(${receiver}, this);`, 106 ` assertEquals_(${receiver}, this);`,
95 ` assertEquals_(undefined, new.target);`, 107 ` ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.tar get);`,
96 check_arguments, 108 check_arguments,
97 ` checkStackTrace_([f, test]);`, 109 ` checkStackTrace_([f, test]);`,
98 ].join("\n"); 110 ].join("\n");
99 111
100 var lines = [ 112 var lines = [
101 `function f(a) {`, 113 `function f(a) {`,
102 ` "use strict";`, 114 ` "use strict";`,
103 ` ${inlinable_comment(cfg.f_inlinable)}`, 115 ` ${inlinable_comment(cfg.f_inlinable)}`,
116 ` counter++;`,
104 ` var expected_args = [${cfg.f_args}];`, 117 ` var expected_args = [${cfg.f_args}];`,
105 do_checks, 118 do_checks,
106 ` %DeoptimizeNow();`, 119 deopt_template(cfg.deopt_mode),
107 do_checks, 120 do_checks,
108 ` return 42;`, 121 ` return 42;`,
109 `}`, 122 `}`,
110 ]; 123 ];
111 return lines.join("\n"); 124 return lines.join("\n");
112 }, 125 },
113 }; 126 };
114 127
115 var f_cfg_possibly_eval = { 128 var f_cfg_possibly_eval = {
116 func_name: 'eval', 129 func_name: 'eval',
117 source_template: function(cfg) { 130 source_template: function(cfg) {
118 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver 131 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
119 : "global"; 132 : "global";
120 var do_checks = [ 133 var do_checks = [
121 ` assertEquals_(${receiver}, this);`, 134 ` assertEquals_(${receiver}, this);`,
122 ` assertEquals_(undefined, new.target);`, 135 ` ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.tar get);`,
123 check_arguments, 136 check_arguments,
124 ` checkStackTrace_([f, test]);`, 137 ` checkStackTrace_([f, test]);`,
125 ].join("\n"); 138 ].join("\n");
126 139
127 var lines = [ 140 var lines = [
128 `function f(a) {`, 141 `function f(a) {`,
129 ` ${inlinable_comment(cfg.f_inlinable)}`, 142 ` ${inlinable_comment(cfg.f_inlinable)}`,
143 ` counter++;`,
130 ` var expected_args = [${cfg.f_args}];`, 144 ` var expected_args = [${cfg.f_args}];`,
131 do_checks, 145 do_checks,
132 ` %DeoptimizeNow();`, 146 deopt_template(cfg.deopt_mode),
133 do_checks, 147 do_checks,
134 ` return 42;`, 148 ` return 42;`,
135 `}`, 149 `}`,
136 `var eval = f;`, 150 `var eval = f;`,
137 ]; 151 ];
138 return lines.join("\n"); 152 return lines.join("\n");
139 }, 153 },
140 }; 154 };
141 155
142 var f_cfg_bound = { 156 var f_cfg_bound = {
143 func_name: 'bound', 157 func_name: 'bound',
144 source_template: function(cfg) { 158 source_template: function(cfg) {
145 var do_checks = [ 159 var do_checks = [
146 ` assertEquals_(receiver, this);`, 160 ` assertEquals_(receiver, this);`,
147 ` assertEquals_(undefined, new.target);`, 161 ` ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.tar get);`,
148 check_arguments, 162 check_arguments,
149 ` checkStackTrace_([f, test]);`, 163 ` checkStackTrace_([f, test]);`,
150 ].join("\n"); 164 ].join("\n");
151 165
152 var lines = [ 166 var lines = [
153 `function f(a) {`, 167 `function f(a) {`,
154 ` "use strict";`, 168 ` "use strict";`,
155 ` ${inlinable_comment(cfg.f_inlinable)}`, 169 ` ${inlinable_comment(cfg.f_inlinable)}`,
170 ` counter++;`,
156 ` var expected_args = [${cfg.f_args}];`, 171 ` var expected_args = [${cfg.f_args}];`,
157 do_checks, 172 do_checks,
158 ` %DeoptimizeNow();`, 173 deopt_template(cfg.deopt_mode),
159 do_checks, 174 do_checks,
160 ` return 42;`, 175 ` return 42;`,
161 `}`, 176 `}`,
162 `var receiver = {a: 153};`, 177 `var receiver = {a: 153};`,
163 `var bound = f.bind(receiver);`, 178 `var bound = f.bind(receiver);`,
164 ]; 179 ];
165 return lines.join("\n"); 180 return lines.join("\n");
166 }, 181 },
167 }; 182 };
168 183
169 var f_cfg_proxy = { 184 var f_cfg_proxy = {
170 func_name: 'p', 185 func_name: 'p',
171 source_template: function(cfg) { 186 source_template: function(cfg) {
172 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver 187 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
173 : "global"; 188 : "global";
174 var do_checks = [ 189 var do_checks = [
175 ` assertEquals_(${receiver}, this);`, 190 ` assertEquals_(${receiver}, this);`,
176 ` assertEquals_(undefined, new.target);`, 191 ` ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.tar get);`,
177 check_arguments, 192 check_arguments,
178 ` checkStackTrace_([f, test]);`, 193 ` checkStackTrace_([f, test]);`,
179 ].join("\n"); 194 ].join("\n");
180 195
181 var lines = [ 196 var lines = [
182 `function f(a) {`, 197 `function f(a) {`,
183 ` ${inlinable_comment(cfg.f_inlinable)}`, 198 ` ${inlinable_comment(cfg.f_inlinable)}`,
199 ` counter++;`,
184 ` var expected_args = [${cfg.f_args}];`, 200 ` var expected_args = [${cfg.f_args}];`,
185 do_checks, 201 do_checks,
186 ` %DeoptimizeNow();`, 202 deopt_template(cfg.deopt_mode),
187 do_checks, 203 do_checks,
188 ` return 42;`, 204 ` return 42;`,
189 `}`, 205 `}`,
190 `var p = new Proxy(f, {});`, 206 `var p = new Proxy(f, {});`,
191 ]; 207 ];
192 return lines.join("\n"); 208 return lines.join("\n");
193 }, 209 },
194 }; 210 };
195 211
196 var g_cfg_normal = { 212 var g_cfg_normal = {
197 receiver: undefined, 213 receiver: undefined,
198 source_template: function(cfg) { 214 source_template: function(cfg) {
199 var lines = [ 215 var lines = [
200 `function g(a) {`, 216 `function g(a) {`,
201 ` "use strict";`, 217 ` "use strict";`,
202 ` ${inlinable_comment(cfg.g_inlinable)}`, 218 ` ${inlinable_comment(cfg.g_inlinable)}`,
203 ` var expected_args = [${cfg.g_args}];`, 219 ` var expected_args = [${cfg.g_args}];`,
204 check_arguments, 220 check_arguments,
205 ` return ${cfg.f_name}(${cfg.f_args});`, 221 ` return ${cfg.f_name}(${cfg.f_args});`,
206 `}`, 222 `}`,
207 ]; 223 ];
208 return lines.join("\n"); 224 return lines.join("\n");
209 }, 225 },
210 }; 226 };
211 227
212 228
229 var g_cfg_reflect_apply = {
230 receiver: "the_receiver",
231 source_template: function(cfg) {
232 var lines = [
233 `function g(a) {`,
234 ` "use strict";`,
235 ` ${inlinable_comment(cfg.g_inlinable)}`,
236 ` var expected_args = [${cfg.g_args}];`,
237 check_arguments,
238 ` return Reflect.apply(${cfg.f_name}, the_receiver, [${cfg.f_args}]);`,
239 `}`,
240 ];
241 return lines.join("\n");
242 },
243 };
244
245
213 var g_cfg_function_apply = { 246 var g_cfg_function_apply = {
214 receiver: "the_receiver", 247 receiver: "the_receiver",
215 source_template: function(cfg) { 248 source_template: function(cfg) {
216 var lines = [ 249 var lines = [
217 `function g(a) {`, 250 `function g(a) {`,
218 ` "use strict";`, 251 ` "use strict";`,
219 ` ${inlinable_comment(cfg.g_inlinable)}`, 252 ` ${inlinable_comment(cfg.g_inlinable)}`,
220 ` var expected_args = [${cfg.g_args}];`, 253 ` var expected_args = [${cfg.g_args}];`,
221 check_arguments, 254 check_arguments,
222 ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`, 255 ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 f_source = ident_source(f_source, 2); 308 f_source = ident_source(f_source, 2);
276 309
277 var lines = [ 310 var lines = [
278 `(function() {`, 311 `(function() {`,
279 ` // Avoid bailing out because of "Reference to a variable which requires dynamic lookup".`, 312 ` // Avoid bailing out because of "Reference to a variable which requires dynamic lookup".`,
280 ` var assertEquals_ = assertEquals;`, 313 ` var assertEquals_ = assertEquals;`,
281 ` var checkStackTrace_ = checkStackTrace;`, 314 ` var checkStackTrace_ = checkStackTrace;`,
282 ` var undefined = void 0;`, 315 ` var undefined = void 0;`,
283 ` var global = Function('return this')();`, 316 ` var global = Function('return this')();`,
284 ` var the_receiver = {receiver: 1};`, 317 ` var the_receiver = {receiver: 1};`,
318 ` var counter = 0;`,
285 ``, 319 ``,
286 ` // Don't inline helper functions`, 320 ` // Don't inline helper functions`,
287 ` %NeverOptimizeFunction(assertEquals);`, 321 ` %NeverOptimizeFunction(assertEquals);`,
288 ` %NeverOptimizeFunction(checkStackTrace);`, 322 ` %NeverOptimizeFunction(checkStackTrace);`,
289 ``, 323 ``,
290 f_source, 324 f_source,
291 g_source, 325 g_source,
292 ` function test() {`, 326 ` function test() {`,
293 ` "use strict";`, 327 ` "use strict";`,
294 ` assertEquals_(42, g(${cfg.g_args}));`, 328 ` assertEquals_(42, g(${cfg.g_args}));`,
295 ` }`, 329 ` }`,
296 ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`,
297 ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`,
298 ` ${"test();".repeat(cfg.test_warmup_count)}`, 330 ` ${"test();".repeat(cfg.test_warmup_count)}`,
331 ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : "%OptimizeFunctionOnNext Call(f)"};`,
332 ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : "%OptimizeFunctionOnNext Call(g)"};`,
299 ` %OptimizeFunctionOnNextCall(test);`, 333 ` %OptimizeFunctionOnNextCall(test);`,
300 ` %OptimizeFunctionOnNextCall(f);`,
301 ` %OptimizeFunctionOnNextCall(g);`,
302 ` test();`, 334 ` test();`,
335 ` assertEquals(${1 + cfg.test_warmup_count}, counter);`,
303 `})();`, 336 `})();`,
304 ``, 337 ``,
305 ]; 338 ];
306 var source = lines.join("\n"); 339 var source = lines.join("\n");
307 return source; 340 return source;
308 } 341 }
309 342
310 var f_args_variants = ["", "1", "1, 2"]; 343 var f_args_variants = ["", "1", "1, 2"];
311 var g_args_variants = ["", "10", "10, 20"]; 344 var g_args_variants = ["", "10", "10, 20"];
312 var f_inlinable_variants = [true, false]; 345 var f_inlinable_variants = [true, false];
313 var g_inlinable_variants = [true, false]; 346 var g_inlinable_variants = [true, false];
347 // This is to avoid bailing out because of referencing new.target.
348 var check_new_target_variants = [true, false];
349 var deopt_mode_variants = ["none", "f", "g", "test"];
314 var f_variants = [ 350 var f_variants = [
315 f_cfg_sloppy, 351 f_cfg_sloppy,
316 f_cfg_strict, 352 f_cfg_strict,
317 f_cfg_bound, 353 f_cfg_bound,
318 f_cfg_proxy, 354 f_cfg_proxy,
319 f_cfg_possibly_eval, 355 f_cfg_possibly_eval,
320 ]; 356 ];
321 var g_variants = [ 357 var g_variants = [
322 g_cfg_normal, 358 g_cfg_normal,
323 g_cfg_function_call, 359 g_cfg_reflect_apply,
324 g_cfg_function_apply, 360 g_cfg_function_apply,
325 g_cfg_function_apply_arguments_object, 361 g_cfg_function_apply_arguments_object,
362 g_cfg_function_call,
326 ]; 363 ];
327 var test_warmup_counts = [0, 1, 2]; 364 var test_warmup_counts = [0, 1, 2];
328 365
329 var iter = 0; 366 var iter = 0;
367 var tests_executed = 0;
330 if (shard !== undefined) { 368 if (shard !== undefined) {
331 print("Running shard #" + shard); 369 print("Running shard #" + shard);
332 } 370 }
333 f_variants.forEach((f_cfg) => { 371 f_variants.forEach((f_cfg) => {
334 g_variants.forEach((g_cfg) => { 372 check_new_target_variants.forEach((check_new_target) => {
335 f_args_variants.forEach((f_args) => { 373 deopt_mode_variants.forEach((deopt_mode) => {
336 g_args_variants.forEach((g_args) => { 374 g_variants.forEach((g_cfg) => {
337 f_inlinable_variants.forEach((f_inlinable) => { 375 f_args_variants.forEach((f_args) => {
338 g_inlinable_variants.forEach((g_inlinable) => { 376 g_args_variants.forEach((g_args) => {
339 test_warmup_counts.forEach((test_warmup_count) => { 377 f_inlinable_variants.forEach((f_inlinable) => {
340 if (shard !== undefined && (iter++) % SHARDS_COUNT != shard) { 378 g_inlinable_variants.forEach((g_inlinable) => {
341 print("skipping..."); 379 test_warmup_counts.forEach((test_warmup_count) => {
342 return; 380 if (shard !== undefined && (iter++) % SHARDS_COUNT != shard) {
343 } 381 print("skipping...");
344 var cfg = { 382 return;
345 f_source_template: f_cfg.source_template, 383 }
346 f_inlinable, 384 tests_executed++;
347 f_args, 385 var cfg = {
348 f_name: f_cfg.func_name, 386 f_source_template: f_cfg.source_template,
349 f_receiver: g_cfg.receiver, 387 f_inlinable,
350 g_source_template: g_cfg.source_template, 388 f_args,
351 g_inlinable, 389 f_name: f_cfg.func_name,
352 g_args, 390 f_receiver: g_cfg.receiver,
353 test_warmup_count, 391 g_source_template: g_cfg.source_template,
354 }; 392 g_inlinable,
355 var source = test_template(cfg); 393 g_args,
356 print("===================="); 394 test_warmup_count,
357 print(source); 395 check_new_target,
358 eval(source); 396 deopt_mode,
397 };
398 var source = test_template(cfg);
399 print("====================");
400 print(source);
401 eval(source);
402 });
403 });
359 }); 404 });
360 }); 405 });
361 }); 406 });
362 }); 407 });
363 }); 408 });
364 }); 409 });
365 }); 410 });
411 print("Number of tests executed: " + tests_executed);
366 } 412 }
367 413
368 // Uncomment to run all the tests at once or use shard runners. 414 // Uncomment to run all the tests at once or use shard runners.
369 //run_tests(); 415 //run_tests();
OLDNEW
« no previous file with comments | « test/mjsunit/es6/tail-call.js ('k') | test/mjsunit/es6/tail-call-megatest-shard0.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698