diff options
Diffstat (limited to 'deps/v8/test/mjsunit/compiler')
20 files changed, 1033 insertions, 29 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 index 8699346bf2..3ddff992f7 100644 --- a/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js +++ b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js @@ -3,6 +3,7 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --opt --no-always-opt +// Flags: --no-stress-background-compile let id = 0; diff --git a/deps/v8/test/mjsunit/compiler/array-slice-clone.js b/deps/v8/test/mjsunit/compiler/array-slice-clone.js new file mode 100644 index 0000000000..610fa17c1a --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/array-slice-clone.js @@ -0,0 +1,365 @@ +// 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 CloneFastJSArray inserted by JSCallReducer for Array.prototype.slice. +// CloneFastJSArray produces COW arrays if the original array is COW. + +// Trigger JSCallReducer on slice() and slice(0) +(function() { + const arr = [1,2,3,4,5]; + + function slice() { + return arr.slice(); + } + + function slice0() { + return arr.slice(0); + } + + assertEquals(arr, slice()); + assertFalse(arr === slice()); + assertEquals(slice(), slice0()); + assertEquals(slice0(), slice()); + + %OptimizeFunctionOnNextCall(slice0); + %OptimizeFunctionOnNextCall(slice); + + assertEquals(slice(), slice0()); + assertOptimized(slice); assertOptimized(slice0); +})(); + +// This will cause deopt of slice by a CheckMap installed by +// JSNativeContextSpecialization::ReduceNamedAccess +(function() { + const arr = [1,2,3,4,5]; + + function slice() { + return arr.slice(); + } + + assertEquals(arr, slice()); + assertEquals(slice(), arr); + + %OptimizeFunctionOnNextCall(slice); + slice(); + + // Trigger deopt here + arr.push(7.2); + assertEquals(slice()[5], 7.2); +})(); + +// There should not be a deopt cycle. +(function() { + const arr = [1,2,3,4,5]; + + function slice() { + return arr.slice(); + } + + assertEquals(arr, slice()); + assertEquals(slice(), arr); + + %OptimizeFunctionOnNextCall(slice); + // Trigger opt + assertEquals(slice(), arr); + + // Trigger deopt by CheckMap from JSNativeContextSpecialization + arr.push(7.2); + slice(); + + %OptimizeFunctionOnNextCall(slice); + // Trigger opt again + slice(); + + // Should not deopt again + arr.push(8.2); + slice(); + assertOptimized(slice); +})(); + +// JSCallReducer will not reduce because the species has been modified +(function() { + const array = [3,4,5]; + + function slice(){ + return array.slice(); + } + + class MyArray extends Array {}; + array.constructor = MyArray; + + slice(); slice(); + + %OptimizeFunctionOnNextCall(slice); + var narr = slice(); + assertInstanceof(narr, MyArray); +})(); + +(function() { + const array = [3,4,5]; + + function slice(){ + return array.slice(); + } + + slice(); slice(); + + %OptimizeFunctionOnNextCall(slice); + + slice(); + + class MyArray extends Array {}; + array.constructor = MyArray; + // deopt + var narr = slice(); + // if not deopt, narr will be instanceof Array + assertTrue(narr instanceof MyArray); +})(); + +// JSCallReducer adds check for UnreliableReceiverMaps +(function() { + const arr = [1,2,3,4,5]; + + function slice() { + return arr.slice(); + } + + slice(); slice(); + arr.foo = 6.2; + + %OptimizeFunctionOnNextCall(slice); + // JSCallReducer will add check for UnreliableReceiverMaps + slice(); + + // Trigger deopt because of DependOnStableMaps + // installed by JSNativeContextSpecialization, + // but not the check installed by ReduceArrayPrototypeSlice itself + arr.bar = 7.2; + + let narr = slice(); + assertEquals(arr, narr); + assertEquals(narr.foo, undefined); + assertEquals(narr.bar, undefined); +})(); + +// Multiple maps +(function() { + const iarr = [1,2,3]; + const darr = [2.1, 3.3, 0.2]; + + function slice(arr) { + return arr.slice(); + } + + slice(iarr); slice(darr); + slice(iarr); slice(darr); + + %OptimizeFunctionOnNextCall(slice); + // The optimization works for both maps + assertEquals(iarr, slice(iarr)); + assertEquals(darr, slice(darr)); + assertOptimized(slice); +})(); + +// Tests for the branch of CanInlineArrayIteratingBuiltin + +// JSCallReducer will not reduce to CloneFastJSArray +// if array's prototype is not JS_ARRAY_TYPE +(function () { + class MyArray extends Array { + constructor() { + super(); + this[6]= 6; + } + } + let array = new MyArray(3, 5, 4); + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + %OptimizeFunctionOnNextCall(slice); + let narr = slice(); + // here, slice supposes to call MyArray's constructor. + // If we optimize with CloneFastJSArray, Array's constructor is called instead. + assertEquals(narr[6], 6); + assertTrue(narr instanceof MyArray); +})(); + +// JSCallReducer will not reduce to CloneFastJSArray +// if array's instance type is not JS_ARRAY_TYPE. +// CloneFastJSArray does not work with non JS_ARRAY_TYPE. +// Check : receiver_map->instance_type() == JS_ARRAY_TYPE +(function () { + var x = {"0" : 0, "2": 2} ; + x.__proto__ = Array.prototype; + + function slice() { + return x.slice(); + } + + slice(); slice(); + + %OptimizeFunctionOnNextCall(slice); + assertEquals(slice(), []); +})(); + +// JSCallReducer will not reduce to CloneFastJSArray +// since array is not Fast Elements Kind +// Check : IsFastElementsKind(receiver_map->elements_kind()) +(function () { + var array = [3, 4, 5]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + // a sparse array switches to Dictionary Elements + array[9999] = 0; + %OptimizeFunctionOnNextCall(slice); + var narr = slice(); + assertEquals(narr, array); +})(); + +(function () { + var array = [3, 4, 5]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + %OptimizeFunctionOnNextCall(slice); + slice(); + + // a sparse array switches to Dictionary Elements + array[9999] = 0; + // trigger deopt because map changes + assertEquals(slice(),array); +})(); + +// JSCallReducer will not reduce to CloneFastJSArray +// if array is used as a prototype and has unstable map +(function () { + var array = [3, 5, 4]; + + function slice(arr) { + return arr.slice(); + } + + // make array's map is_prototype_map() + var x = {__proto__ : array}; + + assertEquals(slice(array),array); + slice(array); + + // make array's map unstable + array.push(6.3); + slice(array); + + %OptimizeFunctionOnNextCall(slice); + + assertEquals(slice(array),array); +})(); + +// JSCallReducer will not reduce to CloneFastJSArray +// if the Array prototype got some elements. +// Check: isolate->IsNoElementsProtectorIntact() +(function () { + var array = [, 6, 6]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + array.__proto__.push(6); + + %OptimizeFunctionOnNextCall(slice); + + // if we optimized, we would get [ , 6, 6] + // here, slice copies elements from both the object and the prototype + let narr = slice(); + assertNotEquals(Object.getOwnPropertyDescriptor(narr,0), undefined); + assertEquals(narr, [6, 6, 6]); +})(); + +(function () { + var array = [, 6, 6]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + %OptimizeFunctionOnNextCall(slice); + slice(); + + // Deopt + array.__proto__.push(6); + let narr = slice(); + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined); + assertEquals(narr[0], 6); +})(); + +// JSCallReducer will not reduce to CloneFastJSArray +// if the Array prototype is not original +// Check: isolate->IsAnyInitialArrayPrototype(receiver_prototype) +(function () { + var array = [6, , 6]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + // change the prototype + array.__proto__ = [ , 6, ]; + + %OptimizeFunctionOnNextCall(slice); + let narr = slice(); + // if optimized, we would get [6, , 6] + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 1), undefined); + assertEquals(narr, [6,6,6]); +})(); + +(function () { + var array = [6, ,6]; + + function slice() { + return array.slice(); + } + + assertEquals(slice(),array); + slice(); + + %OptimizeFunctionOnNextCall(slice); + slice(); + + // change the prototype + array.__proto__ = [,6,]; + // deopt because of map changed + let narr = slice(); + + // if optimized, we would get [6, , 6] + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 1), undefined); + assertEquals(narr, [6,6,6]); +})(); diff --git a/deps/v8/test/mjsunit/compiler/dataview-deopt.js b/deps/v8/test/mjsunit/compiler/dataview-deopt.js new file mode 100644 index 0000000000..b19de30e5d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/dataview-deopt.js @@ -0,0 +1,58 @@ +// 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 + +// Check that there are no deopt loops for DataView methods. + +var buffer = new ArrayBuffer(64); +var dataview = new DataView(buffer, 8, 24); + +// Check DataView getters. + +function readUint8(offset) { + return dataview.getUint8(offset); +} + +function warmupRead(f) { + f(0); + f(1); + %OptimizeFunctionOnNextCall(f); + f(2); + f(3); +} + +warmupRead(readUint8); +assertOptimized(readUint8); +readUint8(0.5); // Deopts. +assertUnoptimized(readUint8); + +warmupRead(readUint8); +assertOptimized(readUint8); +readUint8(1.5); // Doesn't deopt because getUint8 didn't get inlined this time. +assertOptimized(readUint8); + +// Check DataView setters. + +function writeUint8(offset, value) { + dataview.setUint8(offset, value); +} + +function warmupWrite(f) { + f(0, 0); + f(0, 1); + %OptimizeFunctionOnNextCall(f); + f(0, 2); + f(0, 3); +} + +warmupWrite(writeUint8); +assertOptimized(writeUint8); +writeUint8(0.5, 0); // Deopts. +assertUnoptimized(writeUint8); + +warmupWrite(writeUint8); +assertOptimized(writeUint8); +writeUint8(1.5, 0); // Doesn't deopt. +assertOptimized(writeUint8); diff --git a/deps/v8/test/mjsunit/compiler/dataview-get.js b/deps/v8/test/mjsunit/compiler/dataview-get.js index 6c64410344..78c6bdf4ac 100644 --- a/deps/v8/test/mjsunit/compiler/dataview-get.js +++ b/deps/v8/test/mjsunit/compiler/dataview-get.js @@ -131,43 +131,56 @@ assertEquals(b4, readFloat64(16)); dataview.setFloat64(16, b4, true); assertEquals(b4, readFloat64(16, true)); - -// TurboFan out of bounds read, throw with exception handler. +// TurboFan out of bounds reads deopt. assertOptimized(readInt8Handled); assertInstanceof(readInt8Handled(24), RangeError); -assertOptimized(readInt8Handled); +assertUnoptimized(readInt8Handled); assertOptimized(readInt16Handled); assertInstanceof(readInt16Handled(23), RangeError); -assertOptimized(readInt16Handled); +assertUnoptimized(readInt16Handled); assertOptimized(readInt32Handled); assertInstanceof(readInt32Handled(21), RangeError); -assertOptimized(readInt32Handled); +assertUnoptimized(readInt32Handled); // Without exception handler. assertOptimized(readUint8); assertThrows(() => readUint8(24)); -assertOptimized(readUint8); +assertUnoptimized(readUint8); assertOptimized(readFloat32); assertThrows(() => readFloat32(21)); -assertOptimized(readFloat32); +assertUnoptimized(readFloat32); assertOptimized(readFloat64); assertThrows(() => readFloat64(17)); -assertOptimized(readFloat64); - +assertUnoptimized(readFloat64); -// TurboFan deoptimizations. -assertOptimized(readInt8Handled); -assertInstanceof(readInt8Handled(-1), RangeError); // Negative Smi deopts. -assertUnoptimized(readInt8Handled); - -warmup(readInt8Handled); -assertOptimized(readInt8Handled); -assertEquals(values[3], readInt8Handled(3.14)); // Non-Smi index deopts. -assertUnoptimized(readInt8Handled); - -// TurboFan neutered buffer. -warmup(readInt8Handled); -assertOptimized(readInt8Handled); -%ArrayBufferNeuter(buffer); -assertInstanceof(readInt8Handled(0), TypeError); -assertOptimized(readInt8Handled); +// Negative Smi deopts. +(function() { + function readInt8Handled(offset) { + try { return dataview.getInt8(offset); } catch (e) { return e; } + } + warmup(readInt8Handled); + assertOptimized(readInt8Handled); + assertInstanceof(readInt8Handled(-1), RangeError); + assertUnoptimized(readInt8Handled); +})(); + +// Non-Smi index deopts. +(function() { + function readUint8(offset) { return dataview.getUint8(offset); } + warmup(readUint8); + assertOptimized(readUint8); + assertEquals(values[3], readUint8(3.14)); + assertUnoptimized(readUint8); +})(); + +// TurboFan neutered buffer deopts. +(function() { + function readInt8Handled(offset) { + try { return dataview.getInt8(offset); } catch (e) { return e; } + } + warmup(readInt8Handled); + assertOptimized(readInt8Handled); + %ArrayBufferNeuter(buffer); + assertInstanceof(readInt8Handled(0), TypeError); + assertUnoptimized(readInt8Handled); +})(); diff --git a/deps/v8/test/mjsunit/compiler/dataview-set.js b/deps/v8/test/mjsunit/compiler/dataview-set.js index 07bcb8d93c..4759597881 100644 --- a/deps/v8/test/mjsunit/compiler/dataview-set.js +++ b/deps/v8/test/mjsunit/compiler/dataview-set.js @@ -117,15 +117,15 @@ assertEquals(b4, dataview.getFloat64(8)); writeFloat64(8, b4, true); assertEquals(b4, dataview.getFloat64(8, true)); -// TurboFan out of bounds read, throw with exception handler. +// TurboFan out of bounds read, deopt. assertOptimized(writeInt8Handled); assertInstanceof(writeInt8Handled(24, 0), RangeError); -assertOptimized(writeInt8Handled); +assertUnoptimized(writeInt8Handled); -// Without exception handler. +// Without exception handler, deopt too. assertOptimized(writeUint8); assertThrows(() => writeUint8(24, 0)); -assertOptimized(writeUint8); +assertUnoptimized(writeUint8); // None of the stores wrote out of bounds. var bytes = new Uint8Array(buffer); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-iterator-prototype-next.js b/deps/v8/test/mjsunit/compiler/deopt-array-iterator-prototype-next.js new file mode 100644 index 0000000000..b75f3185ac --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-iterator-prototype-next.js @@ -0,0 +1,24 @@ +// 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 deopt behaviors when the prototype has elements */ + +(function () { + var array = [,]; + + function next() { + return array[Symbol.iterator]().next(); + } + + assertEquals(next().value, undefined); + assertEquals(next().value, undefined); + + %OptimizeFunctionOnNextCall(next); + assertEquals(next().value, undefined); + + array.__proto__.push(5); + assertEquals(next().value, 5); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-every.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-every.js new file mode 100644 index 0000000000..0ebf126fa6 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-every.js @@ -0,0 +1,26 @@ +// 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 deopt behaviors when the prototype has elements */ + +// every + +(function () { + var array = [,]; + + function every() { + return array.every(v => v > 0); + } + + every(); every(); + + %OptimizeFunctionOnNextCall(every); + assertEquals(every(), true); + + array.__proto__.push(-6); + //deopt + assertEquals(every(), false); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-filter.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-filter.js new file mode 100644 index 0000000000..fcae939eb8 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-filter.js @@ -0,0 +1,28 @@ +// 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 deopt behaviors when the prototype has elements */ + +// filter + +(function () { + var array = [,]; + + function filter() { + return array.filter(v => v > 0); + } + + filter(); filter(); + + %OptimizeFunctionOnNextCall(filter); + assertEquals(filter(), []); + + array.__proto__.push(6); + // deopt + var narr = filter(); + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined); + assertEquals(narr, [6]); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-find.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-find.js new file mode 100644 index 0000000000..e8b5b9bd1b --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-find.js @@ -0,0 +1,26 @@ +// 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 deopt behaviors when the prototype has elements */ + +// find + +(function () { + var array = [,]; + + function find() { + return array.find(v => v > 0); + } + + find(); find(); + + %OptimizeFunctionOnNextCall(find); + assertEquals(find(), undefined); + + array.__proto__.push(6); + // deopt + assertEquals(find(), 6); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-findindex.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-findindex.js new file mode 100644 index 0000000000..37866a4506 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-findindex.js @@ -0,0 +1,26 @@ +// 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 deopt behaviors when the prototype has elements */ + +// findIndex + +(function () { + var array = [,]; + + function findIndex() { + return array.findIndex(v => v > 0); + } + + findIndex(); findIndex(); + + %OptimizeFunctionOnNextCall(findIndex); + assertEquals(findIndex(), -1); + + array.__proto__.push(6); + // deopt + assertEquals(findIndex(), 0); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-foreach.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-foreach.js new file mode 100644 index 0000000000..6db9078e1b --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-foreach.js @@ -0,0 +1,31 @@ +// 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 deopt behaviors when the prototype has elements */ + +// forEach + +(function () { + var array = [,]; + + function increment (v, k, arr) { arr[k] = v + 1; } + function forEach() { + array.forEach(increment); + } + forEach(); forEach(); + + %OptimizeFunctionOnNextCall(forEach); + + forEach(); + assertEquals(array, [,]); + + array.__proto__.push(5); + assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined); + // deopt + forEach(); + assertNotEquals(Object.getOwnPropertyDescriptor(array, 0), undefined); + assertEquals(array[0], 6); // this reads from the prototype +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-includes.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-includes.js new file mode 100644 index 0000000000..77aedfe1e6 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-includes.js @@ -0,0 +1,103 @@ +// 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 deopt behaviors when the prototype has elements */ + +// includes + +(function() { + const iarr = [0,1,2]; + const darr = [0.0, 2.0, 3.3]; + + function includes(arr, val) { + return arr.includes(val); + } + + assertTrue(includes(iarr, 0)); assertTrue(includes(darr, 0)); + assertTrue(includes(iarr, 2)); assertTrue(includes(darr, 2)); + + // JSCallReducer for includes not reduce because it only works with single map + %OptimizeFunctionOnNextCall(includes); + + assertTrue(includes(iarr, 0)); + assertTrue(includes(darr, 0)); +})(); + +(function() { + const iarr = [0,1,2]; + + function includes(arr, val) { + return arr.includes(val); + } + + assertTrue(includes(iarr, 0)); + assertTrue(includes(iarr, 2)); + + %OptimizeFunctionOnNextCall(includes); + + assertTrue(includes(iarr, 0)); + + const darr = [0.0, 2.0, 3.3]; + // deopt because of map change + assertTrue(includes(darr, 0)); +})(); + +(function() { + const iarr = [,3]; + + function includes(arr, val) { + return arr.includes(val); + } + + iarr.__proto__ = [2]; + + // get feedback + assertFalse(includes(iarr, 0)); + assertTrue(includes(iarr, 2)); + + %OptimizeFunctionOnNextCall(includes); + + assertFalse(includes(iarr, 0)); + + assertTrue(includes(iarr, 2)); +})(); + +(function() { + const iarr = [,3]; + + function includes(arr, val) { + return arr.includes(val); + } + + assertFalse(includes(iarr, 2)); + assertTrue(includes(iarr, 3)); + + %OptimizeFunctionOnNextCall(includes); + assertFalse(includes(iarr, 2)); + + // deopt because of map change + iarr.__proto__ = [2]; + assertTrue(includes(iarr, 2)); +})(); + +// This pollutes the Array prototype, so we should not run more tests +// in the same environment after this. +(function () { + var array = [,]; + + function includes(val) { + return array.includes(val); + } + + includes(6); includes(6); + + %OptimizeFunctionOnNextCall(includes); + assertFalse(includes(6)); + + array.__proto__.push(6); + // deopt because of no_elements_protector + assertTrue(includes(6)); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-indexof.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-indexof.js new file mode 100644 index 0000000000..78cf60507c --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-indexof.js @@ -0,0 +1,104 @@ +// 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 deopt behaviors when the prototype has elements */ + +// indexOf + +(function() { + const iarr = [0,1,2]; + const darr = [0.0, 2.0, 3.3]; + + function indexOf(arr, val) { + return arr.indexOf(val); + } + + assertEquals(0, indexOf(iarr, 0)); + assertEquals(0, indexOf(darr, 0)); + assertEquals(2, indexOf(iarr, 2)); + assertEquals(1, indexOf(darr, 2)); + + // JSCallReducer for indexOf will not reduce + // because it only works with single map + %OptimizeFunctionOnNextCall(indexOf); + + assertEquals(0, indexOf(iarr, 0)); + assertEquals(0, indexOf(darr, 0)); +})(); + +(function() { + const iarr = [0,1,2]; + + function indexOf(arr, val) { + return arr.indexOf(val); + } + + assertEquals(0, indexOf(iarr, 0)); + assertEquals(2, indexOf(iarr, 2)); + + %OptimizeFunctionOnNextCall(indexOf); + + assertEquals(0, indexOf(iarr, 0)); + + const darr = [0.0, 2.0, 3.3]; + // deopt because of map change + assertEquals(0, indexOf(darr, 0)); +})(); + +(function() { + const iarr = [,3]; + + function indexOf(arr, val) { + return arr.indexOf(val); + } + + iarr.__proto__ = [2]; + assertEquals(-1, indexOf(iarr, 0)); + assertEquals(0, indexOf(iarr, 2)); + + %OptimizeFunctionOnNextCall(indexOf); + + assertEquals(-1, indexOf(iarr, 0)); + + assertEquals(0, indexOf(iarr, 2)); +})(); + +(function() { + const iarr = [,3]; + + function indexOf(arr, val) { + return arr.indexOf(val); + } + + assertEquals(-1, indexOf(iarr, 2)); + assertEquals(1, indexOf(iarr, 3)); + + %OptimizeFunctionOnNextCall(indexOf); + assertEquals(-1, indexOf(iarr, 2)); + + // deopt because of map change + iarr.__proto__ = [2]; + assertEquals(0, indexOf(iarr, 2)); +})(); + +// This pollutes the Array prototype, so we should not run more tests +// in the same environment after this. +(function () { + var array = [,]; + + function indexOf(val) { + return array.indexOf(val); + } + + indexOf(6); indexOf(6); + + %OptimizeFunctionOnNextCall(indexOf); + assertEquals(indexOf(6), -1); + + array.__proto__.push(6); + // deopt because of no_elements_protector + assertEquals(indexOf(6), 0); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-lastindexof.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-lastindexof.js new file mode 100644 index 0000000000..d47926cd3d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-lastindexof.js @@ -0,0 +1,26 @@ +// 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 deopt behaviors when the prototype has elements */ + +// lastIndexOf + +(function () { + var array = [,]; + + function lastIndexOf(val) { + return array.lastIndexOf(val); + } + + lastIndexOf(6); lastIndexOf(6); + + %OptimizeFunctionOnNextCall(lastIndexOf); + assertEquals(lastIndexOf(6), -1); + + array.__proto__.push(6); + // deopt + assertEquals(lastIndexOf(6), 0); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-map.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-map.js new file mode 100644 index 0000000000..29c7d32174 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-map.js @@ -0,0 +1,29 @@ +// 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 deopt behaviors when the prototype has elements */ + +// map + +(function () { + var array = [,]; + + function map() { + return array.map(x => x + 1); + } + + map(); map(); + + %OptimizeFunctionOnNextCall(map); + + assertEquals(map(), [,]); + + array.__proto__.push(5); + // deopt + var narr = map(); + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined); + assertEquals(narr[0], 6); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-pop.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-pop.js new file mode 100644 index 0000000000..6d0fe068e4 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-pop.js @@ -0,0 +1,26 @@ +// 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 behaviors when the prototype has elements */ + +// pop + +(function () { + var array = [, , , ,]; + + function pop() { + return array.pop(); + } + + assertEquals(pop(), undefined); + assertEquals(pop(), undefined); + + %OptimizeFunctionOnNextCall(pop); + assertEquals(pop(), undefined); + + array.__proto__.push(6); + assertEquals(pop(), 6); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-reduce.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-reduce.js new file mode 100644 index 0000000000..d2ba0db0f8 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-reduce.js @@ -0,0 +1,31 @@ +// 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 deopt behaviors when the prototype has elements */ + +// reduce + +(function () { + var array = [, 3]; + + function accumulate (prev, cur, curIdx, arr) { arr[curIdx] = cur + prev; } + function reduce() { + array.reduce(accumulate); + } + + reduce(); reduce(); + + %OptimizeFunctionOnNextCall(reduce); + + reduce(); + assertEquals(array, [,3]); + + array.__proto__.push(3); + // deopt + reduce(); + assertEquals(array, [, 6]); + assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-slice.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-slice.js new file mode 100644 index 0000000000..6b2d5fa22d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-slice.js @@ -0,0 +1,29 @@ +// 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 deopt behaviors when the prototype has elements */ + +// slice + +(function () { + var array = [,]; + + function slice() { + return array.slice(); + } + + slice(); slice(); + + %OptimizeFunctionOnNextCall(slice); + + assertEquals(slice(), [,]); + + array.__proto__.push(5); + // deopt + var narr = slice(); + assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined); + assertEquals(narr[0], 5); +})(); diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-prototype-some.js b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-some.js new file mode 100644 index 0000000000..d9604d0c76 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/deopt-array-prototype-some.js @@ -0,0 +1,26 @@ +// 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 deopt behaviors when the prototype has elements */ + +// some + +(function () { + var array = [,]; + + function some() { + return array.some(v => v > 0); + } + + some(); some(); + + %OptimizeFunctionOnNextCall(some); + assertEquals(some(), false); + + array.__proto__.push(6); + //deopt + assertEquals(some(), true); +})(); diff --git a/deps/v8/test/mjsunit/compiler/number-constructor-deopt.js b/deps/v8/test/mjsunit/compiler/number-constructor-deopt.js new file mode 100644 index 0000000000..edffc9ec53 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/number-constructor-deopt.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 + +// This test writes {} to x to trigger lazy deopt +// from inside the number constructor. +var x = "5"; +var b = false; + +check = function() { + if (b) x = {}; + return 0; +} + +var obj = {}; +obj.valueOf = check; + +function f() { + try { + return x + Number(obj); + } catch(e) { + console.log(e.stack); + } +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +b = true; +f(); |