[compiler] Don't iterate past end of StateValuesAccess iterator
StateValuesAccess iterates over actual (non-adapted) arguments, thus we must be careful not to iterate past their end when handling rest args and advancing through the initial non-rest-args. Tbr: neis@chromium.org Bug: chromium:1167709,chromium:1166136 Change-Id: If506050a5518f394e0dcdbf39840b99923d4cbae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2637213 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#72145}
This commit is contained in:
parent
722050d8cd
commit
47135e0368
@ -3876,28 +3876,32 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
|
||||
frame_state = outer_state;
|
||||
}
|
||||
// Add the actual parameters to the {node}, skipping the receiver.
|
||||
Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
|
||||
StateValuesAccess parameters_access(parameters);
|
||||
auto parameters_it = ++parameters_access.begin(); // Skip the receiver.
|
||||
for (int i = 0; i < start_index; i++) {
|
||||
// A non-zero start_index implies that there are rest arguments. Skip them.
|
||||
++parameters_it;
|
||||
const int argument_count =
|
||||
FrameStateInfoOf(frame_state->op()).parameter_count() -
|
||||
1; // Minus receiver.
|
||||
if (start_index < argument_count) {
|
||||
Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
|
||||
StateValuesAccess parameters_access(parameters);
|
||||
auto parameters_it = ++parameters_access.begin(); // Skip the receiver.
|
||||
for (int i = 0; i < start_index; i++) {
|
||||
// A non-zero start_index implies that there are rest arguments. Skip
|
||||
// them.
|
||||
++parameters_it;
|
||||
}
|
||||
for (int i = start_index; i < argument_count; ++i, ++parameters_it) {
|
||||
Node* parameter_node = parameters_it.node();
|
||||
DCHECK_NOT_NULL(parameter_node);
|
||||
node->InsertInput(graph()->zone(),
|
||||
JSCallOrConstructNode::ArgumentIndex(argc++),
|
||||
parameter_node);
|
||||
}
|
||||
// TODO(jgruber): Currently, each use-site does the awkward dance above,
|
||||
// iterating based on the FrameStateInfo's parameter count minus one, and
|
||||
// manually advancing the iterator past the receiver. Consider wrapping all
|
||||
// this in an understandable iterator s.t. one only needs to iterate from
|
||||
// the beginning until done().
|
||||
DCHECK(parameters_it.done());
|
||||
}
|
||||
int argument_count = FrameStateInfoOf(frame_state->op()).parameter_count() -
|
||||
1; // Minus receiver.
|
||||
for (int i = start_index; i < argument_count; ++i, ++parameters_it) {
|
||||
Node* parameter_node = parameters_it.node();
|
||||
DCHECK_NOT_NULL(parameter_node);
|
||||
node->InsertInput(graph()->zone(),
|
||||
JSCallOrConstructNode::ArgumentIndex(argc++),
|
||||
parameter_node);
|
||||
}
|
||||
// TODO(jgruber): Currently, each use-site does the awkward dance above,
|
||||
// iterating based on the FrameStateInfo's parameter count minus one, and
|
||||
// manually advancing the iterator past the receiver. Consider wrapping all
|
||||
// this in an understandable iterator s.t. one only needs to iterate from the
|
||||
// beginning until done().
|
||||
DCHECK(parameters_it.done());
|
||||
|
||||
if (IsCallWithArrayLikeOrSpread(node)) {
|
||||
NodeProperties::ChangeOp(
|
||||
|
18
test/mjsunit/regress/regress-1167709-1.js
Normal file
18
test/mjsunit/regress/regress-1167709-1.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2021 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 --no-lazy-feedback-allocation
|
||||
|
||||
function __f_0() {
|
||||
}
|
||||
function __f_3( __v_7, ...__v_8) {
|
||||
return __f_0( ...__v_8);
|
||||
}
|
||||
function __f_5() {
|
||||
__f_3();
|
||||
}
|
||||
%PrepareFunctionForOptimization(__f_5);
|
||||
__f_5();
|
||||
%OptimizeFunctionOnNextCall(__f_5);
|
||||
__f_5();
|
18
test/mjsunit/regress/regress-1167709-2.js
Normal file
18
test/mjsunit/regress/regress-1167709-2.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2021 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 --no-lazy-feedback-allocation
|
||||
|
||||
function __f_0() {
|
||||
}
|
||||
function __f_3( __v_7, ...__v_8) {
|
||||
return new __f_0( ...__v_8);
|
||||
}
|
||||
function __f_5() {
|
||||
__f_3();
|
||||
}
|
||||
%PrepareFunctionForOptimization(__f_5);
|
||||
__f_5();
|
||||
%OptimizeFunctionOnNextCall(__f_5);
|
||||
__f_5();
|
Loading…
Reference in New Issue
Block a user