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), | |
| 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 |