[turbofan] Allow deopt in Array.push to disallow speculation

This CL passes feedback from the element kind deopt points
in Array.push to the deoptimizer. If the deopt points are
triggered, further speculation on Array.push is disallowed.

Bug: v8:7127, v8:7204
Change-Id: Ie91dee598bd8b8797110c8f468406327226893a4
Reviewed-on: https://chromium-review.googlesource.com/831523
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50171}
This commit is contained in:
Sigurd Schneider 2017-12-18 17:39:14 +01:00 committed by Commit Bot
parent 06309e15a0
commit 1103d4cfef
2 changed files with 27 additions and 5 deletions

View File

@ -1044,12 +1044,11 @@ Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) {
// Array.prototype.push inlining for this function.
for (auto& value : values) {
if (IsSmiElementsKind(receiver_map->elements_kind())) {
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
value = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()),
value, effect, control);
} else if (IsDoubleElementsKind(receiver_map->elements_kind())) {
value = effect =
graph()->NewNode(simplified()->CheckNumber(VectorSlotPair()), value,
effect, control);
value = effect = graph()->NewNode(
simplified()->CheckNumber(p.feedback()), value, effect, control);
// Make sure we do not store signaling NaNs into double arrays.
value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
}

View File

@ -16,6 +16,29 @@
assertOptimized(foo);
})();
(function testElementTypeCheckSmi() {
function foo(a) { a.push('a'); }
foo([1]);
foo([1]);
%OptimizeFunctionOnNextCall(foo);
foo([1]);
%OptimizeFunctionOnNextCall(foo);
foo([1]);
assertOptimized(foo);
})();
(function testElementTypeCheckDouble() {
function foo(a) { a.push('a'); }
foo([0.3413312]);
foo([0.3413312]);
%OptimizeFunctionOnNextCall(foo);
foo([0.3413312]);
%OptimizeFunctionOnNextCall(foo);
foo([0.3413312]);
assertOptimized(foo);
})();
(function test() {
function bar(a) { a.x = 2 };
%NeverOptimizeFunction(bar);