diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-03-07 08:54:53 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-03-07 16:48:52 +0100 |
commit | 88786fecff336342a56e6f2e7ff3b286be716e47 (patch) | |
tree | 92e6ba5b8ac8dae1a058988d20c9d27bfa654390 /deps/v8/test/mjsunit/optimized-array-some.js | |
parent | 4e86f9b5ab83cbabf43839385bf383e6a7ef7d19 (diff) | |
download | android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.tar.gz android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.tar.bz2 android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.zip |
deps: update V8 to 6.5.254.31
PR-URL: https://github.com/nodejs/node/pull/18453
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'deps/v8/test/mjsunit/optimized-array-some.js')
-rw-r--r-- | deps/v8/test/mjsunit/optimized-array-some.js | 502 |
1 files changed, 502 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/optimized-array-some.js b/deps/v8/test/mjsunit/optimized-array-some.js new file mode 100644 index 0000000000..8d0114aa64 --- /dev/null +++ b/deps/v8/test/mjsunit/optimized-array-some.js @@ -0,0 +1,502 @@ +// Copyright 2017 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 --turbo-inline-array-builtins --opt +// Flags: --no-always-opt + +// Early exit from some functions properly. +(() => { + const a = [1, 2, 3, 4, 5]; + let result = 0; + function earlyExit() { + return a.some(v => { + result += v; + return v > 2; + }); + } + assertTrue(earlyExit()); + earlyExit(); + %OptimizeFunctionOnNextCall(earlyExit); + assertTrue(earlyExit()); + assertEquals(18, result); +})(); + +// Soft-deopt plus early exit. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let result = 0; + function softyPlusEarlyExit(deopt) { + return a.some(v => { + result += v; + if (v === 4 && deopt) { + a.abc = 25; + } + return v > 7; + }); + } + assertTrue(softyPlusEarlyExit(false)); + softyPlusEarlyExit(false); + %OptimizeFunctionOnNextCall(softyPlusEarlyExit); + assertTrue(softyPlusEarlyExit(true)); + assertEquals(36*3, result); +})(); + +// Soft-deopt synced with early exit, which forces the lazy deoptimization +// continuation handler to exit. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let called_values = []; + function softyPlusEarlyExit(deopt) { + called_values = []; + return a.some(v => { + called_values.push(v); + if (v === 4 && deopt) { + a.abc = 25; + return true; + } + return v > 7; + }); + } + assertTrue(softyPlusEarlyExit(false)); + assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values); + softyPlusEarlyExit(false); + %OptimizeFunctionOnNextCall(softyPlusEarlyExit); + assertTrue(softyPlusEarlyExit(true)); + assertArrayEquals([1, 2, 3, 4], called_values); +})(); + +// Unknown field access leads to soft-deopt unrelated to some, should still +// lead to correct result. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25]; + let result = 0; + function eagerDeoptInCalled(deopt) { + return a.some((v, i) => { + if (i === 13 && deopt) { + a.abc = 25; + } + result += v; + return false; + }); + } + eagerDeoptInCalled(); + eagerDeoptInCalled(); + %OptimizeFunctionOnNextCall(eagerDeoptInCalled); + eagerDeoptInCalled(); + assertFalse(eagerDeoptInCalled(true)); + eagerDeoptInCalled(); + assertEquals(1625, result); +})(); + +// Length change detected during loop, must cause properly handled eager deopt. +(() => { + let called_values; + function eagerDeoptInCalled(deopt) { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + called_values = []; + return a.some((v,i) => { + called_values.push(v); + a.length = (i === 5 && deopt) ? 8 : 10; + return false; + }); + } + assertFalse(eagerDeoptInCalled()); + assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], called_values); + eagerDeoptInCalled(); + %OptimizeFunctionOnNextCall(eagerDeoptInCalled); + assertFalse(eagerDeoptInCalled()); + assertFalse(eagerDeoptInCalled(true)); + assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values); + eagerDeoptInCalled(); +})(); + +// Lazy deopt from a callback that changes the input array. Deopt in a callback +// execution that returns true. +(() => { + const a = [1, 2, 3, 4, 5]; + function lazyChanger(deopt) { + return a.some((v, i) => { + if (i === 3 && deopt) { + a[3] = 100; + %DeoptimizeNow(); + } + return false; + }); + } + assertFalse(lazyChanger()); + lazyChanger(); + %OptimizeFunctionOnNextCall(lazyChanger); + assertFalse(lazyChanger(true)); + assertFalse(lazyChanger()); +})(); + +// Lazy deopt from a callback that will always return false and no element is +// found. Verifies the lazy-after-callback continuation builtin. +(() => { + const a = [1, 2, 3, 4, 5]; + function lazyChanger(deopt) { + return a.some((v, i) => { + if (i === 3 && deopt) { + %DeoptimizeNow(); + } + return false; + }); + } + assertFalse(lazyChanger()); + lazyChanger(); + %OptimizeFunctionOnNextCall(lazyChanger); + assertFalse(lazyChanger(true)); + assertFalse(lazyChanger()); +})(); + +// Lazy deopt from a callback that changes the input array. Deopt in a callback +// execution that returns false. +(() => { + const a = [1, 2, 3, 4, 5]; + function lazyChanger(deopt) { + return a.every((v, i) => { + if (i === 2 && deopt) { + a[3] = 100; + %DeoptimizeNow(); + } + return false; + }); + } + assertFalse(lazyChanger()); + lazyChanger(); + %OptimizeFunctionOnNextCall(lazyChanger); + assertFalse(lazyChanger(true)); + assertFalse(lazyChanger()); +})(); + +// Escape analyzed array +(() => { + let result = 0; + function eagerDeoptInCalled(deopt) { + const a_noescape = [0, 1, 2, 3, 4, 5]; + a_noescape.some((v, i) => { + result += v | 0; + if (i === 13 && deopt) { + a_noescape.length = 25; + } + return false; + }); + } + eagerDeoptInCalled(); + eagerDeoptInCalled(); + %OptimizeFunctionOnNextCall(eagerDeoptInCalled); + eagerDeoptInCalled(); + eagerDeoptInCalled(true); + eagerDeoptInCalled(); + assertEquals(75, result); +})(); + +// Lazy deopt from runtime call from inlined callback function. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25]; + let result = 0; + function lazyDeopt(deopt) { + a.some((v, i) => { + result += i; + if (i === 13 && deopt) { + %DeoptimizeNow(); + } + return false; + }); + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + lazyDeopt(); + lazyDeopt(true); + lazyDeopt(); + assertEquals(1500, result); +})(); + +// Lazy deopt from runtime call from non-inline callback function. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25]; + let result = 0; + function lazyDeopt(deopt) { + function callback(v, i) { + result += i; + if (i === 13 && deopt) { + %DeoptimizeNow(); + } + return false; + } + %NeverOptimizeFunction(callback); + a.some(callback); + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + lazyDeopt(); + lazyDeopt(true); + lazyDeopt(); + assertEquals(1500, result); +})(); + +// Call to a.some is done inside a try-catch block and the callback function +// being called actually throws. +(() => { + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25]; + let caught = false; + function lazyDeopt(deopt) { + try { + a.some((v, i) => { + if (i === 1 && deopt) { + throw("a"); + } + return false; + }); + } catch (e) { + caught = true; + } + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + lazyDeopt(); + assertDoesNotThrow(() => lazyDeopt(true)); + assertTrue(caught); + lazyDeopt(); +})(); + +// Call to a.some is done inside a try-catch block and the callback function +// being called actually throws, but the callback is not inlined. +(() => { + let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let caught = false; + function lazyDeopt(deopt) { + function callback(v, i) { + if (i === 1 && deopt) { + throw("a"); + } + return false; + } + %NeverOptimizeFunction(callback); + try { + a.some(callback); + } catch (e) { + caught = true; + } + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + lazyDeopt(); + assertDoesNotThrow(() => lazyDeopt(true)); + assertTrue(caught); + lazyDeopt(); +})(); + +// Call to a.some is done inside a try-catch block and the callback function +// being called throws into a deoptimized caller function. +(function TestThrowIntoDeoptimizedOuter() { + const a = [1, 2, 3, 4]; + function lazyDeopt(deopt) { + function callback(v, i) { + if (i === 1 && deopt) { + %DeoptimizeFunction(lazyDeopt); + throw "some exception"; + } + return false; + } + %NeverOptimizeFunction(callback); + let result = 0; + try { + result = a.some(callback); + } catch (e) { + assertEquals("some exception", e); + result = "nope"; + } + return result; + } + assertEquals(false, lazyDeopt(false)); + assertEquals(false, lazyDeopt(false)); + assertEquals("nope", lazyDeopt(true)); + assertEquals("nope", lazyDeopt(true)); + %OptimizeFunctionOnNextCall(lazyDeopt); + assertEquals(false, lazyDeopt(false)); + assertEquals("nope", lazyDeopt(true)); +})(); + +// An error generated inside the callback includes some in it's +// stack trace. +(() => { + const re = /Array\.some/; + function lazyDeopt(deopt) { + const b = [1, 2, 3]; + let result = 0; + b.some((v, i) => { + result += v; + if (i === 1) { + const e = new Error(); + assertTrue(re.exec(e.stack) !== null); + } + return false; + }); + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + lazyDeopt(); +})(); + +// An error generated inside a non-inlined callback function also +// includes some in it's stack trace. +(() => { + const re = /Array\.some/; + function lazyDeopt(deopt) { + const b = [1, 2, 3]; + let did_assert_error = false; + let result = 0; + function callback(v, i) { + result += v; + if (i === 1) { + const e = new Error(); + assertTrue(re.exec(e.stack) !== null); + did_assert_error = true; + } + return false; + } + %NeverOptimizeFunction(callback); + b.some(callback); + return did_assert_error; + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + assertTrue(lazyDeopt()); +})(); + +// An error generated inside a recently deoptimized callback function +// includes some in it's stack trace. +(() => { + const re = /Array\.some/; + function lazyDeopt(deopt) { + const b = [1, 2, 3]; + let did_assert_error = false; + let result = 0; + b.some((v, i) => { + result += v; + if (i === 1) { + %DeoptimizeNow(); + } else if (i === 2) { + const e = new Error(); + assertTrue(re.exec(e.stack) !== null); + did_assert_error = true; + } + return false; + }); + return did_assert_error; + } + lazyDeopt(); + lazyDeopt(); + %OptimizeFunctionOnNextCall(lazyDeopt); + assertTrue(lazyDeopt()); +})(); + +// Verify that various exception edges are handled appropriately. +// The thrown Error object should always indicate it was created from +// a some call stack. +(() => { + const re = /Array\.some/; + const a = [1, 2, 3]; + let result = 0; + function lazyDeopt() { + a.some((v, i) => { + result += i; + if (i === 1) { + %DeoptimizeFunction(lazyDeopt); + throw new Error(); + } + return false; + }); + } + assertThrows(() => lazyDeopt()); + assertThrows(() => lazyDeopt()); + try { + lazyDeopt(); + } catch (e) { + assertTrue(re.exec(e.stack) !== null); + } + %OptimizeFunctionOnNextCall(lazyDeopt); + try { + lazyDeopt(); + } catch (e) { + assertTrue(re.exec(e.stack) !== null); + } +})(); + +// Messing with the Array prototype causes deoptimization. +(() => { + const a = [1, 2, 3]; + let result = 0; + function prototypeChanged() { + a.some((v, i) => { + result += v; + return false; + }); + } + prototypeChanged(); + prototypeChanged(); + %OptimizeFunctionOnNextCall(prototypeChanged); + prototypeChanged(); + a.constructor = {}; + prototypeChanged(); + assertUnoptimized(prototypeChanged); + assertEquals(24, result); +})(); + +// Verify holes are skipped. +(() => { + const a = [1, 2, , 3, 4]; + function withHoles() { + const callback_values = []; + a.some(v => { + callback_values.push(v); + return false; + }); + return callback_values; + } + withHoles(); + withHoles(); + %OptimizeFunctionOnNextCall(withHoles); + assertArrayEquals([1, 2, 3, 4], withHoles()); +})(); + +(() => { + const a = [1.5, 2.5, , 3.5, 4.5]; + function withHoles() { + const callback_values = []; + a.some(v => { + callback_values.push(v); + return false; + }); + return callback_values; + } + withHoles(); + withHoles(); + %OptimizeFunctionOnNextCall(withHoles); + assertArrayEquals([1.5, 2.5, 3.5, 4.5], withHoles()); +})(); + +// Handle callback is not callable. +(() => { + const a = [1, 2, 3, 4, 5]; + function notCallable() { + return a.some(undefined); + } + + assertThrows(notCallable, TypeError); + try { notCallable(); } catch(e) { } + %OptimizeFunctionOnNextCall(notCallable); + assertThrows(notCallable, TypeError); +})(); |