Fix feedback loss when builtins throw
In BinaryOpAssembler::Generate_BinaryOperationWithFeedback, the feedback is stored only after the respective builtin/runtime call. If this call throws an exception, the feedback is lost, leading to a deopt loop in some cases. This CL fixes that issue by writing the gathered feedback before passing control to the builtin. Bug: chromium:1077197, v8:9441 Change-Id: I20e4b14815520224e2c6f8af1af6a89f754ccddf Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2202904 Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Auto-Submit: Nico Hartmann <nicohartmann@chromium.org> Cr-Commit-Position: refs/heads/master@{#68038}
This commit is contained in:
parent
120d433345
commit
fd5cc8837a
@ -279,6 +279,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
|
||||
{
|
||||
Comment("perform smi operation");
|
||||
var_result = smiOperation(lhs_smi, CAST(rhs), &var_type_feedback);
|
||||
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id);
|
||||
Goto(&end);
|
||||
}
|
||||
}
|
||||
@ -321,6 +322,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
|
||||
BIND(&do_float_operation);
|
||||
{
|
||||
var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber);
|
||||
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id);
|
||||
TNode<Float64T> lhs_value = var_float_lhs.value();
|
||||
TNode<Float64T> rhs_value = var_float_rhs.value();
|
||||
TNode<Float64T> value = floatOperation(lhs_value, rhs_value);
|
||||
@ -384,6 +386,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
|
||||
BIND(&if_both_bigint);
|
||||
{
|
||||
var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt);
|
||||
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id);
|
||||
if (op == Operation::kSubtract) {
|
||||
Label bigint_too_big(this);
|
||||
var_result =
|
||||
@ -415,6 +418,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
|
||||
|
||||
BIND(&call_stub);
|
||||
{
|
||||
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id);
|
||||
TNode<Object> result;
|
||||
switch (op) {
|
||||
case Operation::kSubtract:
|
||||
@ -437,7 +441,6 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
|
||||
}
|
||||
|
||||
BIND(&end);
|
||||
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
|
23
test/mjsunit/regress/regress-9441.js
Normal file
23
test/mjsunit/regress/regress-9441.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2020 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 --no-always-opt
|
||||
|
||||
function foo(a, b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(foo);
|
||||
assertEquals(-1n, foo(1n, 2n));
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
assertEquals(1n, foo(2n, 1n));
|
||||
assertOptimized(foo);
|
||||
assertThrows(() => foo(2n, undefined));
|
||||
assertUnoptimized(foo);
|
||||
%PrepareFunctionForOptimization(foo);
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
assertEquals(-1n, foo(1n, 2n));
|
||||
assertOptimized(foo);
|
||||
assertThrows(() => foo(undefined, 2n));
|
||||
assertOptimized(foo);
|
Loading…
Reference in New Issue
Block a user