Commit 9e47513a authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Fix deoptimization framestate in A.p.reduce[Right]

Array.prototype.reduce[Right] used a lazy deoptimization frame
state for an eager deopt point.

Bug: v8:7336, chromium:804096
Change-Id: I720f9e049bd6b396e025fa59192fdbc6b4f18647
Reviewed-on: https://chromium-review.googlesource.com/878120
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50752}
parent afb42cb3
...@@ -1070,15 +1070,19 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1070,15 +1070,19 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
jsgraph()->UndefinedConstant()}); jsgraph()->UndefinedConstant()});
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Builtins::Name builtin = Builtins::Name builtin_lazy =
left ? Builtins::kArrayReduceLoopLazyDeoptContinuation left ? Builtins::kArrayReduceLoopLazyDeoptContinuation
: Builtins::kArrayReduceRightLoopLazyDeoptContinuation; : Builtins::kArrayReduceRightLoopLazyDeoptContinuation;
Builtins::Name builtin_eager =
left ? Builtins::kArrayReduceLoopEagerDeoptContinuation
: Builtins::kArrayReduceRightLoopEagerDeoptContinuation;
// Check whether the given callback function is callable. Note that // Check whether the given callback function is callable. Note that
// this has to happen outside the loop to make sure we also throw on // this has to happen outside the loop to make sure we also throw on
// empty arrays. // empty arrays.
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin, node->InputAt(0), context, jsgraph(), function, builtin_lazy, node->InputAt(0), context,
&checkpoint_params[0], stack_parameters - 1, outer_frame_state, &checkpoint_params[0], stack_parameters - 1, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
Node* check_fail = nullptr; Node* check_fail = nullptr;
...@@ -1089,6 +1093,12 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1089,6 +1093,12 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
// Set initial accumulator value // Set initial accumulator value
Node* cur = jsgraph()->TheHoleConstant(); Node* cur = jsgraph()->TheHoleConstant();
Node* initial_element_frame_state =
CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin_eager, node->InputAt(0), context,
&checkpoint_params[0], stack_parameters, outer_frame_state,
ContinuationFrameStateMode::EAGER);
if (node->op()->ValueInputCount() > 3) { if (node->op()->ValueInputCount() > 3) {
cur = NodeProperties::GetValueInput(node, 3); cur = NodeProperties::GetValueInput(node, 3);
} else { } else {
...@@ -1097,15 +1107,16 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1097,15 +1107,16 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
Node* next_k = graph()->NewNode(next_op, k, jsgraph()->OneConstant()); Node* next_k = graph()->NewNode(next_op, k, jsgraph()->OneConstant());
Node* loop = control; Node* loop = control;
Node* eloop = effect; Node* eloop = effect;
effect = graph()->NewNode(common()->Checkpoint(), check_frame_state, effect, effect = graph()->NewNode(common()->Checkpoint(),
control); initial_element_frame_state, effect, control);
Node* continue_test = Node* continue_test =
left ? graph()->NewNode(simplified()->NumberLessThan(), k, left ? graph()->NewNode(simplified()->NumberLessThan(), k,
original_length) original_length)
: graph()->NewNode(simplified()->NumberLessThanOrEqual(), : graph()->NewNode(simplified()->NumberLessThanOrEqual(),
jsgraph()->ZeroConstant(), k); jsgraph()->ZeroConstant(), k);
effect = graph()->NewNode(simplified()->CheckIf(DeoptimizeReason::kUnknown), effect = graph()->NewNode(
continue_test, effect, control); simplified()->CheckIf(DeoptimizeReason::kNoInitialElement),
continue_test, effect, control);
cur = SafeLoadElement(kind, receiver, control, &effect, &k, p.feedback()); cur = SafeLoadElement(kind, receiver, control, &effect, &k, p.feedback());
...@@ -1151,7 +1162,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1151,7 +1162,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
control = if_true; control = if_true;
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin, node->InputAt(0), context, jsgraph(), function, builtin_eager, node->InputAt(0), context,
&checkpoint_params[0], stack_parameters, outer_frame_state, &checkpoint_params[0], stack_parameters, outer_frame_state,
ContinuationFrameStateMode::EAGER); ContinuationFrameStateMode::EAGER);
...@@ -1192,7 +1203,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1192,7 +1203,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
} }
frame_state = CreateJavaScriptBuiltinContinuationFrameState( frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin, node->InputAt(0), context, jsgraph(), function, builtin_lazy, node->InputAt(0), context,
&checkpoint_params[0], stack_parameters - 1, outer_frame_state, &checkpoint_params[0], stack_parameters - 1, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
......
...@@ -53,7 +53,8 @@ namespace internal { ...@@ -53,7 +53,8 @@ namespace internal {
V(WrongInstanceType, "wrong instance type") \ V(WrongInstanceType, "wrong instance type") \
V(WrongMap, "wrong map") \ V(WrongMap, "wrong map") \
V(WrongName, "wrong name") \ V(WrongName, "wrong name") \
V(WrongValue, "wrong value") V(WrongValue, "wrong value") \
V(NoInitialElement, "no initial element")
enum class DeoptimizeReason : uint8_t { enum class DeoptimizeReason : uint8_t {
#define DEOPTIMIZE_REASON(Name, message) k##Name, #define DEOPTIMIZE_REASON(Name, message) k##Name,
......
// 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: --opt
for (let i = 0; i < 5000; i++) {
try {
[].reduce(function() {});
} catch (x) {
}
}
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