19inline bool IsBigInt64OpSupported(BinaryOpAssembler* assembler,
Operation op) {
20 return assembler->Is64() && op != Operation::kExponentiate &&
21 op != Operation::kShiftLeft && op != Operation::kShiftRight &&
22 op != Operation::kShiftRightLogical;
34 call_with_oddball_feedback(
this), call_with_any_feedback(
this),
43 Label if_lhsissmi(
this);
48 Label if_lhsisnotsmi(
this,
65 Label if_rhsissmi(
this), if_rhsisnotsmi(
this);
68 BIND(&if_rhsisnotsmi);
72 GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball);
77 IsAdditiveSafeIntegerFeedback(var_fadd_rhs.value()),
87 Comment(
"perform smi operation");
93 Label if_overflow(
this,
100 slot_id, update_feedback_mode);
101 var_result = smi_result;
118 BIND(&if_lhsisnotsmi);
122 GotoIfNot(IsHeapNumber(lhs_heap_object), &if_lhsisnotnumber);
124 if (!rhs_known_smi) {
126 Label if_rhsissmi(
this), if_rhsisnotsmi(
this);
129 BIND(&if_rhsisnotsmi);
133 GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball);
138 GotoIfNot(IsAdditiveSafeIntegerFeedback(var_fadd_lhs.value()),
140 GotoIfNot(IsAdditiveSafeIntegerFeedback(var_fadd_rhs.value()),
163 Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value());
167 Label AdditiveSafeInteger_overflow_check_done(
this);
169 &AdditiveSafeInteger_overflow_check_done);
172 SmiEqual(var_type_feedback.value(),
174 &AdditiveSafeInteger_overflow_check_done);
175 GotoIf(IsAdditiveSafeIntegerFeedback(value),
176 &AdditiveSafeInteger_overflow_check_done);
178 Goto(&AdditiveSafeInteger_overflow_check_done);
180 BIND(&AdditiveSafeInteger_overflow_check_done);
182 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
183 update_feedback_mode);
187 BIND(&if_lhsisnotnumber);
190 Label if_lhsisoddball(
this), if_lhsisnotoddball(
this);
194 Branch(lhs_is_oddball, &if_lhsisoddball, &if_lhsisnotoddball);
196 BIND(&if_lhsisoddball);
201 Branch(IsHeapNumber(
CAST(rhs)), &call_with_oddball_feedback,
202 &check_rhsisoddball);
205 BIND(&if_lhsisnotoddball);
212 Label lhs_is_string(
this), lhs_is_bigint(
this);
215 Goto(&call_with_any_feedback);
217 BIND(&lhs_is_bigint);
229 BIND(&lhs_is_string);
231 Label lhs_is_string_rhs_is_not_string(
this);
238 &lhs_is_string_rhs_is_not_string);
241 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(),
242 slot_id, update_feedback_mode);
248 BIND(&lhs_is_string_rhs_is_not_string);
255 StringWrapperToPrimitiveProtectorConstant();
257 PropertyCell::kValueOffset),
259 &call_with_any_feedback);
263 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(),
264 slot_id, update_feedback_mode);
275 BIND(&check_rhsisoddball);
282 GotoIf(rhs_is_oddball, &call_with_oddball_feedback);
283 Goto(&call_with_any_feedback);
291 Label if_overflow(
this);
301 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(),
302 slot_id, update_feedback_mode);
313 Label bigint_too_big(
this);
319 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
320 update_feedback_mode);
323 BIND(&bigint_too_big);
327 maybe_feedback_vector(), slot_id, update_feedback_mode);
332 BIND(&call_with_oddball_feedback);
335 Goto(&call_add_stub);
338 BIND(&call_with_any_feedback);
341 Goto(&call_add_stub);
344 BIND(&call_add_stub);
346 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
347 update_feedback_mode);
353 return var_result.value();
361 Label do_float_operation(
this),
end(
this), call_stub(
this),
370 Label if_lhsissmi(
this);
375 Label if_lhsisnotsmi(
this,
384 if (!rhs_known_smi) {
386 Label if_rhsissmi(
this), if_rhsisnotsmi(
this);
389 BIND(&if_rhsisnotsmi);
393 GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball);
398 Goto(&do_float_operation);
405 Comment(
"perform smi operation");
406 var_result = smiOperation(lhs_smi,
CAST(rhs), &var_type_feedback);
407 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(),
408 slot_id, update_feedback_mode);
413 BIND(&if_lhsisnotsmi);
418 GotoIfNot(IsHeapNumber(lhs_heap_object), &if_lhsisnotnumber);
420 if (!rhs_known_smi) {
422 Label if_rhsissmi(
this), if_rhsisnotsmi(
this);
425 BIND(&if_rhsisnotsmi);
429 GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball);
434 Goto(&do_float_operation);
444 Goto(&do_float_operation);
448 BIND(&do_float_operation);
451 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
452 update_feedback_mode);
460 BIND(&if_lhsisnotnumber);
463 Label if_left_bigint(
this), if_left_oddball(
this);
468 Branch(lhs_is_oddball, &if_left_oddball, &call_with_any_feedback);
470 BIND(&if_left_oddball);
472 Label if_rhsissmi(
this), if_rhsisnotsmi(
this);
482 BIND(&if_rhsisnotsmi);
493 BIND(&if_left_bigint);
497 if (IsBigInt64OpSupported(
this, op)) {
500 Goto(&if_both_bigint64);
502 Goto(&if_both_bigint);
507 BIND(&check_rhsisoddball);
514 GotoIfNot(rhs_is_oddball, &call_with_any_feedback);
520 if (IsBigInt64OpSupported(
this, op)) {
521 BIND(&if_both_bigint64);
523 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
524 update_feedback_mode);
532 case Operation::kSubtract: {
539 case Operation::kMultiply: {
546 case Operation::kDivide: {
549 Label if_div_zero(
this);
559 maybe_feedback_vector(), slot_id,
560 update_feedback_mode);
565 case Operation::kModulus: {
566 Label if_div_zero(
this);
576 maybe_feedback_vector(), slot_id,
577 update_feedback_mode);
587 BIND(&if_both_bigint);
590 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
591 update_feedback_mode);
593 case Operation::kSubtract: {
602 maybe_feedback_vector(), slot_id, update_feedback_mode);
606 case Operation::kMultiply: {
615 &termination_requested);
620 maybe_feedback_vector(), slot_id, update_feedback_mode);
623 BIND(&termination_requested);
627 case Operation::kDivide: {
636 &termination_requested);
641 maybe_feedback_vector(), slot_id, update_feedback_mode);
644 BIND(&termination_requested);
648 case Operation::kModulus: {
657 &termination_requested);
662 maybe_feedback_vector(), slot_id, update_feedback_mode);
665 BIND(&termination_requested);
669 case Operation::kExponentiate: {
681 BIND(&call_with_any_feedback);
689 UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector(), slot_id,
690 update_feedback_mode);
693 case Operation::kSubtract:
696 case Operation::kMultiply:
699 case Operation::kDivide:
702 case Operation::kModulus:
705 case Operation::kExponentiate:
716 return var_result.value();
730 Label if_overflow(
this,
732 var_result =
TrySmiSub(lhs, rhs, &if_overflow);
745 return var_result.value();
748 return Float64Sub(lhs, rhs);
751 context, lhs, rhs, slot_id, maybe_feedback_vector, smiFunction,
752 floatFunction, Operation::kSubtract, update_feedback_mode, rhs_known_smi);
768 return Float64Mul(lhs, rhs);
771 context, lhs, rhs, slot_id, maybe_feedback_vector, smiFunction,
772 floatFunction, Operation::kMultiply, update_feedback_mode, rhs_known_smi);
788 var_result =
TrySmiDiv(lhs, rhs, &bailout);
802 return var_result.value();
805 return Float64Div(lhs, rhs);
808 context, dividend, divisor, slot_id, maybe_feedback_vector, smiFunction,
809 floatFunction, Operation::kDivide, update_feedback_mode, rhs_known_smi);
826 return Float64Mod(lhs, rhs);
829 context, dividend, divisor, slot_id, maybe_feedback_vector, smiFunction,
830 floatFunction, Operation::kModulus, update_feedback_mode, rhs_known_smi);
846 return Float64Pow(
base, exponent);
849 context,
base, exponent, slot_id, maybe_feedback_vector, smiFunction,
850 floatFunction, Operation::kExponentiate, update_feedback_mode,
866 Label if_left_number(
this), do_number_op(
this);
867 Label if_left_bigint(
this), if_left_bigint64(
this);
871 slot ?
FeedbackValues{&var_left_feedback, maybe_feedback_vector, slot,
872 update_feedback_mode}
876 context(), left, &if_left_number, &var_left_word32, &if_left_bigint,
877 IsBigInt64OpSupported(
this, bitwise_op) ? &if_left_bigint64 :
nullptr,
878 &var_left_bigint, feedback_values);
880 BIND(&if_left_number);
881 feedback_values.
var_feedback = slot ? &var_right_feedback :
nullptr;
883 context(), right, &do_number_op, &var_right_word32,
884 &if_left_number_right_bigint,
nullptr,
nullptr, feedback_values);
886 BIND(&if_left_number_right_bigint);
891 (*maybe_feedback_vector)(), *slot, update_feedback_mode);
906 SmiOr(var_left_feedback.value(), var_right_feedback.value());
907 TNode<Smi> feedback = SmiOr(result_type, input_feedback);
909 update_feedback_mode);
917 Label if_both_bigint(
this), if_both_bigint64(
this);
920 BIND(&if_left_bigint);
922 &var_right_bigint, slot ? &var_right_feedback :
nullptr);
924 if (IsBigInt64OpSupported(
this, bitwise_op)) {
925 BIND(&if_left_bigint64);
927 &if_both_bigint64, &var_right_bigint,
928 slot ? &var_right_feedback :
nullptr);
930 BIND(&if_both_bigint64);
934 SmiOr(var_left_feedback.value(), var_right_feedback.value());
936 update_feedback_mode);
944 switch (bitwise_op) {
945 case Operation::kBitwiseAnd: {
947 WordAnd(left_raw.value(), right_raw.value())));
951 case Operation::kBitwiseOr: {
953 WordOr(left_raw.value(), right_raw.value())));
957 case Operation::kBitwiseXor: {
959 WordXor(left_raw.value(), right_raw.value())));
968 BIND(&if_both_bigint);
974 SmiOr(var_left_feedback.value(), var_right_feedback.value());
976 update_feedback_mode);
979 switch (bitwise_op) {
980 case Operation::kBitwiseAnd: {
983 var_left_bigint.value(), var_right_bigint.value());
990 (*maybe_feedback_vector)(), *slot,
991 update_feedback_mode);
996 case Operation::kBitwiseOr: {
999 var_left_bigint.value(), var_right_bigint.value());
1006 (*maybe_feedback_vector)(), *slot,
1007 update_feedback_mode);
1012 case Operation::kBitwiseXor: {
1015 var_left_bigint.value(), var_right_bigint.value());
1022 (*maybe_feedback_vector)(), *slot,
1023 update_feedback_mode);
1028 case Operation::kShiftLeft: {
1031 var_left_bigint.value(), var_right_bigint.value());
1038 (*maybe_feedback_vector)(), *slot,
1039 update_feedback_mode);
1044 case Operation::kShiftRight: {
1047 var_left_bigint.value(), var_right_bigint.value());
1054 (*maybe_feedback_vector)(), *slot,
1055 update_feedback_mode);
1060 case Operation::kShiftRightLogical: {
1064 (*maybe_feedback_vector)(), *slot,
1065 update_feedback_mode);
1076 BIND(&if_bigint_mix);
1081 (*maybe_feedback_vector)(), *slot, update_feedback_mode);
1105 Label do_number_op(
this), if_bigint_mix(
this), done(
this);
1125 BIND(&if_lhsisnotsmi);
1128 FeedbackValues feedback_values{&var_left_feedback, maybe_feedback_vector,
1129 slot, update_feedback_mode};
1131 context(), left_pointer, &do_number_op, &var_left_word32,
1132 &if_bigint_mix,
nullptr, &var_left_bigint, feedback_values);
1133 BIND(&do_number_op);
1141 feedback = SmiOr(result_type, var_left_feedback.value());
1146 BIND(&if_bigint_mix);
1151 (*maybe_feedback_vector)(), *slot, update_feedback_mode);
1159 UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
1160 update_feedback_mode);
bool IsBitwiseOutputKnownSmi(Operation bitwise_op)
std::function< TNode< Object >(TNode< Smi >, TNode< Smi >, TVariable< Smi > *)> SmiOperation
TNode< Object > Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(Operation bitwise_op, TNode< Object > left, TNode< Object > right, const LazyNode< Context > &context, TNode< UintPtrT > *slot, const LazyNode< HeapObject > *maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode)
std::function< TNode< Float64T >(TNode< Float64T >, TNode< Float64T >)> FloatOperation
TNode< Object > Generate_ExponentiateWithFeedback(const LazyNode< Context > &context, TNode< Object > base, TNode< Object > exponent, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_BinaryOperationWithFeedback(const LazyNode< Context > &context, TNode< Object > left, TNode< Object > right, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, const SmiOperation &smiOperation, const FloatOperation &floatOperation, Operation op, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_DivideWithFeedback(const LazyNode< Context > &context, TNode< Object > dividend, TNode< Object > divisor, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_AddWithFeedback(const LazyNode< Context > &context, TNode< Object > left, TNode< Object > right, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_BitwiseBinaryOpWithOptionalFeedback(Operation bitwise_op, TNode< Object > left, TNode< Object > right, const LazyNode< Context > &context, TNode< UintPtrT > *slot, const LazyNode< HeapObject > *maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode)
TNode< Object > Generate_MultiplyWithFeedback(const LazyNode< Context > &context, TNode< Object > left, TNode< Object > right, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_SubtractWithFeedback(const LazyNode< Context > &context, TNode< Object > left, TNode< Object > right, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Object > Generate_ModulusWithFeedback(const LazyNode< Context > &context, TNode< Object > dividend, TNode< Object > divisor, TNode< UintPtrT > slot, const LazyNode< HeapObject > &maybe_feedback_vector, UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi)
TNode< Number > SmiMod(TNode< Smi > a, TNode< Smi > b)
void TaggedToWord32OrBigIntWithFeedback(TNode< Context > context, TNode< Object > value, Label *if_number, TVariable< Word32T > *var_word32, Label *if_bigint, Label *if_bigint64, TVariable< BigInt > *var_maybe_bigint, const FeedbackValues &feedback)
TNode< IntPtrT > TryIntPtrDiv(TNode< IntPtrT > a, TNode< IntPtrT > b, Label *if_div_zero)
TNode< BoolT > InstanceTypeEqual(TNode< Int32T > instance_type, int type)
TNode< Smi > TrySmiSub(TNode< Smi > a, TNode< Smi > b, Label *if_overflow)
void ThrowRangeError(TNode< Context > context, MessageTemplate message, std::optional< TNode< Object > > arg0=std::nullopt, std::optional< TNode< Object > > arg1=std::nullopt, std::optional< TNode< Object > > arg2=std::nullopt)
void ThrowTypeError(TNode< Context > context, MessageTemplate message, char const *arg0=nullptr, char const *arg1=nullptr)
TNode< IntPtrT > TryIntPtrMod(TNode< IntPtrT > a, TNode< IntPtrT > b, Label *if_div_zero)
TNode< BoolT > IsAdditiveSafeIntegerFeedbackEnabled()
TNode< BoolT > TaggedEqual(TNode< AnyTaggedT > a, TNode< AnyTaggedT > b)
TNode< T > LoadObjectField(TNode< HeapObject > object, int offset)
void TaggedPointerToWord32OrBigIntWithFeedback(TNode< Context > context, TNode< HeapObject > pointer, Label *if_number, TVariable< Word32T > *var_word32, Label *if_bigint, Label *if_bigint64, TVariable< BigInt > *var_maybe_bigint, const FeedbackValues &feedback)
TNode< BoolT > TaggedIsNotSmi(TNode< MaybeObject > a)
TNode< IntPtrT > TryIntPtrSub(TNode< IntPtrT > a, TNode< IntPtrT > b, Label *if_overflow)
TNode< Number > BitwiseSmiOp(TNode< Smi > left32, TNode< Smi > right32, Operation bitwise_op)
TNode< BigInt > BigIntFromInt64(TNode< IntPtrT > value)
void UpdateFeedback(TNode< Smi > feedback, TNode< HeapObject > maybe_feedback_vector, TNode< UintPtrT > slot_id, UpdateFeedbackMode mode)
void BigIntToRawBytes(TNode< BigInt > bigint, TVariable< UintPtrT > *var_low, TVariable< UintPtrT > *var_high)
TNode< Float64T > SmiToFloat64(TNode< Smi > value)
TNode< BoolT > IsBigIntInstanceType(TNode< Int32T > instance_type)
TNode< IntPtrT > TryIntPtrMul(TNode< IntPtrT > a, TNode< IntPtrT > b, Label *if_overflow)
std::function< TNode< T >()> LazyNode
TNode< HeapNumber > AllocateHeapNumberWithValue(TNode< Float64T > value)
TNode< Word32T > IsStringWrapper(TNode< HeapObject > object)
TNode< Uint16T > LoadInstanceType(TNode< HeapObject > object)
void TerminateExecution(TNode< Context > context)
TNode< T > Select(TNode< BoolT > condition, const NodeGenerator< T > &true_body, const NodeGenerator< T > &false_body, BranchHint branch_hint=BranchHint::kNone)
TNode< BoolT > TaggedIsSmi(TNode< MaybeObject > a)
TNode< BoolT > IsAdditiveSafeInteger(TNode< Float64T > number)
TNode< Float64T > LoadHeapNumberValue(TNode< HeapObject > object)
TNode< Number > BitwiseOp(TNode< Word32T > left32, TNode< Word32T > right32, Operation bitwise_op)
TNode< Object > LoadJSPrimitiveWrapperValue(TNode< JSPrimitiveWrapper > object)
void GotoIfLargeBigInt(TNode< BigInt > bigint, Label *true_label)
TNode< Int32T > SmiToInt32(TNode< Smi > value)
TNode< IntPtrT > TryIntPtrAdd(TNode< IntPtrT > a, TNode< IntPtrT > b, Label *if_overflow)
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)
TNode< BoolT > IsStringInstanceType(TNode< Int32T > instance_type)
TNode< Smi > SelectSmiConstant(TNode< BoolT > condition, Tagged< Smi > true_value, Tagged< Smi > false_value)
TNode< Smi > TrySmiDiv(TNode< Smi > dividend, TNode< Smi > divisor, Label *bailout)
TNode< BoolT > IsBigInt(TNode< HeapObject > object)
TNode< Number > SmiMul(TNode< Smi > a, TNode< Smi > b)
TNode< Smi > TrySmiAdd(TNode< Smi > a, TNode< Smi > b, Label *if_overflow)
static const int kProtectorInvalid
TNode< IntPtrT > WordOr(TNode< IntPtrT > left, TNode< IntPtrT > right)
void Comment(MessageWithSourceLocation message, Args &&... args)
TNode< T > UncheckedCast(Node *value)
void GotoIfNot(TNode< IntegralT > condition, Label *false_label, GotoHint goto_hint=GotoHint::kNone)
TNode< Smi > SmiConstant(Tagged< Smi > value)
void GotoIf(TNode< IntegralT > condition, Label *true_label, GotoHint goto_hint=GotoHint::kNone)
TNode< IntPtrT > WordAnd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< BoolT > BoolConstant(bool value)
TNode< T > CallRuntime(Runtime::FunctionId function, TNode< Object > context, TArgs... args)
TNode< T > CallBuiltin(Builtin id, TNode< Object > context, TArgs... args)
void Branch(TNode< IntegralT > condition, Label *true_label, Label *false_label, BranchHint branch_hint=BranchHint::kNone)
ZoneVector< RpoNumber > & result
TVariable< Smi > * var_feedback