Commit f4b76a13 authored by Hai Dang's avatar Hai Dang Committed by Commit Bot

Add dependency to deopt when Array prototype has elements.

This affects map, filter, every, some, indexOf and includes.
Tests for those cases and more are also added.

Bug: v8:8049
Change-Id: I196abd8e7e2419a2bb465f44caf4de52990ffced
Reviewed-on: https://chromium-review.googlesource.com/1172346Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Hai Dang <dhai@google.com>
Cr-Commit-Position: refs/heads/master@{#55103}
parent 3f0346cd
...@@ -1508,6 +1508,11 @@ Reduction JSCallReducer::ReduceArrayMap(Node* node, ...@@ -1508,6 +1508,11 @@ Reduction JSCallReducer::ReduceArrayMap(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange(); if (receiver_map->elements_kind() != kind) return NoChange();
} }
if (IsHoleyElementsKind(kind)) {
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
dependencies()->DependOnProtector( dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector())); PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
...@@ -1718,6 +1723,11 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node, ...@@ -1718,6 +1723,11 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange(); if (receiver_map->elements_kind() != kind) return NoChange();
} }
if (IsHoleyElementsKind(kind)) {
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
dependencies()->DependOnProtector( dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector())); PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
...@@ -2313,6 +2323,11 @@ Reduction JSCallReducer::ReduceArrayEvery(Node* node, ...@@ -2313,6 +2323,11 @@ Reduction JSCallReducer::ReduceArrayEvery(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange(); if (receiver_map->elements_kind() != kind) return NoChange();
} }
if (IsHoleyElementsKind(kind)) {
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
dependencies()->DependOnProtector( dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector())); PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
...@@ -2559,7 +2574,15 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes( ...@@ -2559,7 +2574,15 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes(
return NoChange(); return NoChange();
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return NoChange(); if (receiver_map->instance_type() != JS_ARRAY_TYPE) return NoChange();
if (!IsFastElementsKind(receiver_map->elements_kind())) return NoChange();
const ElementsKind kind = receiver_map->elements_kind();
if (!IsFastElementsKind(kind)) return NoChange();
if (IsHoleyElementsKind(kind)) {
if (!isolate()->IsNoElementsProtectorIntact()) return NoChange();
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
Callable const callable = Callable const callable =
search_variant == SearchVariant::kIndexOf search_variant == SearchVariant::kIndexOf
...@@ -2654,6 +2677,11 @@ Reduction JSCallReducer::ReduceArraySome(Node* node, ...@@ -2654,6 +2677,11 @@ Reduction JSCallReducer::ReduceArraySome(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange(); if (receiver_map->elements_kind() != kind) return NoChange();
} }
if (IsHoleyElementsKind(kind)) {
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
dependencies()->DependOnProtector( dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector())); PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
......
// 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 behaviors when the prototype has elements */
(function () {
var array = [,];
function next() {
return array[Symbol.iterator]().next();
}
assertEquals(next().value, undefined);
array.__proto__.push(5);
assertEquals(next().value, 5);
})();
// 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.
/* Test behaviors when the prototype has elements */
// every
(function () {
var array = [,];
function every() {
return array.every(v => v > 0);
}
assertEquals(every(), true);
array.__proto__.push(-6);
assertEquals(every(), false);
})();
// 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.
/* Test behaviors when the prototype has elements */
// filter
(function () {
var array = [,];
function filter() {
return array.filter(v => v > 0);
}
assertEquals(filter(), []);
array.__proto__.push(6);
var narr = filter();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr, [6]);
})();
// 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.
/* Test behaviors when the prototype has elements */
// find
(function () {
var array = [,];
function find() {
return array.find(v => v > 0);
}
assertEquals(find(), undefined);
array.__proto__.push(6);
assertEquals(find(), 6);
})();
// 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.
/* Test behaviors when the prototype has elements */
// findIndex
(function () {
var array = [,];
function findIndex() {
return array.findIndex(v => v > 0);
}
assertEquals(findIndex(), -1);
array.__proto__.push(6);
assertEquals(findIndex(), 0);
})();
// 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.
/* Test 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();
assertEquals(array, [,]);
// behavior from the prototype
array.__proto__.push(5);
assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
forEach();
assertNotEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
assertEquals(array[0], 6);
})();
// 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.
/* Test behaviors when the prototype has elements */
// includes
(function () {
var array = [,];
function includes(val) {
return array.includes(val);
}
assertEquals(includes(6), false);
array.__proto__.push(6);
assertEquals(includes(6), true);
})();
// 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.
/* Test behaviors when the prototype has elements */
// indexOf
(function () {
var array = [,];
function indexOf(val) {
return array.indexOf(val);
}
assertEquals(indexOf(6), -1);
array.__proto__.push(6);
assertEquals(indexOf(6), 0);
})();
// 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.
/* Test behaviors when the prototype has elements */
// lastIndexOf
(function () {
var array = [,];
function lastIndexOf(val) {
return array.lastIndexOf(val);
}
assertEquals(lastIndexOf(6), -1);
array.__proto__.push(6);
assertEquals(lastIndexOf(6), 0);
})();
// 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.
/* Test behaviors when the prototype has elements */
// map
(function () {
var array = [,];
function map() {
return array.map(x => x + 1);
}
assertEquals(map(), [,]);
array.__proto__.push(5);
var narr = map();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr[0], 6);
})();
// 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.
/* Test behaviors when the prototype has elements */
// pop
(function () {
var array = [,];
function pop() {
return array.pop();
}
assertEquals(pop(), undefined);
})();
(function () {
var array = [,];
function pop() {
return array.pop();
}
array.__proto__.push(6);
assertEquals(pop(), 6);
})();
// 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.
/* Test 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();
assertEquals(array, [,3]);
array.__proto__.push(3);
reduce();
assertEquals(array, [, 6]);
assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
})();
// 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.
/* Test behaviors when the prototype has elements */
// slice
(function () {
var array = [,];
function slice() {
return array.slice();
}
assertEquals(slice(), [,]);
array.__proto__.push(5);
var narr = slice();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr[0], 5);
})();
// 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.
/* Test behaviors when the prototype has elements */
// some
(function () {
var array = [,];
function some() {
return array.some(v => v > 0);
}
assertEquals(some(), false);
array.__proto__.push(6);
assertEquals(some(), true);
})();
// 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);
})();
// 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);
})();
// 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]);
})();
// 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);
})();
// 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);
})();
// 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
})();
// 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 () {
var array = [,];
function includes(val) {
return array.includes(val);
}
includes(6); includes(6);
%OptimizeFunctionOnNextCall(includes);
assertEquals(includes(6), false);
array.__proto__.push(6);
// deopt
assertEquals(includes(6), true);
})();
// 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 () {
var array = [,];
function indexOf(val) {
return array.indexOf(val);
}
indexOf(6); indexOf(6);
%OptimizeFunctionOnNextCall(indexOf);
assertEquals(indexOf(6), -1);
array.__proto__.push(6);
// deopt
assertEquals(indexOf(6), 0);
})();
// 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);
})();
// 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);
})();
// 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);
})();
// 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);
})();
// 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);
})();
// 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);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment