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