[ic] Fix no-feedback binops
Fix a non-terminating recursive call in BitwiseAnd/Or/Xor to instead perform the truncation + bitwise op directly. Also, fix up Generate_BitwiseBinaryOpWithOptionalFeedback to allow passing in optional feedback. This is a drive-by from attempting to fix the above issue by calling Generate_BitwiseBinaryOp. Bug: v8:9407 Change-Id: I2f91779de5533d1911b408f80664a4c9ae5c7342 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4111545 Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Auto-Submit: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#84900}
This commit is contained in:
parent
cdc61b447c
commit
cc89eb8024
@ -311,8 +311,6 @@ transitioning javascript builtin NumberParseInt(
|
||||
}
|
||||
|
||||
extern builtin NonNumberToNumeric(implicit context: Context)(JSAny): Numeric;
|
||||
extern builtin BitwiseAnd(implicit context: Context)(Number, Number): Number;
|
||||
extern builtin BitwiseXor(implicit context: Context)(Number, Number): Number;
|
||||
extern builtin Subtract(implicit context: Context)(Number, Number): Number;
|
||||
extern builtin Add(implicit context: Context)(Number, Number): Number;
|
||||
extern builtin StringAddConvertLeft(implicit context: Context)(
|
||||
@ -323,6 +321,7 @@ extern builtin StringAddConvertRight(implicit context: Context)(
|
||||
extern macro BitwiseOp(int32, int32, constexpr Operation): Number;
|
||||
extern macro RelationalComparison(
|
||||
constexpr Operation, JSAny, JSAny, Context): Boolean;
|
||||
extern macro TruncateNumberToWord32(Number): int32;
|
||||
|
||||
// TODO(bbudge) Use a simpler macro structure that doesn't loop when converting
|
||||
// non-numbers, if such a code sequence doesn't make the builtin bigger.
|
||||
@ -699,7 +698,7 @@ builtin BitwiseNot(implicit context: Context)(value: JSAny): Numeric {
|
||||
try {
|
||||
UnaryOp1(value) otherwise Number, BigInt;
|
||||
} label Number(n: Number) {
|
||||
tail BitwiseXor(n, -1);
|
||||
return BitwiseOp(TruncateNumberToWord32(n), -1, Operation::kBitwiseXor);
|
||||
} label BigInt(b: BigInt) {
|
||||
return runtime::BigIntUnaryOp(
|
||||
context, b, SmiTag<Operation>(Operation::kBitwiseNot));
|
||||
@ -754,7 +753,9 @@ builtin BitwiseAnd(implicit context: Context)(
|
||||
try {
|
||||
BinaryOp1(left, right) otherwise Number, AtLeastOneBigInt;
|
||||
} label Number(left: Number, right: Number) {
|
||||
tail BitwiseAnd(left, right);
|
||||
return BitwiseOp(
|
||||
TruncateNumberToWord32(left), TruncateNumberToWord32(right),
|
||||
Operation::kBitwiseAnd);
|
||||
} label AtLeastOneBigInt(left: Numeric, right: Numeric) {
|
||||
tail bigint::BigIntBitwiseAnd(left, right);
|
||||
}
|
||||
@ -765,7 +766,9 @@ builtin BitwiseOr(implicit context: Context)(
|
||||
try {
|
||||
BinaryOp1(left, right) otherwise Number, AtLeastOneBigInt;
|
||||
} label Number(left: Number, right: Number) {
|
||||
tail BitwiseOr(left, right);
|
||||
return BitwiseOp(
|
||||
TruncateNumberToWord32(left), TruncateNumberToWord32(right),
|
||||
Operation::kBitwiseOr);
|
||||
} label AtLeastOneBigInt(left: Numeric, right: Numeric) {
|
||||
tail bigint::BigIntBitwiseOr(left, right);
|
||||
}
|
||||
@ -776,7 +779,9 @@ builtin BitwiseXor(implicit context: Context)(
|
||||
try {
|
||||
BinaryOp1(left, right) otherwise Number, AtLeastOneBigInt;
|
||||
} label Number(left: Number, right: Number) {
|
||||
tail BitwiseXor(left, right);
|
||||
return BitwiseOp(
|
||||
TruncateNumberToWord32(left), TruncateNumberToWord32(right),
|
||||
Operation::kBitwiseXor);
|
||||
} label AtLeastOneBigInt(left: Numeric, right: Numeric) {
|
||||
tail bigint::BigIntBitwiseXor(left, right);
|
||||
}
|
||||
|
@ -7982,15 +7982,6 @@ TNode<BigInt> CodeStubAssembler::ToBigIntConvertNumber(TNode<Context> context,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TaggedToBigIntWithFeedback(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_not_bigint,
|
||||
Label* if_bigint, Label* if_bigint64, TVariable<BigInt>* var_bigint,
|
||||
TVariable<Smi>* var_feedback) {
|
||||
DCHECK_NOT_NULL(var_feedback);
|
||||
TaggedToBigInt(context, value, if_not_bigint, if_bigint, if_bigint64,
|
||||
var_bigint, var_feedback);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
||||
TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
|
@ -2504,11 +2504,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
TNode<Int32T> ChangeBoolToInt32(TNode<BoolT> b);
|
||||
|
||||
void TaggedToBigIntWithFeedback(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
Label* if_bigint64,
|
||||
TVariable<BigInt>* var_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
void TaggedToBigInt(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
Label* if_bigint64, TVariable<BigInt>* var_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
|
||||
// Ensures that {var_shared_value} is shareable across Isolates, and throws if
|
||||
// not.
|
||||
@ -4320,11 +4319,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Context> context, TNode<HeapObject> input, Object::Conversion mode,
|
||||
BigIntHandling bigint_handling = BigIntHandling::kThrow);
|
||||
|
||||
void TaggedToBigInt(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
Label* if_bigint64, TVariable<BigInt>* var_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
|
||||
enum IsKnownTaggedPointer { kNo, kYes };
|
||||
template <Object::Conversion conversion>
|
||||
void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value,
|
||||
|
@ -840,15 +840,14 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
Label if_bigint_mix(this, Label::kDeferred);
|
||||
|
||||
BIND(&if_left_bigint);
|
||||
TaggedToBigIntWithFeedback(context(), right, &if_bigint_mix,
|
||||
&if_both_bigint, nullptr, &var_right_bigint,
|
||||
&var_right_feedback);
|
||||
TaggedToBigInt(context(), right, &if_bigint_mix, &if_both_bigint, nullptr,
|
||||
&var_right_bigint, slot ? &var_right_feedback : nullptr);
|
||||
|
||||
if (IsBigInt64OpSupported(this, bitwise_op)) {
|
||||
BIND(&if_left_bigint64);
|
||||
TaggedToBigIntWithFeedback(context(), right, &if_bigint_mix,
|
||||
&if_both_bigint, &if_both_bigint64,
|
||||
&var_right_bigint, &var_right_feedback);
|
||||
TaggedToBigInt(context(), right, &if_bigint_mix, &if_both_bigint,
|
||||
&if_both_bigint64, &var_right_bigint,
|
||||
slot ? &var_right_feedback : nullptr);
|
||||
|
||||
BIND(&if_both_bigint64);
|
||||
if (slot) {
|
||||
@ -907,10 +906,12 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done);
|
||||
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
@ -921,10 +922,12 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done);
|
||||
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
@ -935,10 +938,12 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done);
|
||||
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user