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