diff options
Diffstat (limited to 'deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js')
-rw-r--r-- | deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js new file mode 100644 index 0000000000..2ef0cc3a01 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js @@ -0,0 +1,122 @@ +// Copyright 2018 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 --opt --no-always-opt + +function runTest(f, message, mkICTraining, deoptArg) { + function test(f, message, ictraining, deoptArg) { + // Train the call ic to the maps. + let t = ictraining; + + // We put the training data into local variables + // to ensure their maps are kepts alive. If the + // maps die, gc *may* deoptimize {f}, which makes + // the test flaky. + let t1 = t(); + let t2 = t(); + let t3 = t(); + + for (let a of t1) { + f(a.arr, () => a.el); + } + for (let a of t2) { + f(a.arr, () => a.el); + } + %OptimizeFunctionOnNextCall(f); + message += " trained with" + JSON.stringify(t()); + if (deoptArg == undefined) { + // Make sure the optimized function can handle + // all trained maps without deopt. + for (let a of t3) { + f(a.arr, () => a.el); + message += " for args " + JSON.stringify(a); + assertOptimized(f, undefined, message + " should have been optimized"); + } + } else { + // Trigger deopt, causing no-speculation bit to be set. + let a1 = deoptArg; + let a2 = deoptArg; + message += " for args " + JSON.stringify(a1); + f(a1.arr, () => a1.el); + assertUnoptimized(f, undefined, message + " should have been unoptimized"); + %OptimizeFunctionOnNextCall(f); + // No speculation should protect against further deopts. + f(a2.arr, () => a2.el); + assertOptimized(f, undefined, message + " should have been optimized"); + } + } + + // Get function as a string. + var testString = test.toString(); + // Remove the function header.. + testString = testString.replace(new RegExp("[^\n]*"), "let f = " + f.toString() + ";"); + // ..and trailing '}'. + testString = testString.replace(new RegExp("[^\n]*$"), ""); + // Substitute parameters. + testString = testString.replace(new RegExp("ictraining", 'g'), mkICTraining.toString()); + testString = testString.replace(new RegExp("deoptArg", 'g'), + deoptArg ? JSON.stringify(deoptArg) : "undefined"); + + var modTest = new Function("message", testString); + //print(modTest); + modTest(message); +} + +let checks = { + smiReceiver: + { mkTrainingArguments : () => [{arr:[1], el:3}], + deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}] + }, + objectReceiver: + { mkTrainingArguments : () => [{arr:[{}], el:0.1}], + deoptingArguments : [] + }, + multipleSmiReceivers: + { mkTrainingArguments : () => { let b = [1]; b.x=3; return [{arr:[1], el:3}, {arr:b, el:3}] }, + deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}] + }, + multipleSmiReceiversPackedUnpacked: + { mkTrainingArguments : () => { let b = [1]; b[100] = 3; return [{arr:[1], el:3}, {arr:b, el:3}] }, + deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}] + }, + multipleDoubleReceivers: + { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] }, + deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}] + }, + multipleDoubleReceiversPackedUnpacked: + { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] }, + deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}] + }, + multipleMixedReceivers: + { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] }, + deoptingArguments : [] + }, + multipleMixedReceiversPackedUnpacked: + { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] }, + deoptingArguments : [] + }, +}; + +const functions = { + push_reliable: (a,g) => { let b = g(); return a.push(2, b); }, + push_unreliable: (a,g) => { return a.push(2, g()); }, + pop_reliable: (a,g) => { let b = g(); return a.pop(2, b); }, + pop_unreliable: (a,g) => { return a.pop(2, g()); }, + shift_reliable: (a,g) => { let b = g(); return a.shift(2, b); }, + shift_unreliable: (a,g) => { return a.shift(2, g()); } +} + +Object.keys(checks).forEach( + key => { + let check = checks[key]; + + for (fnc in functions) { + runTest(functions[fnc], "test-reliable-" + key, check.mkTrainingArguments); + // Test each deopting arg separately. + for (let deoptArg of check.deoptingArguments) { + runTest(functions[fnc], "testDeopt-reliable-" + key, check.mkTrainingArguments, deoptArg); + } + } + } +); |