| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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(); |
| OLD | NEW |