summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic/binary-op-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic/binary-op-assembler.cc')
-rw-r--r--deps/v8/src/ic/binary-op-assembler.cc98
1 files changed, 72 insertions, 26 deletions
diff --git a/deps/v8/src/ic/binary-op-assembler.cc b/deps/v8/src/ic/binary-op-assembler.cc
index 4deed77e75..51c403ceb4 100644
--- a/deps/v8/src/ic/binary-op-assembler.cc
+++ b/deps/v8/src/ic/binary-op-assembler.cc
@@ -596,7 +596,9 @@ TNode<Object> BinaryOpAssembler::Generate_ExponentiateWithFeedback(
TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
- const LazyNode<Context>& context, TVariable<Smi>* feedback) {
+ const LazyNode<Context>& context, TNode<UintPtrT>* slot,
+ const LazyNode<HeapObject>* maybe_feedback_vector,
+ UpdateFeedbackMode update_feedback_mode) {
TVARIABLE(Object, result);
TVARIABLE(Smi, var_left_feedback);
TVARIABLE(Smi, var_right_feedback);
@@ -615,14 +617,14 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
TaggedToWord32OrBigIntWithFeedback(
context(), left, &if_left_number, &var_left_word32, &if_left_bigint,
- &var_left_bigint, feedback ? &var_left_feedback : nullptr);
+ &var_left_bigint, slot ? &var_left_feedback : nullptr);
Label right_is_bigint(this);
BIND(&if_left_number);
{
TaggedToWord32OrBigIntWithFeedback(
context(), right, &do_number_op, &var_right_word32, &right_is_bigint,
- &var_right_bigint, feedback ? &var_right_feedback : nullptr);
+ &var_right_bigint, slot ? &var_right_feedback : nullptr);
}
BIND(&right_is_bigint);
@@ -639,13 +641,15 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
result = BitwiseOp(var_left_word32.value(), var_right_word32.value(),
bitwise_op);
- if (feedback) {
+ if (slot) {
TNode<Smi> result_type = SelectSmiConstant(
TaggedIsSmi(result.value()), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber);
TNode<Smi> input_feedback =
SmiOr(var_left_feedback.value(), var_right_feedback.value());
- *feedback = SmiOr(result_type, input_feedback);
+ TNode<Smi> feedback = SmiOr(result_type, input_feedback);
+ UpdateFeedback(feedback, (*maybe_feedback_vector)(), *slot,
+ update_feedback_mode);
}
Goto(&done);
}
@@ -661,9 +665,15 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
BIND(&do_bigint_op);
{
- if (feedback) {
- *feedback = SmiOr(var_left_feedback.value(), var_right_feedback.value());
+ if (slot) {
+ // Ensure that the feedback is updated even if the runtime call below
+ // would throw.
+ TNode<Smi> feedback =
+ SmiOr(var_left_feedback.value(), var_right_feedback.value());
+ UpdateFeedback(feedback, (*maybe_feedback_vector)(), *slot,
+ update_feedback_mode);
}
+
result = CallRuntime(
Runtime::kBigIntBinaryOp, context(), var_left_maybe_bigint.value(),
var_right_maybe_bigint.value(), SmiConstant(bitwise_op));
@@ -677,35 +687,71 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
TNode<Object>
BinaryOpAssembler::Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
- const LazyNode<Context>& context, TVariable<Smi>* feedback) {
+ const LazyNode<Context>& context, TNode<UintPtrT>* slot,
+ const LazyNode<HeapObject>* maybe_feedback_vector,
+ UpdateFeedbackMode update_feedback_mode) {
TNode<Smi> right_smi = CAST(right);
TVARIABLE(Object, result);
TVARIABLE(Smi, var_left_feedback);
TVARIABLE(Word32T, var_left_word32);
TVARIABLE(BigInt, var_left_bigint);
- Label do_smi_op(this), if_bigint_mix(this, Label::kDeferred), done(this);
-
- TaggedToWord32OrBigIntWithFeedback(context(), left, &do_smi_op,
- &var_left_word32, &if_bigint_mix,
- &var_left_bigint, &var_left_feedback);
- BIND(&do_smi_op);
- result =
- BitwiseOp(var_left_word32.value(), SmiToInt32(right_smi), bitwise_op);
- if (feedback) {
- TNode<Smi> result_type = SelectSmiConstant(
- TaggedIsSmi(result.value()), BinaryOperationFeedback::kSignedSmall,
- BinaryOperationFeedback::kNumber);
- *feedback = SmiOr(result_type, var_left_feedback.value());
+ TVARIABLE(Smi, feedback);
+ // Check if the {lhs} is a Smi or a HeapObject.
+ Label if_lhsissmi(this), if_lhsisnotsmi(this, Label::kDeferred);
+ Label do_number_op(this), if_bigint_mix(this), done(this);
+
+ Branch(TaggedIsSmi(left), &if_lhsissmi, &if_lhsisnotsmi);
+
+ BIND(&if_lhsissmi);
+ {
+ TNode<Smi> left_smi = CAST(left);
+ result = BitwiseSmiOp(left_smi, right_smi, bitwise_op);
+ if (slot) {
+ if (IsBitwiseOutputKnownSmi(bitwise_op)) {
+ feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall);
+ } else {
+ feedback = SelectSmiConstant(TaggedIsSmi(result.value()),
+ BinaryOperationFeedback::kSignedSmall,
+ BinaryOperationFeedback::kNumber);
+ }
+ }
+ Goto(&done);
}
- Goto(&done);
- BIND(&if_bigint_mix);
- if (feedback) {
- *feedback = var_left_feedback.value();
+ BIND(&if_lhsisnotsmi);
+ {
+ TNode<HeapObject> left_pointer = CAST(left);
+ TaggedPointerToWord32OrBigIntWithFeedback(
+ context(), left_pointer, &do_number_op, &var_left_word32,
+ &if_bigint_mix, &var_left_bigint, &var_left_feedback);
+ BIND(&do_number_op);
+ {
+ result =
+ BitwiseOp(var_left_word32.value(), SmiToInt32(right_smi), bitwise_op);
+ if (slot) {
+ TNode<Smi> result_type = SelectSmiConstant(
+ TaggedIsSmi(result.value()), BinaryOperationFeedback::kSignedSmall,
+ BinaryOperationFeedback::kNumber);
+ feedback = SmiOr(result_type, var_left_feedback.value());
+ }
+ Goto(&done);
+ }
+
+ BIND(&if_bigint_mix);
+ {
+ if (slot) {
+ // Ensure that the feedback is updated before we throw.
+ feedback = var_left_feedback.value();
+ UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
+ update_feedback_mode);
+ }
+ ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
+ }
}
- ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
BIND(&done);
+ UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
+ update_feedback_mode);
return result.value();
}