[turbofan] Only store after all checks are done.

The optimized code for %ArrayIteratorPrototype%.next for holey arrays
was wrong, since it would first store the [[NextIndex]] and then check
whether it hit a hole. However in that case TurboFan doesn't have any
point to deoptimize to, so we need to perform the side-effecting stores
only after all checks are done.

Bug: v8:7510, v8:7514, chromium:819086
Change-Id: I0214c7124833286113e4dc7403ddc20a82fa8da3
Reviewed-on: https://chromium-review.googlesource.com/950723
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51753}
This commit is contained in:
Benedikt Meurer 2018-03-06 08:51:40 +01:00 committed by Commit Bot
parent 21b984be72
commit 6196dd051f
2 changed files with 21 additions and 7 deletions

View File

@ -4711,13 +4711,6 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
Type::Range(0.0, length_access.type->Max() - 1.0, graph()->zone())),
index, etrue, if_true);
// Increment the [[NextIndex]] field in the {iterator}. The TypeGuards
// above guarantee that the {next_index} is in the UnsignedSmall range.
Node* next_index = graph()->NewNode(simplified()->NumberAdd(), index,
jsgraph()->OneConstant());
etrue = graph()->NewNode(simplified()->StoreField(index_access), iterator,
next_index, etrue, if_true);
done_true = jsgraph()->FalseConstant();
if (iteration_kind == IterationKind::kKeys) {
// Just return the {index}.
@ -4788,6 +4781,13 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
DCHECK_EQ(IterationKind::kValues, iteration_kind);
}
}
// Increment the [[NextIndex]] field in the {iterator}. The TypeGuards
// above guarantee that the {next_index} is in the UnsignedSmall range.
Node* next_index = graph()->NewNode(simplified()->NumberAdd(), index,
jsgraph()->OneConstant());
etrue = graph()->NewNode(simplified()->StoreField(index_access), iterator,
next_index, etrue, if_true);
}
Node* done_false;

View File

@ -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 foo() {
return [...[, -Infinity]];
}
foo()[0];
foo()[0];
%OptimizeFunctionOnNextCall(foo);
foo()[0];