Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: src/code-stubs.cc

Issue 2221833002: [Interpreter] Collect type feedback for subtract operation and pass it to turbofan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 assembler->Goto(&end); 903 assembler->Goto(&end);
904 } 904 }
905 assembler->Bind(&end); 905 assembler->Bind(&end);
906 return var_result.value(); 906 return var_result.value();
907 } 907 }
908 908
909 // static 909 // static
910 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, 910 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler,
911 compiler::Node* left, 911 compiler::Node* left,
912 compiler::Node* right, 912 compiler::Node* right,
913 compiler::Node* context) { 913 compiler::Node* context,
914 compiler::Node* type_feedback_vector,
915 compiler::Node* slot_id) {
914 typedef CodeStubAssembler::Label Label; 916 typedef CodeStubAssembler::Label Label;
915 typedef compiler::Node Node; 917 typedef compiler::Node Node;
916 typedef CodeStubAssembler::Variable Variable; 918 typedef CodeStubAssembler::Variable Variable;
917 919
920 bool collect_type_feedback = (type_feedback_vector != NULL);
921
918 // Shared entry for floating point subtraction. 922 // Shared entry for floating point subtraction.
919 Label do_fsub(assembler), end(assembler); 923 Label do_fsub(assembler), end(assembler);
920 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), 924 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64),
921 var_fsub_rhs(assembler, MachineRepresentation::kFloat64); 925 var_fsub_rhs(assembler, MachineRepresentation::kFloat64);
926 Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
Benedikt Meurer 2016/08/08 04:56:13 I'm not sure if this will scale, because (a) it'l
mythria 2016/08/08 07:17:36 Thanks Benedikt, I add a subtract stub that deals
922 927
923 // We might need to loop several times due to ToPrimitive and/or ToNumber 928 // We might need to loop several times due to ToPrimitive and/or ToNumber
924 // conversions. 929 // conversions.
925 Variable var_lhs(assembler, MachineRepresentation::kTagged), 930 Variable var_lhs(assembler, MachineRepresentation::kTagged),
926 var_rhs(assembler, MachineRepresentation::kTagged), 931 var_rhs(assembler, MachineRepresentation::kTagged),
927 var_result(assembler, MachineRepresentation::kTagged); 932 var_result(assembler, MachineRepresentation::kTagged);
928 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; 933 Variable* loop_vars[3] = {&var_lhs, &var_rhs, &var_type_feedback};
929 Label loop(assembler, 2, loop_vars); 934 Label loop(assembler, 3, loop_vars);
930 var_lhs.Bind(left); 935 var_lhs.Bind(left);
931 var_rhs.Bind(right); 936 var_rhs.Bind(right);
937 // Start with Smi and keep growing up the lattice. This would avoid
938 // incorrectly collecting Smi type after the ToNumber conversion.
939 var_type_feedback.Bind(
940 assembler->Int32Constant(BinaryOpTypeFeedback::SmiType::encode(1)));
932 assembler->Goto(&loop); 941 assembler->Goto(&loop);
942
933 assembler->Bind(&loop); 943 assembler->Bind(&loop);
934 { 944 {
935 // Load the current {lhs} and {rhs} values. 945 // Load the current {lhs} and {rhs} values.
936 Node* lhs = var_lhs.value(); 946 Node* lhs = var_lhs.value();
937 Node* rhs = var_rhs.value(); 947 Node* rhs = var_rhs.value();
948 Node* type_feedback = var_type_feedback.value();
938 949
939 // Check if the {lhs} is a Smi or a HeapObject. 950 // Check if the {lhs} is a Smi or a HeapObject.
940 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); 951 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
941 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); 952 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
942 953
943 assembler->Bind(&if_lhsissmi); 954 assembler->Bind(&if_lhsissmi);
944 { 955 {
945 // Check if the {rhs} is also a Smi. 956 // Check if the {rhs} is also a Smi.
946 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); 957 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
947 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, 958 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
948 &if_rhsisnotsmi); 959 &if_rhsisnotsmi);
949 960
950 assembler->Bind(&if_rhsissmi); 961 assembler->Bind(&if_rhsissmi);
951 { 962 {
952 // Try a fast Smi subtraction first. 963 // Try a fast Smi subtraction first.
953 Node* pair = assembler->SmiSubWithOverflow(lhs, rhs); 964 Node* pair = assembler->SmiSubWithOverflow(lhs, rhs);
954 Node* overflow = assembler->Projection(1, pair); 965 Node* overflow = assembler->Projection(1, pair);
955 966
956 // Check if the Smi subtraction overflowed. 967 // Check if the Smi subtraction overflowed.
957 Label if_overflow(assembler), if_notoverflow(assembler); 968 Label if_overflow(assembler), if_notoverflow(assembler);
958 assembler->Branch(overflow, &if_overflow, &if_notoverflow); 969 assembler->Branch(overflow, &if_overflow, &if_notoverflow);
959 970
960 assembler->Bind(&if_overflow); 971 assembler->Bind(&if_overflow);
961 { 972 {
973 // lhs, rhs - smi and result - number. combined - number.
962 // The result doesn't fit into Smi range. 974 // The result doesn't fit into Smi range.
975 Node* current_feedback = assembler->Int32Constant(
976 BinaryOpTypeFeedback::NumberType::encode(1));
977 var_type_feedback.Bind(
978 assembler->Word32Or(type_feedback, current_feedback));
963 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); 979 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
964 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); 980 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
965 assembler->Goto(&do_fsub); 981 assembler->Goto(&do_fsub);
966 } 982 }
967 983
968 assembler->Bind(&if_notoverflow); 984 assembler->Bind(&if_notoverflow);
985 // lhs, rhs, result smi. combined - smi.
986 Node* smi_feedback =
987 assembler->Int32Constant(BinaryOpTypeFeedback::SmiType::encode(1));
988 var_type_feedback.Bind(
989 assembler->Word32Or(type_feedback, smi_feedback));
969 var_result.Bind(assembler->Projection(0, pair)); 990 var_result.Bind(assembler->Projection(0, pair));
970 assembler->Goto(&end); 991 assembler->Goto(&end);
971 } 992 }
972 993
973 assembler->Bind(&if_rhsisnotsmi); 994 assembler->Bind(&if_rhsisnotsmi);
974 { 995 {
975 // Load the map of the {rhs}. 996 // Load the map of the {rhs}.
976 Node* rhs_map = assembler->LoadMap(rhs); 997 Node* rhs_map = assembler->LoadMap(rhs);
977 998
978 // Check if {rhs} is a HeapNumber. 999 // Check if {rhs} is a HeapNumber.
979 Label if_rhsisnumber(assembler), 1000 Label if_rhsisnumber(assembler),
980 if_rhsisnotnumber(assembler, Label::kDeferred); 1001 if_rhsisnotnumber(assembler, Label::kDeferred);
981 Node* number_map = assembler->HeapNumberMapConstant(); 1002 Node* number_map = assembler->HeapNumberMapConstant();
982 assembler->Branch(assembler->WordEqual(rhs_map, number_map), 1003 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
983 &if_rhsisnumber, &if_rhsisnotnumber); 1004 &if_rhsisnumber, &if_rhsisnotnumber);
984 1005
985 assembler->Bind(&if_rhsisnumber); 1006 assembler->Bind(&if_rhsisnumber);
986 { 1007 {
1008 Node* current_feedback = assembler->Int32Constant(
1009 BinaryOpTypeFeedback::NumberType::encode(1));
1010 var_type_feedback.Bind(
1011 assembler->Word32Or(type_feedback, current_feedback));
987 // Perform a floating point subtraction. 1012 // Perform a floating point subtraction.
988 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); 1013 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
989 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); 1014 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
990 assembler->Goto(&do_fsub); 1015 assembler->Goto(&do_fsub);
991 } 1016 }
992 1017
993 assembler->Bind(&if_rhsisnotnumber); 1018 assembler->Bind(&if_rhsisnotnumber);
994 { 1019 {
1020 Node* current_feedback = assembler->Int32Constant(
1021 BinaryOpTypeFeedback::AnyType::encode(1));
1022 var_type_feedback.Bind(
1023 assembler->Word32Or(type_feedback, current_feedback));
995 // Convert the {rhs} to a Number first. 1024 // Convert the {rhs} to a Number first.
996 Callable callable = 1025 Callable callable =
997 CodeFactory::NonNumberToNumber(assembler->isolate()); 1026 CodeFactory::NonNumberToNumber(assembler->isolate());
998 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); 1027 var_rhs.Bind(assembler->CallStub(callable, context, rhs));
999 assembler->Goto(&loop); 1028 assembler->Goto(&loop);
1000 } 1029 }
1001 } 1030 }
1002 } 1031 }
1003 1032
1004 assembler->Bind(&if_lhsisnotsmi); 1033 assembler->Bind(&if_lhsisnotsmi);
(...skipping 10 matching lines...) Expand all
1015 1044
1016 assembler->Bind(&if_lhsisnumber); 1045 assembler->Bind(&if_lhsisnumber);
1017 { 1046 {
1018 // Check if the {rhs} is a Smi. 1047 // Check if the {rhs} is a Smi.
1019 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); 1048 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
1020 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, 1049 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
1021 &if_rhsisnotsmi); 1050 &if_rhsisnotsmi);
1022 1051
1023 assembler->Bind(&if_rhsissmi); 1052 assembler->Bind(&if_rhsissmi);
1024 { 1053 {
1054 Node* current_feedback = assembler->Int32Constant(
1055 BinaryOpTypeFeedback::NumberType::encode(1));
1056 var_type_feedback.Bind(
1057 assembler->Word32Or(type_feedback, current_feedback));
1025 // Perform a floating point subtraction. 1058 // Perform a floating point subtraction.
1026 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); 1059 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
1027 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); 1060 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
1028 assembler->Goto(&do_fsub); 1061 assembler->Goto(&do_fsub);
1029 } 1062 }
1030 1063
1031 assembler->Bind(&if_rhsisnotsmi); 1064 assembler->Bind(&if_rhsisnotsmi);
1032 { 1065 {
1033 // Load the map of the {rhs}. 1066 // Load the map of the {rhs}.
1034 Node* rhs_map = assembler->LoadMap(rhs); 1067 Node* rhs_map = assembler->LoadMap(rhs);
1035 1068
1036 // Check if the {rhs} is a HeapNumber. 1069 // Check if the {rhs} is a HeapNumber.
1037 Label if_rhsisnumber(assembler), 1070 Label if_rhsisnumber(assembler),
1038 if_rhsisnotnumber(assembler, Label::kDeferred); 1071 if_rhsisnotnumber(assembler, Label::kDeferred);
1039 assembler->Branch(assembler->WordEqual(rhs_map, number_map), 1072 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
1040 &if_rhsisnumber, &if_rhsisnotnumber); 1073 &if_rhsisnumber, &if_rhsisnotnumber);
1041 1074
1042 assembler->Bind(&if_rhsisnumber); 1075 assembler->Bind(&if_rhsisnumber);
1043 { 1076 {
1077 Node* current_feedback = assembler->Int32Constant(
1078 BinaryOpTypeFeedback::NumberType::encode(1));
1079 var_type_feedback.Bind(
1080 assembler->Word32Or(type_feedback, current_feedback));
1044 // Perform a floating point subtraction. 1081 // Perform a floating point subtraction.
1045 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); 1082 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
1046 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); 1083 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
1047 assembler->Goto(&do_fsub); 1084 assembler->Goto(&do_fsub);
1048 } 1085 }
1049 1086
1050 assembler->Bind(&if_rhsisnotnumber); 1087 assembler->Bind(&if_rhsisnotnumber);
1051 { 1088 {
1089 Node* current_feedback = assembler->Int32Constant(
1090 BinaryOpTypeFeedback::AnyType::encode(1));
1091 var_type_feedback.Bind(
1092 assembler->Word32Or(type_feedback, current_feedback));
1052 // Convert the {rhs} to a Number first. 1093 // Convert the {rhs} to a Number first.
1053 Callable callable = 1094 Callable callable =
1054 CodeFactory::NonNumberToNumber(assembler->isolate()); 1095 CodeFactory::NonNumberToNumber(assembler->isolate());
1055 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); 1096 var_rhs.Bind(assembler->CallStub(callable, context, rhs));
1056 assembler->Goto(&loop); 1097 assembler->Goto(&loop);
1057 } 1098 }
1058 } 1099 }
1059 } 1100 }
1060 1101
1061 assembler->Bind(&if_lhsisnotnumber); 1102 assembler->Bind(&if_lhsisnotnumber);
1062 { 1103 {
1104 Node* current_feedback =
1105 assembler->Int32Constant(BinaryOpTypeFeedback::AnyType::encode(1));
1106 var_type_feedback.Bind(
1107 assembler->Word32Or(type_feedback, current_feedback));
1063 // Convert the {lhs} to a Number first. 1108 // Convert the {lhs} to a Number first.
1064 Callable callable = 1109 Callable callable =
1065 CodeFactory::NonNumberToNumber(assembler->isolate()); 1110 CodeFactory::NonNumberToNumber(assembler->isolate());
1066 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); 1111 var_lhs.Bind(assembler->CallStub(callable, context, lhs));
1067 assembler->Goto(&loop); 1112 assembler->Goto(&loop);
1068 } 1113 }
1069 } 1114 }
1070 } 1115 }
1071 1116
1072 assembler->Bind(&do_fsub); 1117 assembler->Bind(&do_fsub);
1073 { 1118 {
1074 Node* lhs_value = var_fsub_lhs.value(); 1119 Node* lhs_value = var_fsub_lhs.value();
1075 Node* rhs_value = var_fsub_rhs.value(); 1120 Node* rhs_value = var_fsub_rhs.value();
1076 Node* value = assembler->Float64Sub(lhs_value, rhs_value); 1121 Node* value = assembler->Float64Sub(lhs_value, rhs_value);
1077 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); 1122 var_result.Bind(assembler->ChangeFloat64ToTagged(value));
1078 assembler->Goto(&end); 1123 assembler->Goto(&end);
1079 } 1124 }
1125
1080 assembler->Bind(&end); 1126 assembler->Bind(&end);
1127 if (collect_type_feedback) {
1128 // Combine the current type with previous feedback and store it into the
1129 // feedback slot.
1130 Node* previous_feedback_smi =
1131 assembler->LoadFixedArrayElement(type_feedback_vector, slot_id);
1132 // TODO(mythria): Add a DCHECK to verify the loaded value is an Smi.
1133 // ASSERT (WordIsSmi(previous_feedback));
1134 Node* previous_feedback = assembler->SmiUntag(previous_feedback_smi);
1135 Node* combined_feedback =
1136 assembler->Word32Or(previous_feedback, var_type_feedback.value());
1137 assembler->StoreFixedArrayElement(type_feedback_vector, slot_id,
1138 assembler->SmiTag(combined_feedback),
1139 SKIP_WRITE_BARRIER);
1140 }
1081 return var_result.value(); 1141 return var_result.value();
1082 } 1142 }
1083 1143
1084 // static 1144 // static
1085 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, 1145 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler,
1086 compiler::Node* left, 1146 compiler::Node* left,
1087 compiler::Node* right, 1147 compiler::Node* right,
1088 compiler::Node* context) { 1148 compiler::Node* context) {
1089 using compiler::Node; 1149 using compiler::Node;
1090 typedef CodeStubAssembler::Label Label; 1150 typedef CodeStubAssembler::Label Label;
(...skipping 3963 matching lines...) Expand 10 before | Expand all | Expand 10 after
5054 if (type->Is(Type::UntaggedPointer())) { 5114 if (type->Is(Type::UntaggedPointer())) {
5055 return Representation::External(); 5115 return Representation::External();
5056 } 5116 }
5057 5117
5058 DCHECK(!type->Is(Type::Untagged())); 5118 DCHECK(!type->Is(Type::Untagged()));
5059 return Representation::Tagged(); 5119 return Representation::Tagged();
5060 } 5120 }
5061 5121
5062 } // namespace internal 5122 } // namespace internal
5063 } // namespace v8 5123 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698