OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 // static | 664 // static |
665 compiler::Node* AddWithFeedbackStub::Generate( | 665 compiler::Node* AddWithFeedbackStub::Generate( |
666 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, | 666 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
667 compiler::Node* slot_id, compiler::Node* type_feedback_vector, | 667 compiler::Node* slot_id, compiler::Node* type_feedback_vector, |
668 compiler::Node* context) { | 668 compiler::Node* context) { |
669 typedef CodeStubAssembler::Label Label; | 669 typedef CodeStubAssembler::Label Label; |
670 typedef compiler::Node Node; | 670 typedef compiler::Node Node; |
671 typedef CodeStubAssembler::Variable Variable; | 671 typedef CodeStubAssembler::Variable Variable; |
672 | 672 |
673 // Shared entry for floating point addition. | 673 // Shared entry for floating point addition. |
674 Label do_fadd(assembler), end(assembler), | 674 Label do_fadd(assembler), if_lhsisnotnumber(assembler, Label::kDeferred), |
675 call_add_stub(assembler, Label::kDeferred); | 675 check_rhsisoddball(assembler, Label::kDeferred), |
| 676 call_with_oddball_feedback(assembler), call_with_any_feedback(assembler), |
| 677 call_add_stub(assembler), end(assembler); |
676 Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64), | 678 Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64), |
677 var_fadd_rhs(assembler, MachineRepresentation::kFloat64), | 679 var_fadd_rhs(assembler, MachineRepresentation::kFloat64), |
678 var_type_feedback(assembler, MachineRepresentation::kWord32), | 680 var_type_feedback(assembler, MachineRepresentation::kWord32), |
679 var_result(assembler, MachineRepresentation::kTagged); | 681 var_result(assembler, MachineRepresentation::kTagged); |
680 | 682 |
681 // Check if the {lhs} is a Smi or a HeapObject. | 683 // Check if the {lhs} is a Smi or a HeapObject. |
682 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | 684 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
683 assembler->Branch(assembler->TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 685 assembler->Branch(assembler->TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
684 | 686 |
685 assembler->Bind(&if_lhsissmi); | 687 assembler->Bind(&if_lhsissmi); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 } | 720 } |
719 } | 721 } |
720 | 722 |
721 assembler->Bind(&if_rhsisnotsmi); | 723 assembler->Bind(&if_rhsisnotsmi); |
722 { | 724 { |
723 // Load the map of {rhs}. | 725 // Load the map of {rhs}. |
724 Node* rhs_map = assembler->LoadMap(rhs); | 726 Node* rhs_map = assembler->LoadMap(rhs); |
725 | 727 |
726 // Check if the {rhs} is a HeapNumber. | 728 // Check if the {rhs} is a HeapNumber. |
727 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), | 729 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), |
728 &call_add_stub); | 730 &check_rhsisoddball); |
729 | 731 |
730 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); | 732 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); |
731 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 733 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
732 assembler->Goto(&do_fadd); | 734 assembler->Goto(&do_fadd); |
733 } | 735 } |
734 } | 736 } |
735 | 737 |
736 assembler->Bind(&if_lhsisnotsmi); | 738 assembler->Bind(&if_lhsisnotsmi); |
737 { | 739 { |
738 Label check_string(assembler); | |
739 | |
740 // Load the map of {lhs}. | 740 // Load the map of {lhs}. |
741 Node* lhs_map = assembler->LoadMap(lhs); | 741 Node* lhs_map = assembler->LoadMap(lhs); |
742 | 742 |
743 // Check if {lhs} is a HeapNumber. | 743 // Check if {lhs} is a HeapNumber. |
744 Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler); | 744 assembler->GotoUnless(assembler->IsHeapNumberMap(lhs_map), |
745 assembler->GotoUnless(assembler->IsHeapNumberMap(lhs_map), &check_string); | 745 &if_lhsisnotnumber); |
746 | 746 |
747 // Check if the {rhs} is Smi. | 747 // Check if the {rhs} is Smi. |
748 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 748 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
749 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, | 749 assembler->Branch(assembler->TaggedIsSmi(rhs), &if_rhsissmi, |
750 &if_rhsisnotsmi); | 750 &if_rhsisnotsmi); |
751 | 751 |
752 assembler->Bind(&if_rhsissmi); | 752 assembler->Bind(&if_rhsissmi); |
753 { | 753 { |
754 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 754 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
755 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); | 755 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); |
756 assembler->Goto(&do_fadd); | 756 assembler->Goto(&do_fadd); |
757 } | 757 } |
758 | 758 |
759 assembler->Bind(&if_rhsisnotsmi); | 759 assembler->Bind(&if_rhsisnotsmi); |
760 { | 760 { |
761 // Load the map of {rhs}. | 761 // Load the map of {rhs}. |
762 Node* rhs_map = assembler->LoadMap(rhs); | 762 Node* rhs_map = assembler->LoadMap(rhs); |
763 | 763 |
764 // Check if the {rhs} is a HeapNumber. | 764 // Check if the {rhs} is a HeapNumber. |
765 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), | 765 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), |
766 &call_add_stub); | 766 &check_rhsisoddball); |
767 | 767 |
768 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 768 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
769 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 769 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
770 assembler->Goto(&do_fadd); | 770 assembler->Goto(&do_fadd); |
771 } | 771 } |
| 772 } |
772 | 773 |
773 assembler->Bind(&check_string); | 774 assembler->Bind(&do_fadd); |
| 775 { |
| 776 var_type_feedback.Bind( |
| 777 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 778 Node* value = |
| 779 assembler->Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); |
| 780 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 781 var_result.Bind(result); |
| 782 assembler->Goto(&end); |
| 783 } |
| 784 |
| 785 assembler->Bind(&if_lhsisnotnumber); |
| 786 { |
| 787 // No checks on rhs are done yet. We just know lhs is not a number or Smi. |
| 788 Label if_lhsisoddball(assembler), if_lhsisnotoddball(assembler); |
| 789 Node* lhs_instance_type = assembler->LoadInstanceType(lhs); |
| 790 Node* lhs_is_oddball = assembler->Word32Equal( |
| 791 lhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 792 assembler->Branch(lhs_is_oddball, &if_lhsisoddball, &if_lhsisnotoddball); |
| 793 |
| 794 assembler->Bind(&if_lhsisoddball); |
774 { | 795 { |
775 // Check if the {rhs} is a smi, and exit the string check early if it is. | 796 assembler->GotoIf(assembler->TaggedIsSmi(rhs), |
776 assembler->GotoIf(assembler->TaggedIsSmi(rhs), &call_add_stub); | 797 &call_with_oddball_feedback); |
777 | 798 |
778 Node* lhs_instance_type = assembler->LoadMapInstanceType(lhs_map); | 799 // Load the map of the {rhs}. |
| 800 Node* rhs_map = assembler->LoadMap(rhs); |
779 | 801 |
| 802 // Check if {rhs} is a HeapNumber. |
| 803 assembler->Branch(assembler->IsHeapNumberMap(rhs_map), |
| 804 &call_with_oddball_feedback, &check_rhsisoddball); |
| 805 } |
| 806 |
| 807 assembler->Bind(&if_lhsisnotoddball); |
| 808 { |
780 // Exit unless {lhs} is a string | 809 // Exit unless {lhs} is a string |
781 assembler->GotoUnless(assembler->IsStringInstanceType(lhs_instance_type), | 810 assembler->GotoUnless(assembler->IsStringInstanceType(lhs_instance_type), |
782 &call_add_stub); | 811 &call_with_any_feedback); |
| 812 |
| 813 // Check if the {rhs} is a smi, and exit the string check early if it is. |
| 814 assembler->GotoIf(assembler->TaggedIsSmi(rhs), &call_with_any_feedback); |
783 | 815 |
784 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); | 816 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); |
785 | 817 |
786 // Exit unless {rhs} is a string | 818 // Exit unless {rhs} is a string. Since {lhs} is a string we no longer |
| 819 // need an Oddball check. |
787 assembler->GotoUnless(assembler->IsStringInstanceType(rhs_instance_type), | 820 assembler->GotoUnless(assembler->IsStringInstanceType(rhs_instance_type), |
788 &call_add_stub); | 821 &call_with_any_feedback); |
789 | 822 |
790 var_type_feedback.Bind( | 823 var_type_feedback.Bind( |
791 assembler->Int32Constant(BinaryOperationFeedback::kString)); | 824 assembler->Int32Constant(BinaryOperationFeedback::kString)); |
792 Callable callable = CodeFactory::StringAdd( | 825 Callable callable = CodeFactory::StringAdd( |
793 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 826 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); |
794 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); | 827 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
795 | 828 |
796 assembler->Goto(&end); | 829 assembler->Goto(&end); |
797 } | 830 } |
798 } | 831 } |
799 | 832 |
800 assembler->Bind(&do_fadd); | 833 assembler->Bind(&check_rhsisoddball); |
| 834 { |
| 835 // Check if rhs is an oddball. At this point we know lhs is either a |
| 836 // Smi or number or oddball and rhs is not a number or Smi. |
| 837 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); |
| 838 Node* rhs_is_oddball = assembler->Word32Equal( |
| 839 rhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 840 assembler->Branch(rhs_is_oddball, &call_with_oddball_feedback, |
| 841 &call_with_any_feedback); |
| 842 } |
| 843 |
| 844 assembler->Bind(&call_with_oddball_feedback); |
801 { | 845 { |
802 var_type_feedback.Bind( | 846 var_type_feedback.Bind( |
803 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 847 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
804 Node* value = | 848 assembler->Goto(&call_add_stub); |
805 assembler->Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); | 849 } |
806 Node* result = assembler->ChangeFloat64ToTagged(value); | 850 |
807 var_result.Bind(result); | 851 assembler->Bind(&call_with_any_feedback); |
808 assembler->Goto(&end); | 852 { |
| 853 var_type_feedback.Bind( |
| 854 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 855 assembler->Goto(&call_add_stub); |
809 } | 856 } |
810 | 857 |
811 assembler->Bind(&call_add_stub); | 858 assembler->Bind(&call_add_stub); |
812 { | 859 { |
813 var_type_feedback.Bind( | |
814 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
815 Callable callable = CodeFactory::Add(assembler->isolate()); | 860 Callable callable = CodeFactory::Add(assembler->isolate()); |
816 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); | 861 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
817 assembler->Goto(&end); | 862 assembler->Goto(&end); |
818 } | 863 } |
819 | 864 |
820 assembler->Bind(&end); | 865 assembler->Bind(&end); |
821 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 866 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
822 slot_id); | 867 slot_id); |
823 return var_result.value(); | 868 return var_result.value(); |
824 } | 869 } |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 // static | 1065 // static |
1021 compiler::Node* MultiplyWithFeedbackStub::Generate( | 1066 compiler::Node* MultiplyWithFeedbackStub::Generate( |
1022 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, | 1067 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
1023 compiler::Node* slot_id, compiler::Node* type_feedback_vector, | 1068 compiler::Node* slot_id, compiler::Node* type_feedback_vector, |
1024 compiler::Node* context) { | 1069 compiler::Node* context) { |
1025 using compiler::Node; | 1070 using compiler::Node; |
1026 typedef CodeStubAssembler::Label Label; | 1071 typedef CodeStubAssembler::Label Label; |
1027 typedef CodeStubAssembler::Variable Variable; | 1072 typedef CodeStubAssembler::Variable Variable; |
1028 | 1073 |
1029 // Shared entry point for floating point multiplication. | 1074 // Shared entry point for floating point multiplication. |
1030 Label do_fmul(assembler), end(assembler), | 1075 Label do_fmul(assembler), if_lhsisnotnumber(assembler, Label::kDeferred), |
1031 call_multiply_stub(assembler, Label::kDeferred); | 1076 check_rhsisoddball(assembler, Label::kDeferred), |
| 1077 call_with_oddball_feedback(assembler), call_with_any_feedback(assembler), |
| 1078 call_multiply_stub(assembler), end(assembler); |
1032 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), | 1079 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), |
1033 var_rhs_float64(assembler, MachineRepresentation::kFloat64), | 1080 var_rhs_float64(assembler, MachineRepresentation::kFloat64), |
1034 var_result(assembler, MachineRepresentation::kTagged), | 1081 var_result(assembler, MachineRepresentation::kTagged), |
1035 var_type_feedback(assembler, MachineRepresentation::kWord32); | 1082 var_type_feedback(assembler, MachineRepresentation::kWord32); |
1036 | 1083 |
1037 Node* number_map = assembler->HeapNumberMapConstant(); | 1084 Node* number_map = assembler->HeapNumberMapConstant(); |
1038 | 1085 |
1039 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); | 1086 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); |
1040 assembler->Branch(assembler->TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); | 1087 assembler->Branch(assembler->TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
1041 | 1088 |
(...skipping 15 matching lines...) Expand all Loading... |
1057 MachineRepresentation::kWord32)); | 1104 MachineRepresentation::kWord32)); |
1058 assembler->Goto(&end); | 1105 assembler->Goto(&end); |
1059 } | 1106 } |
1060 | 1107 |
1061 assembler->Bind(&rhs_is_not_smi); | 1108 assembler->Bind(&rhs_is_not_smi); |
1062 { | 1109 { |
1063 Node* rhs_map = assembler->LoadMap(rhs); | 1110 Node* rhs_map = assembler->LoadMap(rhs); |
1064 | 1111 |
1065 // Check if {rhs} is a HeapNumber. | 1112 // Check if {rhs} is a HeapNumber. |
1066 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), | 1113 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), |
1067 &call_multiply_stub); | 1114 &check_rhsisoddball); |
1068 | 1115 |
1069 // Convert {lhs} to a double and multiply it with the value of {rhs}. | 1116 // Convert {lhs} to a double and multiply it with the value of {rhs}. |
1070 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); | 1117 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); |
1071 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); | 1118 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); |
1072 assembler->Goto(&do_fmul); | 1119 assembler->Goto(&do_fmul); |
1073 } | 1120 } |
1074 } | 1121 } |
1075 | 1122 |
1076 assembler->Bind(&lhs_is_not_smi); | 1123 assembler->Bind(&lhs_is_not_smi); |
1077 { | 1124 { |
1078 Node* lhs_map = assembler->LoadMap(lhs); | 1125 Node* lhs_map = assembler->LoadMap(lhs); |
1079 | 1126 |
1080 // Check if {lhs} is a HeapNumber. | 1127 // Check if {lhs} is a HeapNumber. |
1081 assembler->GotoUnless(assembler->WordEqual(lhs_map, number_map), | 1128 assembler->GotoUnless(assembler->WordEqual(lhs_map, number_map), |
1082 &call_multiply_stub); | 1129 &if_lhsisnotnumber); |
1083 | 1130 |
1084 // Check if {rhs} is a Smi. | 1131 // Check if {rhs} is a Smi. |
1085 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); | 1132 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); |
1086 assembler->Branch(assembler->TaggedIsSmi(rhs), &rhs_is_smi, | 1133 assembler->Branch(assembler->TaggedIsSmi(rhs), &rhs_is_smi, |
1087 &rhs_is_not_smi); | 1134 &rhs_is_not_smi); |
1088 | 1135 |
1089 assembler->Bind(&rhs_is_smi); | 1136 assembler->Bind(&rhs_is_smi); |
1090 { | 1137 { |
1091 // Convert {rhs} to a double and multiply it with the value of {lhs}. | 1138 // Convert {rhs} to a double and multiply it with the value of {lhs}. |
1092 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); | 1139 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); |
1093 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); | 1140 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); |
1094 assembler->Goto(&do_fmul); | 1141 assembler->Goto(&do_fmul); |
1095 } | 1142 } |
1096 | 1143 |
1097 assembler->Bind(&rhs_is_not_smi); | 1144 assembler->Bind(&rhs_is_not_smi); |
1098 { | 1145 { |
1099 Node* rhs_map = assembler->LoadMap(rhs); | 1146 Node* rhs_map = assembler->LoadMap(rhs); |
1100 | 1147 |
1101 // Check if {rhs} is a HeapNumber. | 1148 // Check if {rhs} is a HeapNumber. |
1102 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), | 1149 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), |
1103 &call_multiply_stub); | 1150 &check_rhsisoddball); |
1104 | 1151 |
1105 // Both {lhs} and {rhs} are HeapNumbers. Load their values and | 1152 // Both {lhs} and {rhs} are HeapNumbers. Load their values and |
1106 // multiply them. | 1153 // multiply them. |
1107 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); | 1154 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); |
1108 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); | 1155 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); |
1109 assembler->Goto(&do_fmul); | 1156 assembler->Goto(&do_fmul); |
1110 } | 1157 } |
1111 } | 1158 } |
1112 | 1159 |
1113 assembler->Bind(&do_fmul); | 1160 assembler->Bind(&do_fmul); |
1114 { | 1161 { |
1115 var_type_feedback.Bind( | 1162 var_type_feedback.Bind( |
1116 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 1163 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
1117 Node* value = | 1164 Node* value = |
1118 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); | 1165 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
1119 Node* result = assembler->ChangeFloat64ToTagged(value); | 1166 Node* result = assembler->ChangeFloat64ToTagged(value); |
1120 var_result.Bind(result); | 1167 var_result.Bind(result); |
1121 assembler->Goto(&end); | 1168 assembler->Goto(&end); |
1122 } | 1169 } |
1123 | 1170 |
| 1171 assembler->Bind(&if_lhsisnotnumber); |
| 1172 { |
| 1173 // No checks on rhs are done yet. We just know lhs is not a number or Smi. |
| 1174 // Check if lhs is an oddball. |
| 1175 Node* lhs_instance_type = assembler->LoadInstanceType(lhs); |
| 1176 Node* lhs_is_oddball = assembler->Word32Equal( |
| 1177 lhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1178 assembler->GotoUnless(lhs_is_oddball, &call_with_any_feedback); |
| 1179 |
| 1180 assembler->GotoIf(assembler->TaggedIsSmi(rhs), &call_with_oddball_feedback); |
| 1181 |
| 1182 // Load the map of the {rhs}. |
| 1183 Node* rhs_map = assembler->LoadMap(rhs); |
| 1184 |
| 1185 // Check if {rhs} is a HeapNumber. |
| 1186 assembler->Branch(assembler->IsHeapNumberMap(rhs_map), |
| 1187 &call_with_oddball_feedback, &check_rhsisoddball); |
| 1188 } |
| 1189 |
| 1190 assembler->Bind(&check_rhsisoddball); |
| 1191 { |
| 1192 // Check if rhs is an oddball. At this point we know lhs is either a |
| 1193 // Smi or number or oddball and rhs is not a number or Smi. |
| 1194 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); |
| 1195 Node* rhs_is_oddball = assembler->Word32Equal( |
| 1196 rhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1197 assembler->Branch(rhs_is_oddball, &call_with_oddball_feedback, |
| 1198 &call_with_any_feedback); |
| 1199 } |
| 1200 |
| 1201 assembler->Bind(&call_with_oddball_feedback); |
| 1202 { |
| 1203 var_type_feedback.Bind( |
| 1204 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 1205 assembler->Goto(&call_multiply_stub); |
| 1206 } |
| 1207 |
| 1208 assembler->Bind(&call_with_any_feedback); |
| 1209 { |
| 1210 var_type_feedback.Bind( |
| 1211 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1212 assembler->Goto(&call_multiply_stub); |
| 1213 } |
| 1214 |
1124 assembler->Bind(&call_multiply_stub); | 1215 assembler->Bind(&call_multiply_stub); |
1125 { | 1216 { |
1126 var_type_feedback.Bind( | |
1127 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
1128 Callable callable = CodeFactory::Multiply(assembler->isolate()); | 1217 Callable callable = CodeFactory::Multiply(assembler->isolate()); |
1129 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); | 1218 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
1130 assembler->Goto(&end); | 1219 assembler->Goto(&end); |
1131 } | 1220 } |
1132 | 1221 |
1133 assembler->Bind(&end); | 1222 assembler->Bind(&end); |
1134 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1223 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1135 slot_id); | 1224 slot_id); |
1136 return var_result.value(); | 1225 return var_result.value(); |
1137 } | 1226 } |
1138 | 1227 |
1139 | 1228 |
1140 // static | 1229 // static |
1141 compiler::Node* DivideWithFeedbackStub::Generate( | 1230 compiler::Node* DivideWithFeedbackStub::Generate( |
1142 CodeStubAssembler* assembler, compiler::Node* dividend, | 1231 CodeStubAssembler* assembler, compiler::Node* dividend, |
1143 compiler::Node* divisor, compiler::Node* slot_id, | 1232 compiler::Node* divisor, compiler::Node* slot_id, |
1144 compiler::Node* type_feedback_vector, compiler::Node* context) { | 1233 compiler::Node* type_feedback_vector, compiler::Node* context) { |
1145 using compiler::Node; | 1234 using compiler::Node; |
1146 typedef CodeStubAssembler::Label Label; | 1235 typedef CodeStubAssembler::Label Label; |
1147 typedef CodeStubAssembler::Variable Variable; | 1236 typedef CodeStubAssembler::Variable Variable; |
1148 | 1237 |
1149 // Shared entry point for floating point division. | 1238 // Shared entry point for floating point division. |
1150 Label do_fdiv(assembler), end(assembler), call_divide_stub(assembler); | 1239 Label do_fdiv(assembler), dividend_is_not_number(assembler, Label::kDeferred), |
| 1240 check_divisor_for_oddball(assembler, Label::kDeferred), |
| 1241 call_with_oddball_feedback(assembler), call_with_any_feedback(assembler), |
| 1242 call_divide_stub(assembler), end(assembler); |
1151 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), | 1243 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), |
1152 var_divisor_float64(assembler, MachineRepresentation::kFloat64), | 1244 var_divisor_float64(assembler, MachineRepresentation::kFloat64), |
1153 var_result(assembler, MachineRepresentation::kTagged), | 1245 var_result(assembler, MachineRepresentation::kTagged), |
1154 var_type_feedback(assembler, MachineRepresentation::kWord32); | 1246 var_type_feedback(assembler, MachineRepresentation::kWord32); |
1155 | 1247 |
1156 Node* number_map = assembler->HeapNumberMapConstant(); | 1248 Node* number_map = assembler->HeapNumberMapConstant(); |
1157 | 1249 |
1158 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); | 1250 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); |
1159 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, | 1251 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, |
1160 ÷nd_is_not_smi); | 1252 ÷nd_is_not_smi); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 assembler->Goto(&do_fdiv); | 1325 assembler->Goto(&do_fdiv); |
1234 } | 1326 } |
1235 } | 1327 } |
1236 | 1328 |
1237 assembler->Bind(&divisor_is_not_smi); | 1329 assembler->Bind(&divisor_is_not_smi); |
1238 { | 1330 { |
1239 Node* divisor_map = assembler->LoadMap(divisor); | 1331 Node* divisor_map = assembler->LoadMap(divisor); |
1240 | 1332 |
1241 // Check if {divisor} is a HeapNumber. | 1333 // Check if {divisor} is a HeapNumber. |
1242 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), | 1334 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
1243 &call_divide_stub); | 1335 &check_divisor_for_oddball); |
1244 | 1336 |
1245 // Convert {dividend} to a double and divide it with the value of | 1337 // Convert {dividend} to a double and divide it with the value of |
1246 // {divisor}. | 1338 // {divisor}. |
1247 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); | 1339 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
1248 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1340 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
1249 assembler->Goto(&do_fdiv); | 1341 assembler->Goto(&do_fdiv); |
1250 } | 1342 } |
1251 | 1343 |
1252 assembler->Bind(÷nd_is_not_smi); | 1344 assembler->Bind(÷nd_is_not_smi); |
1253 { | 1345 { |
1254 Node* dividend_map = assembler->LoadMap(dividend); | 1346 Node* dividend_map = assembler->LoadMap(dividend); |
1255 | 1347 |
1256 // Check if {dividend} is a HeapNumber. | 1348 // Check if {dividend} is a HeapNumber. |
1257 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), | 1349 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), |
1258 &call_divide_stub); | 1350 ÷nd_is_not_number); |
1259 | 1351 |
1260 // Check if {divisor} is a Smi. | 1352 // Check if {divisor} is a Smi. |
1261 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1353 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
1262 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1354 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, |
1263 &divisor_is_not_smi); | 1355 &divisor_is_not_smi); |
1264 | 1356 |
1265 assembler->Bind(&divisor_is_smi); | 1357 assembler->Bind(&divisor_is_smi); |
1266 { | 1358 { |
1267 // Convert {divisor} to a double and use it for a floating point | 1359 // Convert {divisor} to a double and use it for a floating point |
1268 // division. | 1360 // division. |
1269 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1361 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1270 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1362 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
1271 assembler->Goto(&do_fdiv); | 1363 assembler->Goto(&do_fdiv); |
1272 } | 1364 } |
1273 | 1365 |
1274 assembler->Bind(&divisor_is_not_smi); | 1366 assembler->Bind(&divisor_is_not_smi); |
1275 { | 1367 { |
1276 Node* divisor_map = assembler->LoadMap(divisor); | 1368 Node* divisor_map = assembler->LoadMap(divisor); |
1277 | 1369 |
1278 // Check if {divisor} is a HeapNumber. | 1370 // Check if {divisor} is a HeapNumber. |
1279 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), | 1371 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
1280 &call_divide_stub); | 1372 &check_divisor_for_oddball); |
1281 | 1373 |
1282 // Both {dividend} and {divisor} are HeapNumbers. Load their values | 1374 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
1283 // and divide them. | 1375 // and divide them. |
1284 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1376 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1285 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1377 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
1286 assembler->Goto(&do_fdiv); | 1378 assembler->Goto(&do_fdiv); |
1287 } | 1379 } |
1288 } | 1380 } |
1289 } | 1381 } |
1290 | 1382 |
1291 assembler->Bind(&do_fdiv); | 1383 assembler->Bind(&do_fdiv); |
1292 { | 1384 { |
1293 var_type_feedback.Bind( | 1385 var_type_feedback.Bind( |
1294 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 1386 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
1295 Node* value = assembler->Float64Div(var_dividend_float64.value(), | 1387 Node* value = assembler->Float64Div(var_dividend_float64.value(), |
1296 var_divisor_float64.value()); | 1388 var_divisor_float64.value()); |
1297 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1389 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1298 assembler->Goto(&end); | 1390 assembler->Goto(&end); |
1299 } | 1391 } |
1300 | 1392 |
| 1393 assembler->Bind(÷nd_is_not_number); |
| 1394 { |
| 1395 // We just know dividend is not a number or Smi. No checks on divisor yet. |
| 1396 // Check if dividend is an oddball. |
| 1397 Node* dividend_instance_type = assembler->LoadInstanceType(dividend); |
| 1398 Node* dividend_is_oddball = assembler->Word32Equal( |
| 1399 dividend_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1400 assembler->GotoUnless(dividend_is_oddball, &call_with_any_feedback); |
| 1401 |
| 1402 assembler->GotoIf(assembler->TaggedIsSmi(divisor), |
| 1403 &call_with_oddball_feedback); |
| 1404 |
| 1405 // Load the map of the {divisor}. |
| 1406 Node* divisor_map = assembler->LoadMap(divisor); |
| 1407 |
| 1408 // Check if {divisor} is a HeapNumber. |
| 1409 assembler->Branch(assembler->IsHeapNumberMap(divisor_map), |
| 1410 &call_with_oddball_feedback, &check_divisor_for_oddball); |
| 1411 } |
| 1412 |
| 1413 assembler->Bind(&check_divisor_for_oddball); |
| 1414 { |
| 1415 // Check if divisor is an oddball. At this point we know dividend is either |
| 1416 // a Smi or number or oddball and divisor is not a number or Smi. |
| 1417 Node* divisor_instance_type = assembler->LoadInstanceType(divisor); |
| 1418 Node* divisor_is_oddball = assembler->Word32Equal( |
| 1419 divisor_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1420 assembler->Branch(divisor_is_oddball, &call_with_oddball_feedback, |
| 1421 &call_with_any_feedback); |
| 1422 } |
| 1423 |
| 1424 assembler->Bind(&call_with_oddball_feedback); |
| 1425 { |
| 1426 var_type_feedback.Bind( |
| 1427 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 1428 assembler->Goto(&call_divide_stub); |
| 1429 } |
| 1430 |
| 1431 assembler->Bind(&call_with_any_feedback); |
| 1432 { |
| 1433 var_type_feedback.Bind( |
| 1434 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1435 assembler->Goto(&call_divide_stub); |
| 1436 } |
| 1437 |
1301 assembler->Bind(&call_divide_stub); | 1438 assembler->Bind(&call_divide_stub); |
1302 { | 1439 { |
1303 var_type_feedback.Bind( | |
1304 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
1305 Callable callable = CodeFactory::Divide(assembler->isolate()); | 1440 Callable callable = CodeFactory::Divide(assembler->isolate()); |
1306 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); | 1441 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); |
1307 assembler->Goto(&end); | 1442 assembler->Goto(&end); |
1308 } | 1443 } |
1309 | 1444 |
1310 assembler->Bind(&end); | 1445 assembler->Bind(&end); |
1311 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1446 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1312 slot_id); | 1447 slot_id); |
1313 return var_result.value(); | 1448 return var_result.value(); |
1314 } | 1449 } |
1315 | 1450 |
1316 // static | 1451 // static |
1317 compiler::Node* ModulusWithFeedbackStub::Generate( | 1452 compiler::Node* ModulusWithFeedbackStub::Generate( |
1318 CodeStubAssembler* assembler, compiler::Node* dividend, | 1453 CodeStubAssembler* assembler, compiler::Node* dividend, |
1319 compiler::Node* divisor, compiler::Node* slot_id, | 1454 compiler::Node* divisor, compiler::Node* slot_id, |
1320 compiler::Node* type_feedback_vector, compiler::Node* context) { | 1455 compiler::Node* type_feedback_vector, compiler::Node* context) { |
1321 using compiler::Node; | 1456 using compiler::Node; |
1322 typedef CodeStubAssembler::Label Label; | 1457 typedef CodeStubAssembler::Label Label; |
1323 typedef CodeStubAssembler::Variable Variable; | 1458 typedef CodeStubAssembler::Variable Variable; |
1324 | 1459 |
1325 // Shared entry point for floating point division. | 1460 // Shared entry point for floating point division. |
1326 Label do_fmod(assembler), end(assembler), call_modulus_stub(assembler); | 1461 Label do_fmod(assembler), dividend_is_not_number(assembler, Label::kDeferred), |
| 1462 check_divisor_for_oddball(assembler, Label::kDeferred), |
| 1463 call_with_oddball_feedback(assembler), call_with_any_feedback(assembler), |
| 1464 call_modulus_stub(assembler), end(assembler); |
1327 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), | 1465 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), |
1328 var_divisor_float64(assembler, MachineRepresentation::kFloat64), | 1466 var_divisor_float64(assembler, MachineRepresentation::kFloat64), |
1329 var_result(assembler, MachineRepresentation::kTagged), | 1467 var_result(assembler, MachineRepresentation::kTagged), |
1330 var_type_feedback(assembler, MachineRepresentation::kWord32); | 1468 var_type_feedback(assembler, MachineRepresentation::kWord32); |
1331 | 1469 |
1332 Node* number_map = assembler->HeapNumberMapConstant(); | 1470 Node* number_map = assembler->HeapNumberMapConstant(); |
1333 | 1471 |
1334 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); | 1472 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); |
1335 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, | 1473 assembler->Branch(assembler->TaggedIsSmi(dividend), ÷nd_is_smi, |
1336 ÷nd_is_not_smi); | 1474 ÷nd_is_not_smi); |
(...skipping 13 matching lines...) Expand all Loading... |
1350 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); | 1488 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); |
1351 assembler->Goto(&end); | 1489 assembler->Goto(&end); |
1352 } | 1490 } |
1353 | 1491 |
1354 assembler->Bind(&divisor_is_not_smi); | 1492 assembler->Bind(&divisor_is_not_smi); |
1355 { | 1493 { |
1356 Node* divisor_map = assembler->LoadMap(divisor); | 1494 Node* divisor_map = assembler->LoadMap(divisor); |
1357 | 1495 |
1358 // Check if {divisor} is a HeapNumber. | 1496 // Check if {divisor} is a HeapNumber. |
1359 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), | 1497 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
1360 &call_modulus_stub); | 1498 &check_divisor_for_oddball); |
1361 | 1499 |
1362 // Convert {dividend} to a double and divide it with the value of | 1500 // Convert {dividend} to a double and divide it with the value of |
1363 // {divisor}. | 1501 // {divisor}. |
1364 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); | 1502 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
1365 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1503 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
1366 assembler->Goto(&do_fmod); | 1504 assembler->Goto(&do_fmod); |
1367 } | 1505 } |
1368 } | 1506 } |
1369 | 1507 |
1370 assembler->Bind(÷nd_is_not_smi); | 1508 assembler->Bind(÷nd_is_not_smi); |
1371 { | 1509 { |
1372 Node* dividend_map = assembler->LoadMap(dividend); | 1510 Node* dividend_map = assembler->LoadMap(dividend); |
1373 | 1511 |
1374 // Check if {dividend} is a HeapNumber. | 1512 // Check if {dividend} is a HeapNumber. |
1375 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), | 1513 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), |
1376 &call_modulus_stub); | 1514 ÷nd_is_not_number); |
1377 | 1515 |
1378 // Check if {divisor} is a Smi. | 1516 // Check if {divisor} is a Smi. |
1379 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1517 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
1380 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, | 1518 assembler->Branch(assembler->TaggedIsSmi(divisor), &divisor_is_smi, |
1381 &divisor_is_not_smi); | 1519 &divisor_is_not_smi); |
1382 | 1520 |
1383 assembler->Bind(&divisor_is_smi); | 1521 assembler->Bind(&divisor_is_smi); |
1384 { | 1522 { |
1385 // Convert {divisor} to a double and use it for a floating point | 1523 // Convert {divisor} to a double and use it for a floating point |
1386 // division. | 1524 // division. |
1387 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1525 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1388 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1526 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
1389 assembler->Goto(&do_fmod); | 1527 assembler->Goto(&do_fmod); |
1390 } | 1528 } |
1391 | 1529 |
1392 assembler->Bind(&divisor_is_not_smi); | 1530 assembler->Bind(&divisor_is_not_smi); |
1393 { | 1531 { |
1394 Node* divisor_map = assembler->LoadMap(divisor); | 1532 Node* divisor_map = assembler->LoadMap(divisor); |
1395 | 1533 |
1396 // Check if {divisor} is a HeapNumber. | 1534 // Check if {divisor} is a HeapNumber. |
1397 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), | 1535 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
1398 &call_modulus_stub); | 1536 &check_divisor_for_oddball); |
1399 | 1537 |
1400 // Both {dividend} and {divisor} are HeapNumbers. Load their values | 1538 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
1401 // and divide them. | 1539 // and divide them. |
1402 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1540 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1403 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1541 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
1404 assembler->Goto(&do_fmod); | 1542 assembler->Goto(&do_fmod); |
1405 } | 1543 } |
1406 } | 1544 } |
1407 | 1545 |
1408 assembler->Bind(&do_fmod); | 1546 assembler->Bind(&do_fmod); |
1409 { | 1547 { |
1410 var_type_feedback.Bind( | 1548 var_type_feedback.Bind( |
1411 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 1549 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
1412 Node* value = assembler->Float64Mod(var_dividend_float64.value(), | 1550 Node* value = assembler->Float64Mod(var_dividend_float64.value(), |
1413 var_divisor_float64.value()); | 1551 var_divisor_float64.value()); |
1414 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1552 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1415 assembler->Goto(&end); | 1553 assembler->Goto(&end); |
1416 } | 1554 } |
1417 | 1555 |
| 1556 assembler->Bind(÷nd_is_not_number); |
| 1557 { |
| 1558 // No checks on divisor yet. We just know dividend is not a number or Smi. |
| 1559 // Check if dividend is an oddball. |
| 1560 Node* dividend_instance_type = assembler->LoadInstanceType(dividend); |
| 1561 Node* dividend_is_oddball = assembler->Word32Equal( |
| 1562 dividend_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1563 assembler->GotoUnless(dividend_is_oddball, &call_with_any_feedback); |
| 1564 |
| 1565 assembler->GotoIf(assembler->TaggedIsSmi(divisor), |
| 1566 &call_with_oddball_feedback); |
| 1567 |
| 1568 // Load the map of the {divisor}. |
| 1569 Node* divisor_map = assembler->LoadMap(divisor); |
| 1570 |
| 1571 // Check if {divisor} is a HeapNumber. |
| 1572 assembler->Branch(assembler->IsHeapNumberMap(divisor_map), |
| 1573 &call_with_oddball_feedback, &check_divisor_for_oddball); |
| 1574 } |
| 1575 |
| 1576 assembler->Bind(&check_divisor_for_oddball); |
| 1577 { |
| 1578 // Check if divisor is an oddball. At this point we know dividend is either |
| 1579 // a Smi or number or oddball and divisor is not a number or Smi. |
| 1580 Node* divisor_instance_type = assembler->LoadInstanceType(divisor); |
| 1581 Node* divisor_is_oddball = assembler->Word32Equal( |
| 1582 divisor_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 1583 assembler->Branch(divisor_is_oddball, &call_with_oddball_feedback, |
| 1584 &call_with_any_feedback); |
| 1585 } |
| 1586 |
| 1587 assembler->Bind(&call_with_oddball_feedback); |
| 1588 { |
| 1589 var_type_feedback.Bind( |
| 1590 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 1591 assembler->Goto(&call_modulus_stub); |
| 1592 } |
| 1593 |
| 1594 assembler->Bind(&call_with_any_feedback); |
| 1595 { |
| 1596 var_type_feedback.Bind( |
| 1597 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1598 assembler->Goto(&call_modulus_stub); |
| 1599 } |
| 1600 |
1418 assembler->Bind(&call_modulus_stub); | 1601 assembler->Bind(&call_modulus_stub); |
1419 { | 1602 { |
1420 var_type_feedback.Bind( | |
1421 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
1422 Callable callable = CodeFactory::Modulus(assembler->isolate()); | 1603 Callable callable = CodeFactory::Modulus(assembler->isolate()); |
1423 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); | 1604 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); |
1424 assembler->Goto(&end); | 1605 assembler->Goto(&end); |
1425 } | 1606 } |
1426 | 1607 |
1427 assembler->Bind(&end); | 1608 assembler->Bind(&end); |
1428 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1609 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1429 slot_id); | 1610 slot_id); |
1430 return var_result.value(); | 1611 return var_result.value(); |
1431 } | 1612 } |
(...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 | 3226 |
3046 if (type == MachineType::Pointer()) { | 3227 if (type == MachineType::Pointer()) { |
3047 return Representation::External(); | 3228 return Representation::External(); |
3048 } | 3229 } |
3049 | 3230 |
3050 return Representation::Tagged(); | 3231 return Representation::Tagged(); |
3051 } | 3232 } |
3052 | 3233 |
3053 } // namespace internal | 3234 } // namespace internal |
3054 } // namespace v8 | 3235 } // namespace v8 |
OLD | NEW |