diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-03-12 09:01:49 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-03-14 18:49:21 +0100 |
commit | 7b48713334469818661fe276cf571de9c7899f2d (patch) | |
tree | 4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/test/mjsunit/compiler | |
parent | 8549ac09b256666cf5275224ec58fab9939ff32e (diff) | |
download | node-new-7b48713334469818661fe276cf571de9c7899f2d.tar.gz |
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/test/mjsunit/compiler')
29 files changed, 1038 insertions, 256 deletions
diff --git a/deps/v8/test/mjsunit/compiler/abstract-equal-receiver.js b/deps/v8/test/mjsunit/compiler/abstract-equal-receiver.js new file mode 100644 index 0000000000..1026b68342 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/abstract-equal-receiver.js @@ -0,0 +1,177 @@ +// 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 --noalways-opt + +// Known receivers abstract equality. +(function() { + const a = {}; + const b = {}; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver/null abstract equality. +(function() { + const a = {}; + const b = null; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known null/receiver abstract equality. +(function() { + const a = null; + const b = {}; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver/undefined abstract equality. +(function() { + const a = {}; + const b = undefined; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known undefined/receiver abstract equality. +(function() { + const a = undefined; + const b = {}; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver on one side strict equality. +(function() { + const a = {}; + const b = {}; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + + // TurboFan bakes in feedback for the (unknown) left hand side. + assertFalse(foo(null)); + assertUnoptimized(foo); +})(); + +// Known receiver on one side strict equality with null. +(function() { + const a = null; + const b = {}; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + + // TurboFan bakes in feedback for the (unknown) left hand side. + assertFalse(foo(1)); + assertUnoptimized(foo); +})(); + +// Known receiver on one side strict equality with undefined. +(function() { + const a = undefined; + const b = {}; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + + // TurboFan bakes in feedback for the (unknown) left hand side. + assertFalse(foo(1)); + assertUnoptimized(foo); +})(); + +// Known null on one side strict equality with receiver. +(function() { + const a = {}; + const b = null; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(null)); + assertTrue(foo(undefined)); + assertOptimized(foo); + + // TurboFan doesn't need to bake in feedback, since it sees the null. + assertFalse(foo(1)); + assertOptimized(foo); +})(); + +// Known undefined on one side strict equality with receiver. +(function() { + const a = {}; + const b = undefined; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(null)); + assertTrue(foo(undefined)); + assertOptimized(foo); + + // TurboFan needs to bake in feedback, since undefined cannot + // be context specialized. + assertFalse(foo(1)); + assertUnoptimized(foo); +})(); diff --git a/deps/v8/test/mjsunit/compiler/abstract-equal-undetectable.js b/deps/v8/test/mjsunit/compiler/abstract-equal-undetectable.js new file mode 100644 index 0000000000..1e1bb6ba2d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/abstract-equal-undetectable.js @@ -0,0 +1,119 @@ +// 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 --noalways-opt + +const undetectable = %GetUndetectable(); + +// Known undetectable abstract equality. +(function() { + const a = undetectable; + const b = {}; + + function foo() { return a == b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known undetectable/null abstract equality. +(function() { + const a = undetectable; + const b = null; + + function foo() { return a == b; } + + assertTrue(foo()); + assertTrue(foo()); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo()); +})(); + +// Known undetectable/receiver abstract equality. +(function() { + const a = null; + const b = undetectable; + + function foo() { return a == b; } + + assertTrue(foo()); + assertTrue(foo()); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo()); +})(); + +// Known undetectable/undefined abstract equality. +(function() { + const a = undetectable; + const b = undefined; + + function foo() { return a == b; } + + assertTrue(foo()); + assertTrue(foo()); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo()); +})(); + +// Known undefined/undetectable abstract equality. +(function() { + const a = undefined; + const b = undetectable; + + function foo() { return a == b; } + + assertTrue(foo()); + assertTrue(foo()); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo()); +})(); + +// Known undetectable on one side strict equality with receiver. +(function() { + const a = {}; + const b = undetectable; + + function foo(a) { return a == b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); + + // TurboFan doesn't need to bake in feedback, since it sees the undetectable. + assertFalse(foo(1)); + assertOptimized(foo); +})(); + +// Unknown undetectable on one side strict equality with receiver. +(function() { + const a = undetectable; + const b = {}; + + function foo(a, b) { return a == b; } + + assertTrue(foo(b, b)); + assertFalse(foo(a, b)); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + assertTrue(foo(a, null)); + assertFalse(foo(b, null)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b, b)); + assertFalse(foo(a, b)); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + assertTrue(foo(a, null)); + assertFalse(foo(b, null)); + assertOptimized(foo); + + // TurboFan bakes in feedback on the inputs. + assertFalse(foo(1)); + assertUnoptimized(foo); +})(); diff --git a/deps/v8/test/mjsunit/compiler/array-every.js b/deps/v8/test/mjsunit/compiler/array-every.js new file mode 100644 index 0000000000..5064bd557d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-every.js @@ -0,0 +1,18 @@ +// 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 + +// Basic loop peeling test case with Array.prototype.every(). +(function() { + function foo(a, o) { + return a.every(x => x === o.x); + } + + assertTrue(foo([3, 3, 3], {x:3})); + assertFalse(foo([3, 3, 2], {x:3})); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo([3, 3, 3], {x:3})); + assertFalse(foo([3, 3, 2], {x:3})); +})(); diff --git a/deps/v8/test/mjsunit/compiler/array-find.js b/deps/v8/test/mjsunit/compiler/array-find.js new file mode 100644 index 0000000000..419a758ac7 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-find.js @@ -0,0 +1,18 @@ +// 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 + +// Basic loop peeling test case with Array.prototype.find(). +(function() { + function foo(a, o) { + return a.find(x => x === o.x); + } + + assertEquals(3, foo([1, 2, 3], {x:3})); + assertEquals(undefined, foo([0, 1, 2], {x:3})); + %OptimizeFunctionOnNextCall(foo); + assertEquals(3, foo([1, 2, 3], {x:3})); + assertEquals(undefined, foo([0, 1, 2], {x:3})); +})(); diff --git a/deps/v8/test/mjsunit/compiler/array-findindex.js b/deps/v8/test/mjsunit/compiler/array-findindex.js new file mode 100644 index 0000000000..583f553ce4 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-findindex.js @@ -0,0 +1,18 @@ +// 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 + +// Basic loop peeling test case with Array.prototype.findIndex(). +(function() { + function foo(a, o) { + return a.findIndex(x => x === o.x); + } + + assertEquals(2, foo([1, 2, 3], {x:3})); + assertEquals(-1, foo([0, 1, 2], {x:3})); + %OptimizeFunctionOnNextCall(foo); + assertEquals(2, foo([1, 2, 3], {x:3})); + assertEquals(-1, foo([0, 1, 2], {x:3})); +})(); diff --git a/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js index 3ddff992f7..c26aeda7dc 100644 --- a/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js +++ b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js @@ -3,7 +3,7 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --opt --no-always-opt -// Flags: --no-stress-background-compile +// Flags: --no-stress-background-compile --trace-opt --trace-deopt let id = 0; diff --git a/deps/v8/test/mjsunit/compiler/array-some.js b/deps/v8/test/mjsunit/compiler/array-some.js new file mode 100644 index 0000000000..411a5881de --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-some.js @@ -0,0 +1,18 @@ +// 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 + +// Basic loop peeling test case with Array.prototype.some(). +(function() { + function foo(a, o) { + return a.some(x => x === o.x); + } + + assertTrue(foo([1, 2, 3], {x:3})); + assertFalse(foo([0, 1, 2], {x:3})); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo([1, 2, 3], {x:3})); + assertFalse(foo([0, 1, 2], {x:3})); +})(); diff --git a/deps/v8/test/mjsunit/compiler/dataview-get.js b/deps/v8/test/mjsunit/compiler/dataview-get.js index 78c6bdf4ac..09094399df 100644 --- a/deps/v8/test/mjsunit/compiler/dataview-get.js +++ b/deps/v8/test/mjsunit/compiler/dataview-get.js @@ -173,14 +173,14 @@ assertUnoptimized(readFloat64); assertUnoptimized(readUint8); })(); -// TurboFan neutered buffer deopts. +// TurboFan detached buffer deopts. (function() { function readInt8Handled(offset) { try { return dataview.getInt8(offset); } catch (e) { return e; } } warmup(readInt8Handled); assertOptimized(readInt8Handled); - %ArrayBufferNeuter(buffer); + %ArrayBufferDetach(buffer); assertInstanceof(readInt8Handled(0), TypeError); assertUnoptimized(readInt8Handled); })(); diff --git a/deps/v8/test/mjsunit/compiler/dataview-neutered.js b/deps/v8/test/mjsunit/compiler/dataview-neutered.js index 54b35f73c8..ef485c69db 100644 --- a/deps/v8/test/mjsunit/compiler/dataview-neutered.js +++ b/deps/v8/test/mjsunit/compiler/dataview-neutered.js @@ -2,10 +2,10 @@ // 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 --noalways-opt +// Flags: --allow-natives-syntax --opt --noalways-opt --no-stress-flush-bytecode -// Invalidate the neutering protector. -%ArrayBufferNeuter(new ArrayBuffer(1)); +// Invalidate the detaching protector. +%ArrayBufferDetach(new ArrayBuffer(1)); // Check DataView.prototype.getInt8() optimization. (function() { @@ -21,7 +21,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -43,7 +43,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -65,7 +65,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -87,7 +87,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -109,7 +109,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -131,7 +131,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -153,7 +153,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -175,7 +175,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(dv)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -199,7 +199,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -223,7 +223,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -247,7 +247,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -271,7 +271,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -295,7 +295,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -319,7 +319,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -343,7 +343,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); @@ -367,7 +367,7 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(undefined, foo(dv, 3)); assertOptimized(foo); - %ArrayBufferNeuter(ab); + %ArrayBufferDetach(ab); assertThrows(() => foo(dv, 4), TypeError); assertUnoptimized(foo); %OptimizeFunctionOnNextCall(foo); diff --git a/deps/v8/test/mjsunit/compiler/deopt-inlined-smi.js b/deps/v8/test/mjsunit/compiler/deopt-inlined-smi.js index dda083e5b4..9c0dc99bcb 100644 --- a/deps/v8/test/mjsunit/compiler/deopt-inlined-smi.js +++ b/deps/v8/test/mjsunit/compiler/deopt-inlined-smi.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --always-opt --always-inline-smi-code +// Flags: --always-opt // Test deoptimization into inlined smi code. diff --git a/deps/v8/test/mjsunit/compiler/instance-of-overridden-has-instance.js b/deps/v8/test/mjsunit/compiler/instance-of-overridden-has-instance.js new file mode 100644 index 0000000000..49c8899e69 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/instance-of-overridden-has-instance.js @@ -0,0 +1,106 @@ +// 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 + +(function NonConstHasInstance() { + var C = { + [Symbol.hasInstance] : () => true + }; + + function f() { + return {} instanceof C; + } + + assertTrue(f()); + assertTrue(f()); + %OptimizeFunctionOnNextCall(f); + assertTrue(f()); + C[Symbol.hasInstance] = () => false; + assertFalse(f()); +})(); + +(function NumberHasInstance() { + var C = { + [Symbol.hasInstance] : 0.1 + }; + + function f(b, C) { + if (b) return {} instanceof C; + return false; + } + + function g(b) { + return f(b, C); + } + + assertFalse(f(true, Number)); + assertFalse(f(true, Number)); + assertFalse(g(false)); + assertFalse(g(false)); + %OptimizeFunctionOnNextCall(g); + assertThrows(() => g(true)); +})(); + +(function NonFunctionHasInstance() { + var C = { + [Symbol.hasInstance] : {} + }; + + function f(b, C) { + if (b) return {} instanceof C; + return false; + } + + function g(b) { + return f(b, C); + } + + assertFalse(f(true, Number)); + assertFalse(f(true, Number)); + assertFalse(g(false)); + assertFalse(g(false)); + %OptimizeFunctionOnNextCall(g); + assertThrows(() => g(true)); +})(); + +(function NonConstHasInstanceProto() { + var B = { + [Symbol.hasInstance]() { return true; } + }; + + var C = { __proto__ : B }; + + function f() { + return {} instanceof C; + } + + assertTrue(f()); + assertTrue(f()); + %OptimizeFunctionOnNextCall(f); + assertTrue(f()); + B[Symbol.hasInstance] = () => { return false; }; + assertFalse(f()); +})(); + +(function HasInstanceOverwriteOnProto() { + var A = { + [Symbol.hasInstance] : () => false + } + + var B = { __proto__ : A }; + + var C = { __proto__ : B }; + + function f() { + return {} instanceof C; + } + + assertFalse(f()); + assertFalse(f()); + %OptimizeFunctionOnNextCall(f); + assertFalse(f()); + B[Symbol.hasInstance] = () => { return true; }; + assertTrue(f()); +})(); diff --git a/deps/v8/test/mjsunit/compiler/int64.js b/deps/v8/test/mjsunit/compiler/int64.js index 0a88a95895..b2c53913da 100644 --- a/deps/v8/test/mjsunit/compiler/int64.js +++ b/deps/v8/test/mjsunit/compiler/int64.js @@ -89,3 +89,43 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(0, foo(0xFFFFFFFF)); })(); + +// Test checked Float32->Word64 conversions. +(function() { + function foo(dv, i) { + i = dv.getFloat32(i, true); + return dv.getInt8(i, true); + } + + const dv = new DataView(new ArrayBuffer(10)); + dv.setFloat32(0, 8, true); + dv.setFloat32(4, 9, true); + dv.setInt8(8, 42); + dv.setInt8(9, 24); + + assertEquals(42, foo(dv, 0)); + assertEquals(24, foo(dv, 4)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(42, foo(dv, 0)); + assertEquals(24, foo(dv, 4)); +})(); + +// Test checked Float64->Word64 conversions. +(function() { + function foo(dv, i) { + i = dv.getFloat64(i, true); + return dv.getInt8(i, true); + } + + const dv = new DataView(new ArrayBuffer(18)); + dv.setFloat64(0, 16, true); + dv.setFloat64(8, 17, true); + dv.setInt8(16, 42); + dv.setInt8(17, 24); + + assertEquals(42, foo(dv, 0)); + assertEquals(24, foo(dv, 8)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(42, foo(dv, 0)); + assertEquals(24, foo(dv, 8)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/lazy-deopt-async-function-resolve.js b/deps/v8/test/mjsunit/compiler/lazy-deopt-async-function-resolve.js new file mode 100644 index 0000000000..faa5e63239 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/lazy-deopt-async-function-resolve.js @@ -0,0 +1,27 @@ +// 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 + +// Test that the lazy deoptimization point for JSAsyncFunctionResolve +// works correctly, aka that we return the promise and not the result +// of the JSResolvePromise operation. +(function() { + async function foo(x) { + return x; + } + + assertPromiseResult((async () => { + await foo(1); + await foo(2); + %OptimizeFunctionOnNextCall(foo); + const p = new Proxy({}, { + get(...args) { + %DeoptimizeFunction(foo); + return Reflect.get(...args); + } + }); + assertEquals(p, await foo(p)); + })()); +})(); diff --git a/deps/v8/test/mjsunit/compiler/native-context-specialization-hole-check.js b/deps/v8/test/mjsunit/compiler/native-context-specialization-hole-check.js index 1256f453eb..7f4db56483 100644 --- a/deps/v8/test/mjsunit/compiler/native-context-specialization-hole-check.js +++ b/deps/v8/test/mjsunit/compiler/native-context-specialization-hole-check.js @@ -27,6 +27,11 @@ // Flags: --allow-natives-syntax --opt --no-always-opt +if (isNeverOptimizeLiteMode()) { + print("Warning: skipping test that requires optimization in Lite mode."); + quit(0); +} + function f() { Array.prototype[10] = 2; var arr = new Array(); diff --git a/deps/v8/test/mjsunit/compiler/number-max.js b/deps/v8/test/mjsunit/compiler/number-max.js index 7e5a4a4ad1..0e9b84fb39 100644 --- a/deps/v8/test/mjsunit/compiler/number-max.js +++ b/deps/v8/test/mjsunit/compiler/number-max.js @@ -21,3 +21,17 @@ assertEquals(0, foo(0)); assertOptimized(foo); })(); + +// Test that NumberMax properly handles 64-bit comparisons. +(function() { + function foo(x) { + x = x|0; + return Math.max(x - 1, x + 1); + } + + assertEquals(-Math.pow(2, 31) + 1, foo(-Math.pow(2, 31))); + assertEquals(Math.pow(2, 31), foo(Math.pow(2, 31) - 1)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(-Math.pow(2, 31) + 1, foo(-Math.pow(2, 31))); + assertEquals(Math.pow(2, 31), foo(Math.pow(2, 31) - 1)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/number-min.js b/deps/v8/test/mjsunit/compiler/number-min.js index 72bff78686..6c7c62d773 100644 --- a/deps/v8/test/mjsunit/compiler/number-min.js +++ b/deps/v8/test/mjsunit/compiler/number-min.js @@ -21,3 +21,17 @@ assertEquals(1, foo(0)); assertOptimized(foo); })(); + +// Test that NumberMin properly handles 64-bit comparisons. +(function() { + function foo(x) { + x = x|0; + return Math.min(x - 1, x + 1); + } + + assertEquals(-Math.pow(2, 31) - 1, foo(-Math.pow(2, 31))); + assertEquals(Math.pow(2, 31) - 2, foo(Math.pow(2, 31) - 1)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(-Math.pow(2, 31) - 1, foo(-Math.pow(2, 31))); + assertEquals(Math.pow(2, 31) - 2, foo(Math.pow(2, 31) - 1)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/number-modulus.js b/deps/v8/test/mjsunit/compiler/number-modulus.js index 5f695d1ee5..0925aa0da3 100644 --- a/deps/v8/test/mjsunit/compiler/number-modulus.js +++ b/deps/v8/test/mjsunit/compiler/number-modulus.js @@ -4,178 +4,6 @@ // Flags: --allow-natives-syntax --opt --noalways-opt -// Test that NumberModulus with Number feedback works if only in the -// end SimplifiedLowering figures out that the inputs to this operation -// are actually Unsigned32. -(function() { - // We need a separately polluted % with NumberOrOddball feedback. - function bar(x) { return x % 2; } - bar(undefined); // The % feedback is now NumberOrOddball. - - // Now just use the gadget above in a way that only after RETYPE - // in SimplifiedLowering we find out that the `x` is actually in - // Unsigned32 range (based on taking the SignedSmall feedback on - // the + operator). - function foo(x) { - x = (x >>> 0) + 1; - return bar(x) | 0; - } - - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - assertOptimized(foo); -})(); - -// Test that NumberModulus with Number feedback works if only in the -// end SimplifiedLowering figures out that the inputs to this operation -// are actually Signed32. -(function() { - // We need a separately polluted % with NumberOrOddball feedback. - function bar(x) { return x % 2; } - bar(undefined); // The % feedback is now NumberOrOddball. - - // Now just use the gadget above in a way that only after RETYPE - // in SimplifiedLowering we find out that the `x` is actually in - // Signed32 range (based on taking the SignedSmall feedback on - // the + operator). - function foo(x) { - x = (x | 0) + 1; - return bar(x) | 0; - } - - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - assertOptimized(foo); -})(); - -// Test that SpeculativeNumberModulus with Number feedback works if -// only in the end SimplifiedLowering figures out that the inputs to -// this operation are actually Unsigned32. -(function() { - // We need to use an object literal here to make sure that the - // SpeculativeNumberModulus is not turned into a NumberModulus - // early during JSTypedLowering. - function bar(x) { return {x}.x % 2; } - bar(undefined); // The % feedback is now NumberOrOddball. - - // Now just use the gadget above in a way that only after RETYPE - // in SimplifiedLowering we find out that the `x` is actually in - // Unsigned32 range (based on taking the SignedSmall feedback on - // the + operator). - function foo(x) { - x = (x >>> 0) + 1; - return bar(x) | 0; - } - - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - assertOptimized(foo); -})(); - -// Test that SpeculativeNumberModulus with Number feedback works if -// only in the end SimplifiedLowering figures out that the inputs to -// this operation are actually Signed32. -(function() { - // We need to use an object literal here to make sure that the - // SpeculativeNumberModulus is not turned into a NumberModulus - // early during JSTypedLowering. - function bar(x) { return {x}.x % 2; } - bar(undefined); // The % feedback is now NumberOrOddball. - - // Now just use the gadget above in a way that only after RETYPE - // in SimplifiedLowering we find out that the `x` is actually in - // Signed32 range (based on taking the SignedSmall feedback on - // the + operator). - function foo(x) { - x = (x | 0) + 1; - return bar(x) | 0; - } - - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(1)); - assertEquals(1, foo(2)); - assertEquals(0, foo(3)); - assertEquals(1, foo(4)); - assertOptimized(foo); -})(); - -// Test that NumberModulus works in the case where TurboFan -// can infer that the output is Signed32 \/ MinusZero, and -// there's a truncation on the result that identifies zeros -// (via the SpeculativeNumberEqual). -(function() { - // We need a separately polluted % with NumberOrOddball feedback. - function bar(x) { return x % 2; } - bar(undefined); // The % feedback is now NumberOrOddball. - - // Now we just use the gadget above on an `x` that is known - // to be in Signed32 range and compare it to 0, which passes - // a truncation that identifies zeros. - function foo(x) { - if (bar(x | 0) == 0) return 0; - return 1; - } - - assertEquals(0, foo(2)); - assertEquals(1, foo(1)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(2)); - assertEquals(1, foo(1)); - assertOptimized(foo); - - // Now `foo` should stay optimized even if `x % 2` would - // produce -0, aka when we pass a negative value for `x`. - assertEquals(0, foo(-2)); - assertEquals(1, foo(-1)); - assertOptimized(foo); -})(); - -// Test that CheckedInt32Mod handles the slow-path (when -// the left hand side is negative) correctly. -(function() { - // We need a SpeculativeNumberModulus with SignedSmall feedback. - function foo(x, y) { - return x % y; - } - - assertEquals(0, foo(2, 1)); - assertEquals(0, foo(2, 2)); - assertEquals(-1, foo(-3, 2)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(2, 1)); - assertEquals(0, foo(2, 2)); - assertEquals(-1, foo(-3, 2)); - assertOptimized(foo); - - // Now `foo` should deoptimize if the result is -0. - assertEquals(-0, foo(-2, 2)); - assertUnoptimized(foo); -})(); // Test that NumberModulus passes kIdentifiesZero to the // left hand side input when the result doesn't care about @@ -196,61 +24,3 @@ assertTrue(foo(0)); assertOptimized(foo); })(); - -// Test that NumberModulus passes kIdentifiesZero to the -// right hand side input, even when the inputs are outside -// the Signed32 range. -(function() { - function foo(x) { - return (2 ** 32) % (x * -2); - } - - assertEquals(0, foo(1)); - assertEquals(0, foo(1)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(1)); - - // Now `foo` should stay optimized even if `x * -2` would - // produce -0, aka when we pass a zero value for `x`. - assertEquals(NaN, foo(0)); - assertOptimized(foo); -})(); - -// Test that SpeculativeNumberModulus passes kIdentifiesZero -// to the right hand side input, even when feedback is consumed. -(function() { - function foo(x, y) { - return (x % (y * -2)) | 0; - } - - assertEquals(0, foo(2, 1)); - assertEquals(-1, foo(-3, 1)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(0, foo(2, 1)); - assertEquals(-1, foo(-3, 1)); - assertOptimized(foo); - - // Now `foo` should stay optimized even if `y * -2` would - // produce -0, aka when we pass a zero value for `y`. - assertEquals(0, foo(2, 0)); - assertOptimized(foo); -})(); - -// Test that SpeculativeNumberModulus passes kIdentifiesZero -// to the left hand side input, even when feedback is consumed. -(function() { - function foo(x, y) { - return ((x * -2) % y) | 0; - } - - assertEquals(-2, foo(1, 3)); - assertEquals(-2, foo(1, 3)); - %OptimizeFunctionOnNextCall(foo); - assertEquals(-2, foo(1, 3)); - assertOptimized(foo); - - // Now `foo` should stay optimized even if `x * -2` would - // produce -0, aka when we pass a zero value for `x`. - assertEquals(0, foo(0, 2)); - assertOptimized(foo); -})(); diff --git a/deps/v8/test/mjsunit/compiler/number-multiply.js b/deps/v8/test/mjsunit/compiler/number-multiply.js new file mode 100644 index 0000000000..5b644974ec --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/number-multiply.js @@ -0,0 +1,59 @@ +// 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 + +// Test the extreme case where -0 is produced by rounding errors. +(function() { + function bar(x) { + return 1e-308 * x; + } + bar(1); + + function foo() { + return Object.is(-0, bar(-1e-308)); + } + + assertTrue(foo()); + assertTrue(foo()); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo()); +})(); + +// Test that multiplication of integer by 0 produces the correct results. +(function() { + function foo(x) { + return 0 * Math.round(x); + } + + assertEquals(0, foo(0.1)); + assertEquals(-0, foo(-0.1)); + assertEquals(NaN, foo(NaN)); + assertEquals(NaN, foo(Infinity)); + assertEquals(NaN, foo(-Infinity)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(0.1)); + assertEquals(-0, foo(-0.1)); + assertEquals(NaN, foo(NaN)); + assertEquals(NaN, foo(Infinity)); + assertEquals(NaN, foo(-Infinity)); +})(); + +// Test that multiplication properly preserves -0 and NaN, and doesn't +// cut it short incorrectly. +(function() { + function foo(x, y) { + x = Math.sign(x); + y = Math.sign(y); + return Math.min(x * y, 0); + } + + assertEquals(0, foo(1, 0)); + assertEquals(-0, foo(1, -0)); + assertEquals(NaN, foo(NaN, -0)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(1, 0)); + assertEquals(-0, foo(1, -0)); + assertEquals(NaN, foo(NaN, -0)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/osr-assert.js b/deps/v8/test/mjsunit/compiler/osr-assert.js index 94b901fd4f..c67ad536ad 100644 --- a/deps/v8/test/mjsunit/compiler/osr-assert.js +++ b/deps/v8/test/mjsunit/compiler/osr-assert.js @@ -25,17 +25,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --use-osr +// Flags: --use-osr --allow-natives-syntax function f(x, b, c) { - var outer = 1000000; + var outer = 10; var a = 1; while (outer > 0) { a = a + 5; assertEquals(b + 1, c); outer--; + if (outer === 5) { + %OptimizeOsr(); + } } return a + 4; } -assertEquals(5000005, f(5, "122", "1221")); +assertEquals(55, f(5, "122", "1221")); diff --git a/deps/v8/test/mjsunit/compiler/promise-resolve-stable-maps.js b/deps/v8/test/mjsunit/compiler/promise-resolve-stable-maps.js new file mode 100644 index 0000000000..7acd891b9b --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/promise-resolve-stable-maps.js @@ -0,0 +1,61 @@ +// 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 --noalways-opt + +// Test that JSResolvePromise takes a proper stability dependency +// on the resolutions map if the infer receiver maps are unreliable +// (as is the case for HeapConstants). +(function() { + // We need an object literal which gets a stable map initially. + function makeObjectWithStableMap() { + return {a:1, b:1, c:1}; + } + const a = makeObjectWithStableMap(); + + function foo() { + return Promise.resolve(a); + } + + assertInstanceof(foo(), Promise); + assertInstanceof(foo(), Promise); + %OptimizeFunctionOnNextCall(foo); + assertInstanceof(foo(), Promise); + assertOptimized(foo); + + // Now invalidate the stability of a's map. + const b = makeObjectWithStableMap(); + b.d = 1; + + // This should deoptimize foo. + assertUnoptimized(foo); +})(); + +// Same test with async functions. +(function() { + // We need an object literal which gets a stable map initially, + // it needs to be different from the above, otherwise the map + // is already not stable when we get here. + function makeObjectWithStableMap() { + return {x:1, y:1}; + } + const a = makeObjectWithStableMap(); + + async function foo() { + return a; + } + + assertInstanceof(foo(), Promise); + assertInstanceof(foo(), Promise); + %OptimizeFunctionOnNextCall(foo); + assertInstanceof(foo(), Promise); + assertOptimized(foo); + + // Now invalidate the stability of a's map. + const b = makeObjectWithStableMap(); + b.z = 1; + + // This should deoptimize foo. + assertUnoptimized(foo); +})(); diff --git a/deps/v8/test/mjsunit/compiler/regress-8380.js b/deps/v8/test/mjsunit/compiler/regress-8380.js new file mode 100644 index 0000000000..d0bf28571e --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-8380.js @@ -0,0 +1,32 @@ +// 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 + +function reduceLHS() { + for (var i = 0; i < 2 ;i++) { + let [q, r] = [1n, 1n]; + r = r - 1n; + q += 1n; + q = r; + } +} + +reduceLHS(); +%OptimizeFunctionOnNextCall(reduceLHS); +reduceLHS(); + + +function reduceRHS() { + for (var i = 0; i < 2 ;i++) { + let [q, r] = [1n, 1n]; + r = 1n - r; + q += 1n; + q = r; + } +} + +reduceRHS(); +%OptimizeFunctionOnNextCall(reduceRHS); +reduceRHS(); diff --git a/deps/v8/test/mjsunit/compiler/regress-902608.js b/deps/v8/test/mjsunit/compiler/regress-902608.js new file mode 100644 index 0000000000..faa9ec49df --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-902608.js @@ -0,0 +1,16 @@ +// 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 + +async function f() { + var a = [...new Int8Array([, ...new Uint8Array(65536)])]; + var p = new Proxy([f], { + set: function () { }, + done: undefined.prototype + }); +} + +f() +f(); diff --git a/deps/v8/test/mjsunit/compiler/regress-905555-2.js b/deps/v8/test/mjsunit/compiler/regress-905555-2.js new file mode 100644 index 0000000000..5852c6dd43 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-905555-2.js @@ -0,0 +1,25 @@ +// 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 --block-concurrent-recompilation --noalways-opt + +global = 1; + +function boom(value) { + return global; +} + +assertEquals(1, boom()); +assertEquals(1, boom()); +%OptimizeFunctionOnNextCall(boom, "concurrent"); +assertEquals(1, boom()); + +delete this.global; + +%UnblockConcurrentRecompilation(); + +// boom should be deoptimized because the global property cell has changed. +assertUnoptimized(boom, "sync"); + +assertThrows(boom); diff --git a/deps/v8/test/mjsunit/compiler/regress-905555.js b/deps/v8/test/mjsunit/compiler/regress-905555.js new file mode 100644 index 0000000000..bc7ba7428e --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-905555.js @@ -0,0 +1,25 @@ +// 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 --block-concurrent-recompilation --noalways-opt + +global = 1; + +function boom(value) { + return global; +} + +assertEquals(1, boom()); +assertEquals(1, boom()); +%OptimizeFunctionOnNextCall(boom, "concurrent"); +assertEquals(1, boom()); + +this.__defineGetter__("global", () => 42); + +%UnblockConcurrentRecompilation(); + +// boom should be deoptimized because the global property cell has changed. +assertUnoptimized(boom, "sync"); + +assertEquals(42, boom()); diff --git a/deps/v8/test/mjsunit/compiler/regress-910838.js b/deps/v8/test/mjsunit/compiler/regress-910838.js new file mode 100644 index 0000000000..6e62a453e0 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-910838.js @@ -0,0 +1,20 @@ +// 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 + +function f(b, s, x) { + if (!b) { + return (x ? b : s * undefined) ? 1 : 42; + } +} + +function g(b, x) { + return f(b, 'abc', x); +} + +f(false, 0, 0); +g(true, 0); +%OptimizeFunctionOnNextCall(g); +assertEquals(42, g(false, 0)); diff --git a/deps/v8/test/mjsunit/compiler/regress-913232.js b/deps/v8/test/mjsunit/compiler/regress-913232.js new file mode 100644 index 0000000000..efd7fb8e5f --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-913232.js @@ -0,0 +1,14 @@ +// 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 + +function* E(b) { + while (true) { + for (yield* 0; b; yield* 0) {} + } +} + +%OptimizeFunctionOnNextCall(E); +E(); diff --git a/deps/v8/test/mjsunit/compiler/regress-919754.js b/deps/v8/test/mjsunit/compiler/regress-919754.js new file mode 100644 index 0000000000..5f20aad928 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-919754.js @@ -0,0 +1,15 @@ +// Copyright 2019 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 + + +function f(get, ...a) { + for (let i = 0; i < 1000; i++) { + if (i === 999) %OptimizeOsr(); + a.map(f); + } + return get(); +} +assertThrows(f); diff --git a/deps/v8/test/mjsunit/compiler/strict-equal-number.js b/deps/v8/test/mjsunit/compiler/strict-equal-number.js new file mode 100644 index 0000000000..18cd52aa01 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/strict-equal-number.js @@ -0,0 +1,16 @@ +// 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 + +// Make sure that we don't incorrectly truncate Oddball +// to Number for strict equality comparisons. +(function() { + function foo(x, y) { return x === y; } + + assertTrue(foo(0.1, 0.1)); + assertTrue(foo(undefined, undefined)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(undefined, undefined)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/strict-equal-receiver.js b/deps/v8/test/mjsunit/compiler/strict-equal-receiver.js new file mode 100644 index 0000000000..1f38d79dfa --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/strict-equal-receiver.js @@ -0,0 +1,152 @@ +// 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 --noalways-opt + +// Known receivers strict equality. +(function() { + const a = {}; + const b = {}; + + function foo() { return a === b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver/null strict equality. +(function() { + const a = {}; + const b = null; + + function foo() { return a === b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver/undefined strict equality. +(function() { + const a = {}; + const b = undefined; + + function foo() { return a === b; } + + assertFalse(foo()); + assertFalse(foo()); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo()); +})(); + +// Known receiver on one side strict equality. +(function() { + const a = {}; + const b = {}; + + function foo(a) { return a === b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); +})(); + +// Known receiver on one side strict equality. +(function() { + const a = {}; + const b = null; + + function foo(a) { return a === b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); +})(); + +// Known receiver on one side strict equality. +(function() { + const a = {}; + const b = undefined; + + function foo(a) { return a === b; } + + assertTrue(foo(b)); + assertFalse(foo(a)); + assertTrue(foo(b)); + assertFalse(foo(a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(b)); + assertFalse(foo(a)); +})(); + +// Feedback based receiver strict equality. +(function() { + const a = {}; + const b = {}; + + function foo(a, b) { return a === b; } + + assertTrue(foo(b, b)); + assertFalse(foo(a, b)); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + + // TurboFan bakes in feedback for the left hand side. + assertFalse(foo(null, b)); + assertUnoptimized(foo); +})(); + +// Feedback based receiver/null strict equality. +(function() { + const a = {}; + const b = null; + + function foo(a, b) { return a === b; } + + assertTrue(foo(b, b)); + assertFalse(foo(a, b)); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + + // TurboFan bakes in feedback for the left hand side. + assertFalse(foo(1, b)); + assertUnoptimized(foo); +})(); + +// Feedback based receiver/undefined strict equality. +(function() { + const a = {}; + const b = undefined; + + function foo(a, b) { return a === b; } + + assertTrue(foo(b, b)); + assertFalse(foo(a, b)); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(a, a)); + assertFalse(foo(b, a)); + + // TurboFan bakes in feedback for the left hand side. + assertFalse(foo(1, b)); + assertUnoptimized(foo); +})(); |