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 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 // static | 821 // static |
822 compiler::Node* SubtractWithFeedbackStub::Generate( | 822 compiler::Node* SubtractWithFeedbackStub::Generate( |
823 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, | 823 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
824 compiler::Node* slot_id, compiler::Node* type_feedback_vector, | 824 compiler::Node* slot_id, compiler::Node* type_feedback_vector, |
825 compiler::Node* context) { | 825 compiler::Node* context) { |
826 typedef CodeStubAssembler::Label Label; | 826 typedef CodeStubAssembler::Label Label; |
827 typedef compiler::Node Node; | 827 typedef compiler::Node Node; |
828 typedef CodeStubAssembler::Variable Variable; | 828 typedef CodeStubAssembler::Variable Variable; |
829 | 829 |
830 // Shared entry for floating point subtraction. | 830 // Shared entry for floating point subtraction. |
831 Label do_fsub(assembler), end(assembler), | 831 Label do_fsub(assembler), end(assembler), call_subtract_stub(assembler), |
832 call_subtract_stub(assembler, Label::kDeferred); | 832 if_lhsisnotnumber(assembler), check_rhsisoddball(assembler), |
| 833 call_with_any_feedback(assembler); |
833 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), | 834 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), |
834 var_fsub_rhs(assembler, MachineRepresentation::kFloat64), | 835 var_fsub_rhs(assembler, MachineRepresentation::kFloat64), |
835 var_type_feedback(assembler, MachineRepresentation::kWord32), | 836 var_type_feedback(assembler, MachineRepresentation::kWord32), |
836 var_result(assembler, MachineRepresentation::kTagged); | 837 var_result(assembler, MachineRepresentation::kTagged); |
837 | 838 |
838 // Check if the {lhs} is a Smi or a HeapObject. | 839 // Check if the {lhs} is a Smi or a HeapObject. |
839 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | 840 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
840 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 841 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
841 | 842 |
842 assembler->Bind(&if_lhsissmi); | 843 assembler->Bind(&if_lhsissmi); |
(...skipping 29 matching lines...) Expand all Loading... |
872 assembler->Goto(&end); | 873 assembler->Goto(&end); |
873 } | 874 } |
874 | 875 |
875 assembler->Bind(&if_rhsisnotsmi); | 876 assembler->Bind(&if_rhsisnotsmi); |
876 { | 877 { |
877 // Load the map of the {rhs}. | 878 // Load the map of the {rhs}. |
878 Node* rhs_map = assembler->LoadMap(rhs); | 879 Node* rhs_map = assembler->LoadMap(rhs); |
879 | 880 |
880 // Check if {rhs} is a HeapNumber. | 881 // Check if {rhs} is a HeapNumber. |
881 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), | 882 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), |
882 &call_subtract_stub); | 883 &check_rhsisoddball); |
883 | 884 |
884 // Perform a floating point subtraction. | 885 // Perform a floating point subtraction. |
885 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); | 886 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); |
886 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 887 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
887 assembler->Goto(&do_fsub); | 888 assembler->Goto(&do_fsub); |
888 } | 889 } |
889 } | 890 } |
890 | 891 |
891 assembler->Bind(&if_lhsisnotsmi); | 892 assembler->Bind(&if_lhsisnotsmi); |
892 { | 893 { |
893 // Load the map of the {lhs}. | 894 // Load the map of the {lhs}. |
894 Node* lhs_map = assembler->LoadMap(lhs); | 895 Node* lhs_map = assembler->LoadMap(lhs); |
895 | 896 |
896 // Check if the {lhs} is a HeapNumber. | 897 // Check if the {lhs} is a HeapNumber. |
897 assembler->GotoUnless(assembler->IsHeapNumberMap(lhs_map), | 898 assembler->GotoUnless(assembler->IsHeapNumberMap(lhs_map), |
898 &call_subtract_stub); | 899 &if_lhsisnotnumber); |
899 | 900 |
900 // Check if the {rhs} is a Smi. | 901 // Check if the {rhs} is a Smi. |
901 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 902 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
902 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 903 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
903 | 904 |
904 assembler->Bind(&if_rhsissmi); | 905 assembler->Bind(&if_rhsissmi); |
905 { | 906 { |
906 // Perform a floating point subtraction. | 907 // Perform a floating point subtraction. |
907 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 908 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
908 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); | 909 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
909 assembler->Goto(&do_fsub); | 910 assembler->Goto(&do_fsub); |
910 } | 911 } |
911 | 912 |
912 assembler->Bind(&if_rhsisnotsmi); | 913 assembler->Bind(&if_rhsisnotsmi); |
913 { | 914 { |
914 // Load the map of the {rhs}. | 915 // Load the map of the {rhs}. |
915 Node* rhs_map = assembler->LoadMap(rhs); | 916 Node* rhs_map = assembler->LoadMap(rhs); |
916 | 917 |
917 // Check if the {rhs} is a HeapNumber. | 918 // Check if the {rhs} is a HeapNumber. |
918 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), | 919 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), |
919 &call_subtract_stub); | 920 &check_rhsisoddball); |
920 | 921 |
921 // Perform a floating point subtraction. | 922 // Perform a floating point subtraction. |
922 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | 923 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
923 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | 924 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
924 assembler->Goto(&do_fsub); | 925 assembler->Goto(&do_fsub); |
925 } | 926 } |
926 } | 927 } |
927 | 928 |
928 assembler->Bind(&do_fsub); | 929 assembler->Bind(&do_fsub); |
929 { | 930 { |
930 var_type_feedback.Bind( | 931 var_type_feedback.Bind( |
931 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 932 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
932 Node* lhs_value = var_fsub_lhs.value(); | 933 Node* lhs_value = var_fsub_lhs.value(); |
933 Node* rhs_value = var_fsub_rhs.value(); | 934 Node* rhs_value = var_fsub_rhs.value(); |
934 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 935 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
935 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 936 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
936 assembler->Goto(&end); | 937 assembler->Goto(&end); |
937 } | 938 } |
938 | 939 |
| 940 assembler->Bind(&if_lhsisnotnumber); |
| 941 { |
| 942 // No checks on rhs are done yet. We just know lhs is not a number or Smi. |
| 943 // Check if lhs is an oddball. |
| 944 Node* lhs_instance_type = assembler->LoadInstanceType(lhs); |
| 945 Node* lhs_is_oddball = assembler->Word32Equal( |
| 946 lhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 947 assembler->GotoUnless(lhs_is_oddball, &call_with_any_feedback); |
| 948 |
| 949 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 950 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
| 951 |
| 952 assembler->Bind(&if_rhsissmi); |
| 953 { |
| 954 var_type_feedback.Bind( |
| 955 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 956 assembler->Goto(&call_subtract_stub); |
| 957 } |
| 958 |
| 959 assembler->Bind(&if_rhsisnotsmi); |
| 960 { |
| 961 // Load the map of the {rhs}. |
| 962 Node* rhs_map = assembler->LoadMap(rhs); |
| 963 |
| 964 // Check if {rhs} is a HeapNumber. |
| 965 assembler->GotoUnless(assembler->IsHeapNumberMap(rhs_map), |
| 966 &check_rhsisoddball); |
| 967 |
| 968 var_type_feedback.Bind( |
| 969 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 970 assembler->Goto(&call_subtract_stub); |
| 971 } |
| 972 } |
| 973 |
| 974 assembler->Bind(&check_rhsisoddball); |
| 975 { |
| 976 // Check if rhs is an oddball. At this point we know lhs is either a |
| 977 // Smi or number or oddball and rhs is not a number or Smi. |
| 978 Node* rhs_instance_type = assembler->LoadInstanceType(rhs); |
| 979 Node* rhs_is_oddball = assembler->Word32Equal( |
| 980 rhs_instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
| 981 assembler->GotoUnless(rhs_is_oddball, &call_with_any_feedback); |
| 982 |
| 983 var_type_feedback.Bind( |
| 984 assembler->Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 985 assembler->Goto(&call_subtract_stub); |
| 986 } |
| 987 |
| 988 assembler->Bind(&call_with_any_feedback); |
| 989 { |
| 990 var_type_feedback.Bind( |
| 991 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 992 assembler->Goto(&call_subtract_stub); |
| 993 } |
| 994 |
939 assembler->Bind(&call_subtract_stub); | 995 assembler->Bind(&call_subtract_stub); |
940 { | 996 { |
941 var_type_feedback.Bind( | |
942 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
943 Callable callable = CodeFactory::Subtract(assembler->isolate()); | 997 Callable callable = CodeFactory::Subtract(assembler->isolate()); |
944 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); | 998 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
945 assembler->Goto(&end); | 999 assembler->Goto(&end); |
946 } | 1000 } |
947 | 1001 |
948 assembler->Bind(&end); | 1002 assembler->Bind(&end); |
949 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1003 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
950 slot_id); | 1004 slot_id); |
951 return var_result.value(); | 1005 return var_result.value(); |
952 } | 1006 } |
(...skipping 2055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3008 | 3062 |
3009 if (type == MachineType::Pointer()) { | 3063 if (type == MachineType::Pointer()) { |
3010 return Representation::External(); | 3064 return Representation::External(); |
3011 } | 3065 } |
3012 | 3066 |
3013 return Representation::Tagged(); | 3067 return Representation::Tagged(); |
3014 } | 3068 } |
3015 | 3069 |
3016 } // namespace internal | 3070 } // namespace internal |
3017 } // namespace v8 | 3071 } // namespace v8 |
OLD | NEW |