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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 Node* value = assembler->Float64Add(lhs_value, rhs_value); | 900 Node* value = assembler->Float64Add(lhs_value, rhs_value); |
901 Node* result = assembler->ChangeFloat64ToTagged(value); | 901 Node* result = assembler->ChangeFloat64ToTagged(value); |
902 var_result.Bind(result); | 902 var_result.Bind(result); |
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* AddWithFeedbackStub::Generate( |
| 911 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
| 912 compiler::Node* context, compiler::Node* type_feedback_vector, |
| 913 compiler::Node* slot_id) { |
| 914 typedef CodeStubAssembler::Label Label; |
| 915 typedef compiler::Node Node; |
| 916 typedef CodeStubAssembler::Variable Variable; |
| 917 |
| 918 // Shared entry for floating point addition. |
| 919 Label do_fadd(assembler), end(assembler), |
| 920 call_add_stub(assembler, Label::kDeferred); |
| 921 Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64), |
| 922 var_fadd_rhs(assembler, MachineRepresentation::kFloat64), |
| 923 var_type_feedback(assembler, MachineRepresentation::kWord32), |
| 924 var_result(assembler, MachineRepresentation::kTagged); |
| 925 |
| 926 // Check if the {lhs} is a Smi or a HeapObject. |
| 927 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
| 928 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
| 929 |
| 930 assembler->Bind(&if_lhsissmi); |
| 931 { |
| 932 // Check if the {rhs} is also a Smi. |
| 933 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 934 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
| 935 |
| 936 assembler->Bind(&if_rhsissmi); |
| 937 { |
| 938 // Try fast Smi addition first. |
| 939 Node* pair = assembler->SmiAddWithOverflow(lhs, rhs); |
| 940 Node* overflow = assembler->Projection(1, pair); |
| 941 |
| 942 // Check if the Smi additon overflowed. |
| 943 Label if_overflow(assembler), if_notoverflow(assembler); |
| 944 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
| 945 |
| 946 assembler->Bind(&if_overflow); |
| 947 { |
| 948 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); |
| 949 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); |
| 950 assembler->Goto(&do_fadd); |
| 951 } |
| 952 |
| 953 assembler->Bind(&if_notoverflow); |
| 954 { |
| 955 var_type_feedback.Bind( |
| 956 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)); |
| 957 var_result.Bind(assembler->Projection(0, pair)); |
| 958 assembler->Goto(&end); |
| 959 } |
| 960 } |
| 961 |
| 962 assembler->Bind(&if_rhsisnotsmi); |
| 963 { |
| 964 // Load the map of {rhs}. |
| 965 Node* rhs_map = assembler->LoadMap(rhs); |
| 966 |
| 967 // Check if the {rhs} is a HeapNumber. |
| 968 assembler->GotoUnless( |
| 969 assembler->WordEqual(rhs_map, assembler->HeapNumberMapConstant()), |
| 970 &call_add_stub); |
| 971 |
| 972 var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); |
| 973 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
| 974 assembler->Goto(&do_fadd); |
| 975 } |
| 976 } |
| 977 |
| 978 assembler->Bind(&if_lhsisnotsmi); |
| 979 { |
| 980 // Load the map of {lhs}. |
| 981 Node* lhs_map = assembler->LoadMap(lhs); |
| 982 |
| 983 // Check if {lhs} is a HeapNumber. |
| 984 Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler); |
| 985 assembler->GotoUnless( |
| 986 assembler->WordEqual(lhs_map, assembler->HeapNumberMapConstant()), |
| 987 &call_add_stub); |
| 988 |
| 989 // Check if the {rhs} is Smi. |
| 990 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 991 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
| 992 |
| 993 assembler->Bind(&if_rhsissmi); |
| 994 { |
| 995 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
| 996 var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); |
| 997 assembler->Goto(&do_fadd); |
| 998 } |
| 999 |
| 1000 assembler->Bind(&if_rhsisnotsmi); |
| 1001 { |
| 1002 // Load the map of {rhs}. |
| 1003 Node* rhs_map = assembler->LoadMap(rhs); |
| 1004 |
| 1005 // Check if the {rhs} is a HeapNumber. |
| 1006 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1007 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), |
| 1008 &call_add_stub); |
| 1009 |
| 1010 var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
| 1011 var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
| 1012 assembler->Goto(&do_fadd); |
| 1013 } |
| 1014 } |
| 1015 |
| 1016 assembler->Bind(&do_fadd); |
| 1017 { |
| 1018 var_type_feedback.Bind( |
| 1019 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 1020 Node* value = |
| 1021 assembler->Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); |
| 1022 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 1023 var_result.Bind(result); |
| 1024 assembler->Goto(&end); |
| 1025 } |
| 1026 |
| 1027 assembler->Bind(&call_add_stub); |
| 1028 { |
| 1029 var_type_feedback.Bind( |
| 1030 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1031 Callable callable = CodeFactory::Add(assembler->isolate()); |
| 1032 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
| 1033 assembler->Goto(&end); |
| 1034 } |
| 1035 |
| 1036 assembler->Bind(&end); |
| 1037 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 1038 slot_id); |
| 1039 return var_result.value(); |
| 1040 } |
| 1041 |
| 1042 // static |
910 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, | 1043 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
911 compiler::Node* left, | 1044 compiler::Node* left, |
912 compiler::Node* right, | 1045 compiler::Node* right, |
913 compiler::Node* context) { | 1046 compiler::Node* context) { |
914 typedef CodeStubAssembler::Label Label; | 1047 typedef CodeStubAssembler::Label Label; |
915 typedef compiler::Node Node; | 1048 typedef compiler::Node Node; |
916 typedef CodeStubAssembler::Variable Variable; | 1049 typedef CodeStubAssembler::Variable Variable; |
917 | 1050 |
918 // Shared entry for floating point subtraction. | 1051 // Shared entry for floating point subtraction. |
919 Label do_fsub(assembler), end(assembler); | 1052 Label do_fsub(assembler), end(assembler); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 // static | 1217 // static |
1085 compiler::Node* SubtractWithFeedbackStub::Generate( | 1218 compiler::Node* SubtractWithFeedbackStub::Generate( |
1086 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, | 1219 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
1087 compiler::Node* context, compiler::Node* type_feedback_vector, | 1220 compiler::Node* context, compiler::Node* type_feedback_vector, |
1088 compiler::Node* slot_id) { | 1221 compiler::Node* slot_id) { |
1089 typedef CodeStubAssembler::Label Label; | 1222 typedef CodeStubAssembler::Label Label; |
1090 typedef compiler::Node Node; | 1223 typedef compiler::Node Node; |
1091 typedef CodeStubAssembler::Variable Variable; | 1224 typedef CodeStubAssembler::Variable Variable; |
1092 | 1225 |
1093 // Shared entry for floating point subtraction. | 1226 // Shared entry for floating point subtraction. |
1094 Label do_fsub(assembler), record_feedback(assembler), | 1227 Label do_fsub(assembler), end(assembler), |
1095 call_subtract_stub(assembler, Label::kDeferred); | 1228 call_subtract_stub(assembler, Label::kDeferred); |
1096 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), | 1229 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), |
1097 var_fsub_rhs(assembler, MachineRepresentation::kFloat64); | 1230 var_fsub_rhs(assembler, MachineRepresentation::kFloat64), |
1098 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); | 1231 var_type_feedback(assembler, MachineRepresentation::kWord32), |
1099 Variable var_result(assembler, MachineRepresentation::kTagged); | 1232 var_result(assembler, MachineRepresentation::kTagged); |
1100 | 1233 |
1101 // Check if the {lhs} is a Smi or a HeapObject. | 1234 // Check if the {lhs} is a Smi or a HeapObject. |
1102 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | 1235 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
1103 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 1236 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
1104 | 1237 |
1105 assembler->Bind(&if_lhsissmi); | 1238 assembler->Bind(&if_lhsissmi); |
1106 { | 1239 { |
1107 // Check if the {rhs} is also a Smi. | 1240 // Check if the {rhs} is also a Smi. |
1108 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 1241 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
1109 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 1242 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
1110 | 1243 |
1111 assembler->Bind(&if_rhsissmi); | 1244 assembler->Bind(&if_rhsissmi); |
1112 { | 1245 { |
1113 // Try a fast Smi subtraction first. | 1246 // Try a fast Smi subtraction first. |
1114 Node* pair = assembler->SmiSubWithOverflow(lhs, rhs); | 1247 Node* pair = assembler->SmiSubWithOverflow(lhs, rhs); |
1115 Node* overflow = assembler->Projection(1, pair); | 1248 Node* overflow = assembler->Projection(1, pair); |
1116 | 1249 |
1117 // Check if the Smi subtraction overflowed. | 1250 // Check if the Smi subtraction overflowed. |
1118 Label if_overflow(assembler), if_notoverflow(assembler); | 1251 Label if_overflow(assembler), if_notoverflow(assembler); |
1119 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 1252 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
1120 | 1253 |
1121 assembler->Bind(&if_overflow); | 1254 assembler->Bind(&if_overflow); |
1122 { | 1255 { |
1123 // lhs, rhs - smi and result - number. combined - number. | 1256 // lhs, rhs - smi and result - number. combined - number. |
1124 // The result doesn't fit into Smi range. | 1257 // The result doesn't fit into Smi range. |
1125 var_type_feedback.Bind( | |
1126 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | |
1127 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); | 1258 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); |
1128 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); | 1259 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
1129 assembler->Goto(&do_fsub); | 1260 assembler->Goto(&do_fsub); |
1130 } | 1261 } |
1131 | 1262 |
1132 assembler->Bind(&if_notoverflow); | 1263 assembler->Bind(&if_notoverflow); |
1133 // lhs, rhs, result smi. combined - smi. | 1264 // lhs, rhs, result smi. combined - smi. |
1134 var_type_feedback.Bind( | 1265 var_type_feedback.Bind( |
1135 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)); | 1266 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)); |
1136 var_result.Bind(assembler->Projection(0, pair)); | 1267 var_result.Bind(assembler->Projection(0, pair)); |
1137 assembler->Goto(&record_feedback); | 1268 assembler->Goto(&end); |
1138 } | 1269 } |
1139 | 1270 |
1140 assembler->Bind(&if_rhsisnotsmi); | 1271 assembler->Bind(&if_rhsisnotsmi); |
1141 { | 1272 { |
1142 // Load the map of the {rhs}. | 1273 // Load the map of the {rhs}. |
1143 Node* rhs_map = assembler->LoadMap(rhs); | 1274 Node* rhs_map = assembler->LoadMap(rhs); |
1144 | 1275 |
1145 // Check if {rhs} is a HeapNumber. | 1276 // Check if {rhs} is a HeapNumber. |
1146 Label if_rhsisnumber(assembler), | 1277 assembler->GotoUnless( |
1147 if_rhsisnotnumber(assembler, Label::kDeferred); | 1278 assembler->WordEqual(rhs_map, assembler->HeapNumberMapConstant()), |
1148 Node* number_map = assembler->HeapNumberMapConstant(); | 1279 &call_subtract_stub); |
1149 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
1150 &if_rhsisnumber, &if_rhsisnotnumber); | |
1151 | 1280 |
1152 assembler->Bind(&if_rhsisnumber); | 1281 // Perform a floating point subtraction. |
1153 { | 1282 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); |
1154 var_type_feedback.Bind( | 1283 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
1155 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | 1284 assembler->Goto(&do_fsub); |
1156 // Perform a floating point subtraction. | |
1157 var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); | |
1158 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | |
1159 assembler->Goto(&do_fsub); | |
1160 } | |
1161 | |
1162 assembler->Bind(&if_rhsisnotnumber); | |
1163 { | |
1164 var_type_feedback.Bind( | |
1165 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
1166 assembler->Goto(&call_subtract_stub); | |
1167 } | |
1168 } | 1285 } |
1169 } | 1286 } |
1170 | 1287 |
1171 assembler->Bind(&if_lhsisnotsmi); | 1288 assembler->Bind(&if_lhsisnotsmi); |
1172 { | 1289 { |
1173 // Load the map of the {lhs}. | 1290 // Load the map of the {lhs}. |
1174 Node* lhs_map = assembler->LoadMap(lhs); | 1291 Node* lhs_map = assembler->LoadMap(lhs); |
1175 | 1292 |
1176 // Check if the {lhs} is a HeapNumber. | 1293 // Check if the {lhs} is a HeapNumber. |
1177 Label if_lhsisnumber(assembler), | 1294 assembler->GotoUnless( |
1178 if_lhsisnotnumber(assembler, Label::kDeferred); | 1295 assembler->WordEqual(lhs_map, assembler->HeapNumberMapConstant()), |
1179 Node* number_map = assembler->HeapNumberMapConstant(); | 1296 &call_subtract_stub); |
1180 assembler->Branch(assembler->WordEqual(lhs_map, number_map), | |
1181 &if_lhsisnumber, &if_lhsisnotnumber); | |
1182 | 1297 |
1183 assembler->Bind(&if_lhsisnumber); | 1298 // Check if the {rhs} is a Smi. |
| 1299 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 1300 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
| 1301 |
| 1302 assembler->Bind(&if_rhsissmi); |
1184 { | 1303 { |
1185 // Check if the {rhs} is a Smi. | 1304 // Perform a floating point subtraction. |
1186 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | 1305 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
1187 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, | 1306 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
1188 &if_rhsisnotsmi); | 1307 assembler->Goto(&do_fsub); |
1189 | |
1190 assembler->Bind(&if_rhsissmi); | |
1191 { | |
1192 var_type_feedback.Bind( | |
1193 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | |
1194 // Perform a floating point subtraction. | |
1195 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | |
1196 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); | |
1197 assembler->Goto(&do_fsub); | |
1198 } | |
1199 | |
1200 assembler->Bind(&if_rhsisnotsmi); | |
1201 { | |
1202 // Load the map of the {rhs}. | |
1203 Node* rhs_map = assembler->LoadMap(rhs); | |
1204 | |
1205 // Check if the {rhs} is a HeapNumber. | |
1206 Label if_rhsisnumber(assembler), | |
1207 if_rhsisnotnumber(assembler, Label::kDeferred); | |
1208 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
1209 &if_rhsisnumber, &if_rhsisnotnumber); | |
1210 | |
1211 assembler->Bind(&if_rhsisnumber); | |
1212 { | |
1213 var_type_feedback.Bind( | |
1214 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); | |
1215 // Perform a floating point subtraction. | |
1216 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); | |
1217 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); | |
1218 assembler->Goto(&do_fsub); | |
1219 } | |
1220 | |
1221 assembler->Bind(&if_rhsisnotnumber); | |
1222 { | |
1223 var_type_feedback.Bind( | |
1224 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | |
1225 assembler->Goto(&call_subtract_stub); | |
1226 } | |
1227 } | |
1228 } | 1308 } |
1229 | 1309 |
1230 assembler->Bind(&if_lhsisnotnumber); | 1310 assembler->Bind(&if_rhsisnotsmi); |
1231 { | 1311 { |
1232 var_type_feedback.Bind( | 1312 // Load the map of the {rhs}. |
1233 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | 1313 Node* rhs_map = assembler->LoadMap(rhs); |
1234 assembler->Goto(&call_subtract_stub); | 1314 |
| 1315 // Check if the {rhs} is a HeapNumber. |
| 1316 assembler->GotoUnless( |
| 1317 assembler->WordEqual(rhs_map, assembler->HeapNumberMapConstant()), |
| 1318 &call_subtract_stub); |
| 1319 |
| 1320 // Perform a floating point subtraction. |
| 1321 var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
| 1322 var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
| 1323 assembler->Goto(&do_fsub); |
1235 } | 1324 } |
1236 } | 1325 } |
1237 | 1326 |
1238 assembler->Bind(&do_fsub); | 1327 assembler->Bind(&do_fsub); |
1239 { | 1328 { |
| 1329 var_type_feedback.Bind( |
| 1330 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
1240 Node* lhs_value = var_fsub_lhs.value(); | 1331 Node* lhs_value = var_fsub_lhs.value(); |
1241 Node* rhs_value = var_fsub_rhs.value(); | 1332 Node* rhs_value = var_fsub_rhs.value(); |
1242 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1333 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
1243 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1334 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1244 assembler->Goto(&record_feedback); | 1335 assembler->Goto(&end); |
1245 } | 1336 } |
1246 | 1337 |
1247 assembler->Bind(&call_subtract_stub); | 1338 assembler->Bind(&call_subtract_stub); |
1248 { | 1339 { |
| 1340 var_type_feedback.Bind( |
| 1341 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
1249 Callable callable = CodeFactory::Subtract(assembler->isolate()); | 1342 Callable callable = CodeFactory::Subtract(assembler->isolate()); |
1250 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); | 1343 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
1251 assembler->Goto(&record_feedback); | 1344 assembler->Goto(&end); |
1252 } | 1345 } |
1253 | 1346 |
1254 assembler->Bind(&record_feedback); | 1347 assembler->Bind(&end); |
1255 Label combine_feedback(assembler), initialize_feedback(assembler), | 1348 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1256 return_value(assembler); | 1349 slot_id); |
1257 | |
1258 Node* previous_feedback = | |
1259 assembler->LoadFixedArrayElement(type_feedback_vector, slot_id); | |
1260 Node* is_uninitialized = assembler->WordEqual( | |
1261 previous_feedback, | |
1262 assembler->HeapConstant( | |
1263 TypeFeedbackVector::UninitializedSentinel(assembler->isolate()))); | |
1264 assembler->BranchIf(is_uninitialized, &initialize_feedback, | |
1265 &combine_feedback); | |
1266 | |
1267 assembler->Bind(&initialize_feedback); | |
1268 { | |
1269 assembler->StoreFixedArrayElement( | |
1270 type_feedback_vector, slot_id, | |
1271 assembler->SmiTag(var_type_feedback.value()), SKIP_WRITE_BARRIER); | |
1272 assembler->Goto(&return_value); | |
1273 } | |
1274 | |
1275 assembler->Bind(&combine_feedback); | |
1276 { | |
1277 Node* previous_feedback_int = assembler->SmiUntag(previous_feedback); | |
1278 Node* combined_feedback = | |
1279 assembler->Word32Or(previous_feedback_int, var_type_feedback.value()); | |
1280 assembler->StoreFixedArrayElement(type_feedback_vector, slot_id, | |
1281 assembler->SmiTag(combined_feedback), | |
1282 SKIP_WRITE_BARRIER); | |
1283 assembler->Goto(&return_value); | |
1284 } | |
1285 | |
1286 assembler->Bind(&return_value); | |
1287 return var_result.value(); | 1350 return var_result.value(); |
1288 } | 1351 } |
1289 | 1352 |
1290 // static | 1353 // static |
1291 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, | 1354 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
1292 compiler::Node* left, | 1355 compiler::Node* left, |
1293 compiler::Node* right, | 1356 compiler::Node* right, |
1294 compiler::Node* context) { | 1357 compiler::Node* context) { |
1295 using compiler::Node; | 1358 using compiler::Node; |
1296 typedef CodeStubAssembler::Label Label; | 1359 typedef CodeStubAssembler::Label Label; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 Node* result = assembler->ChangeFloat64ToTagged(value); | 1497 Node* result = assembler->ChangeFloat64ToTagged(value); |
1435 var_result.Bind(result); | 1498 var_result.Bind(result); |
1436 assembler->Goto(&return_result); | 1499 assembler->Goto(&return_result); |
1437 } | 1500 } |
1438 | 1501 |
1439 assembler->Bind(&return_result); | 1502 assembler->Bind(&return_result); |
1440 return var_result.value(); | 1503 return var_result.value(); |
1441 } | 1504 } |
1442 | 1505 |
1443 // static | 1506 // static |
| 1507 compiler::Node* MultiplyWithFeedbackStub::Generate( |
| 1508 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
| 1509 compiler::Node* context, compiler::Node* type_feedback_vector, |
| 1510 compiler::Node* slot_id) { |
| 1511 using compiler::Node; |
| 1512 typedef CodeStubAssembler::Label Label; |
| 1513 typedef CodeStubAssembler::Variable Variable; |
| 1514 |
| 1515 // Shared entry point for floating point multiplication. |
| 1516 Label do_fmul(assembler), end(assembler), |
| 1517 call_multiply_stub(assembler, Label::kDeferred); |
| 1518 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), |
| 1519 var_rhs_float64(assembler, MachineRepresentation::kFloat64), |
| 1520 var_result(assembler, MachineRepresentation::kTagged), |
| 1521 var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 1522 |
| 1523 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1524 |
| 1525 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); |
| 1526 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
| 1527 |
| 1528 assembler->Bind(&lhs_is_smi); |
| 1529 { |
| 1530 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); |
| 1531 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, &rhs_is_not_smi); |
| 1532 |
| 1533 assembler->Bind(&rhs_is_smi); |
| 1534 { |
| 1535 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi, |
| 1536 // in case of overflow. |
| 1537 var_result.Bind(assembler->SmiMul(lhs, rhs)); |
| 1538 var_type_feedback.Bind(assembler->Select( |
| 1539 assembler->WordIsSmi(var_result.value()), |
| 1540 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall), |
| 1541 assembler->Int32Constant(BinaryOperationFeedback::kNumber), |
| 1542 MachineRepresentation::kWord32)); |
| 1543 assembler->Goto(&end); |
| 1544 } |
| 1545 |
| 1546 assembler->Bind(&rhs_is_not_smi); |
| 1547 { |
| 1548 Node* rhs_map = assembler->LoadMap(rhs); |
| 1549 |
| 1550 // Check if {rhs} is a HeapNumber. |
| 1551 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), |
| 1552 &call_multiply_stub); |
| 1553 |
| 1554 // Convert {lhs} to a double and multiply it with the value of {rhs}. |
| 1555 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); |
| 1556 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); |
| 1557 assembler->Goto(&do_fmul); |
| 1558 } |
| 1559 } |
| 1560 |
| 1561 assembler->Bind(&lhs_is_not_smi); |
| 1562 { |
| 1563 Node* lhs_map = assembler->LoadMap(lhs); |
| 1564 |
| 1565 // Check if {lhs} is a HeapNumber. |
| 1566 assembler->GotoUnless(assembler->WordEqual(lhs_map, number_map), |
| 1567 &call_multiply_stub); |
| 1568 |
| 1569 // Check if {rhs} is a Smi. |
| 1570 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); |
| 1571 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, &rhs_is_not_smi); |
| 1572 |
| 1573 assembler->Bind(&rhs_is_smi); |
| 1574 { |
| 1575 // Convert {rhs} to a double and multiply it with the value of {lhs}. |
| 1576 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); |
| 1577 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); |
| 1578 assembler->Goto(&do_fmul); |
| 1579 } |
| 1580 |
| 1581 assembler->Bind(&rhs_is_not_smi); |
| 1582 { |
| 1583 Node* rhs_map = assembler->LoadMap(rhs); |
| 1584 |
| 1585 // Check if {rhs} is a HeapNumber. |
| 1586 assembler->GotoUnless(assembler->WordEqual(rhs_map, number_map), |
| 1587 &call_multiply_stub); |
| 1588 |
| 1589 // Both {lhs} and {rhs} are HeapNumbers. Load their values and |
| 1590 // multiply them. |
| 1591 var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs)); |
| 1592 var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs)); |
| 1593 assembler->Goto(&do_fmul); |
| 1594 } |
| 1595 } |
| 1596 |
| 1597 assembler->Bind(&do_fmul); |
| 1598 { |
| 1599 var_type_feedback.Bind( |
| 1600 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 1601 Node* value = |
| 1602 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
| 1603 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 1604 var_result.Bind(result); |
| 1605 assembler->Goto(&end); |
| 1606 } |
| 1607 |
| 1608 assembler->Bind(&call_multiply_stub); |
| 1609 { |
| 1610 var_type_feedback.Bind( |
| 1611 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1612 Callable callable = CodeFactory::Multiply(assembler->isolate()); |
| 1613 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
| 1614 assembler->Goto(&end); |
| 1615 } |
| 1616 |
| 1617 assembler->Bind(&end); |
| 1618 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 1619 slot_id); |
| 1620 return var_result.value(); |
| 1621 } |
| 1622 |
| 1623 // static |
1444 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler, | 1624 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler, |
1445 compiler::Node* left, | 1625 compiler::Node* left, |
1446 compiler::Node* right, | 1626 compiler::Node* right, |
1447 compiler::Node* context) { | 1627 compiler::Node* context) { |
1448 using compiler::Node; | 1628 using compiler::Node; |
1449 typedef CodeStubAssembler::Label Label; | 1629 typedef CodeStubAssembler::Label Label; |
1450 typedef CodeStubAssembler::Variable Variable; | 1630 typedef CodeStubAssembler::Variable Variable; |
1451 | 1631 |
1452 // Shared entry point for floating point division. | 1632 // Shared entry point for floating point division. |
1453 Label do_fdiv(assembler), end(assembler); | 1633 Label do_fdiv(assembler), end(assembler); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 Node* value = assembler->Float64Div(var_dividend_float64.value(), | 1832 Node* value = assembler->Float64Div(var_dividend_float64.value(), |
1653 var_divisor_float64.value()); | 1833 var_divisor_float64.value()); |
1654 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1834 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1655 assembler->Goto(&end); | 1835 assembler->Goto(&end); |
1656 } | 1836 } |
1657 assembler->Bind(&end); | 1837 assembler->Bind(&end); |
1658 return var_result.value(); | 1838 return var_result.value(); |
1659 } | 1839 } |
1660 | 1840 |
1661 // static | 1841 // static |
| 1842 compiler::Node* DivideWithFeedbackStub::Generate( |
| 1843 CodeStubAssembler* assembler, compiler::Node* dividend, |
| 1844 compiler::Node* divisor, compiler::Node* context, |
| 1845 compiler::Node* type_feedback_vector, compiler::Node* slot_id) { |
| 1846 using compiler::Node; |
| 1847 typedef CodeStubAssembler::Label Label; |
| 1848 typedef CodeStubAssembler::Variable Variable; |
| 1849 |
| 1850 // Shared entry point for floating point division. |
| 1851 Label do_fdiv(assembler), end(assembler), call_divide_stub(assembler); |
| 1852 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), |
| 1853 var_divisor_float64(assembler, MachineRepresentation::kFloat64), |
| 1854 var_result(assembler, MachineRepresentation::kTagged), |
| 1855 var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 1856 |
| 1857 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1858 |
| 1859 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); |
| 1860 assembler->Branch(assembler->WordIsSmi(dividend), ÷nd_is_smi, |
| 1861 ÷nd_is_not_smi); |
| 1862 |
| 1863 assembler->Bind(÷nd_is_smi); |
| 1864 { |
| 1865 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 1866 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 1867 &divisor_is_not_smi); |
| 1868 |
| 1869 assembler->Bind(&divisor_is_smi); |
| 1870 { |
| 1871 Label bailout(assembler); |
| 1872 |
| 1873 // Do floating point division if {divisor} is zero. |
| 1874 assembler->GotoIf( |
| 1875 assembler->WordEqual(divisor, assembler->IntPtrConstant(0)), |
| 1876 &bailout); |
| 1877 |
| 1878 // Do floating point division {dividend} is zero and {divisor} is |
| 1879 // negative. |
| 1880 Label dividend_is_zero(assembler), dividend_is_not_zero(assembler); |
| 1881 assembler->Branch( |
| 1882 assembler->WordEqual(dividend, assembler->IntPtrConstant(0)), |
| 1883 ÷nd_is_zero, ÷nd_is_not_zero); |
| 1884 |
| 1885 assembler->Bind(÷nd_is_zero); |
| 1886 { |
| 1887 assembler->GotoIf( |
| 1888 assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)), |
| 1889 &bailout); |
| 1890 assembler->Goto(÷nd_is_not_zero); |
| 1891 } |
| 1892 assembler->Bind(÷nd_is_not_zero); |
| 1893 |
| 1894 Node* untagged_divisor = assembler->SmiUntag(divisor); |
| 1895 Node* untagged_dividend = assembler->SmiUntag(dividend); |
| 1896 |
| 1897 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1 |
| 1898 // if the Smi size is 31) and {divisor} is -1. |
| 1899 Label divisor_is_minus_one(assembler), |
| 1900 divisor_is_not_minus_one(assembler); |
| 1901 assembler->Branch(assembler->Word32Equal(untagged_divisor, |
| 1902 assembler->Int32Constant(-1)), |
| 1903 &divisor_is_minus_one, &divisor_is_not_minus_one); |
| 1904 |
| 1905 assembler->Bind(&divisor_is_minus_one); |
| 1906 { |
| 1907 assembler->GotoIf( |
| 1908 assembler->Word32Equal( |
| 1909 untagged_dividend, |
| 1910 assembler->Int32Constant(kSmiValueSize == 32 ? kMinInt |
| 1911 : (kMinInt >> 1))), |
| 1912 &bailout); |
| 1913 assembler->Goto(&divisor_is_not_minus_one); |
| 1914 } |
| 1915 assembler->Bind(&divisor_is_not_minus_one); |
| 1916 |
| 1917 Node* untagged_result = |
| 1918 assembler->Int32Div(untagged_dividend, untagged_divisor); |
| 1919 Node* truncated = assembler->IntPtrMul(untagged_result, untagged_divisor); |
| 1920 // Do floating point division if the remainder is not 0. |
| 1921 assembler->GotoIf(assembler->Word32NotEqual(untagged_dividend, truncated), |
| 1922 &bailout); |
| 1923 var_type_feedback.Bind( |
| 1924 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)); |
| 1925 var_result.Bind(assembler->SmiTag(untagged_result)); |
| 1926 assembler->Goto(&end); |
| 1927 |
| 1928 // Bailout: convert {dividend} and {divisor} to double and do double |
| 1929 // division. |
| 1930 assembler->Bind(&bailout); |
| 1931 { |
| 1932 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
| 1933 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
| 1934 assembler->Goto(&do_fdiv); |
| 1935 } |
| 1936 } |
| 1937 |
| 1938 assembler->Bind(&divisor_is_not_smi); |
| 1939 { |
| 1940 Node* divisor_map = assembler->LoadMap(divisor); |
| 1941 |
| 1942 // Check if {divisor} is a HeapNumber. |
| 1943 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
| 1944 &call_divide_stub); |
| 1945 |
| 1946 // Convert {dividend} to a double and divide it with the value of |
| 1947 // {divisor}. |
| 1948 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
| 1949 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 1950 assembler->Goto(&do_fdiv); |
| 1951 } |
| 1952 |
| 1953 assembler->Bind(÷nd_is_not_smi); |
| 1954 { |
| 1955 Node* dividend_map = assembler->LoadMap(dividend); |
| 1956 |
| 1957 // Check if {dividend} is a HeapNumber. |
| 1958 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), |
| 1959 &call_divide_stub); |
| 1960 |
| 1961 // Check if {divisor} is a Smi. |
| 1962 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 1963 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 1964 &divisor_is_not_smi); |
| 1965 |
| 1966 assembler->Bind(&divisor_is_smi); |
| 1967 { |
| 1968 // Convert {divisor} to a double and use it for a floating point |
| 1969 // division. |
| 1970 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 1971 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
| 1972 assembler->Goto(&do_fdiv); |
| 1973 } |
| 1974 |
| 1975 assembler->Bind(&divisor_is_not_smi); |
| 1976 { |
| 1977 Node* divisor_map = assembler->LoadMap(divisor); |
| 1978 |
| 1979 // Check if {divisor} is a HeapNumber. |
| 1980 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
| 1981 &call_divide_stub); |
| 1982 |
| 1983 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
| 1984 // and divide them. |
| 1985 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 1986 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 1987 assembler->Goto(&do_fdiv); |
| 1988 } |
| 1989 } |
| 1990 } |
| 1991 |
| 1992 assembler->Bind(&do_fdiv); |
| 1993 { |
| 1994 var_type_feedback.Bind( |
| 1995 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 1996 Node* value = assembler->Float64Div(var_dividend_float64.value(), |
| 1997 var_divisor_float64.value()); |
| 1998 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
| 1999 assembler->Goto(&end); |
| 2000 } |
| 2001 |
| 2002 assembler->Bind(&call_divide_stub); |
| 2003 { |
| 2004 var_type_feedback.Bind( |
| 2005 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 2006 Callable callable = CodeFactory::Divide(assembler->isolate()); |
| 2007 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); |
| 2008 assembler->Goto(&end); |
| 2009 } |
| 2010 |
| 2011 assembler->Bind(&end); |
| 2012 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 2013 slot_id); |
| 2014 return var_result.value(); |
| 2015 } |
| 2016 |
| 2017 // static |
1662 compiler::Node* ModulusStub::Generate(CodeStubAssembler* assembler, | 2018 compiler::Node* ModulusStub::Generate(CodeStubAssembler* assembler, |
1663 compiler::Node* left, | 2019 compiler::Node* left, |
1664 compiler::Node* right, | 2020 compiler::Node* right, |
1665 compiler::Node* context) { | 2021 compiler::Node* context) { |
1666 using compiler::Node; | 2022 using compiler::Node; |
1667 typedef CodeStubAssembler::Label Label; | 2023 typedef CodeStubAssembler::Label Label; |
1668 typedef CodeStubAssembler::Variable Variable; | 2024 typedef CodeStubAssembler::Variable Variable; |
1669 | 2025 |
1670 Variable var_result(assembler, MachineRepresentation::kTagged); | 2026 Variable var_result(assembler, MachineRepresentation::kTagged); |
1671 Label return_result(assembler, &var_result); | 2027 Label return_result(assembler, &var_result); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1811 var_divisor_float64.value()); | 2167 var_divisor_float64.value()); |
1812 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 2168 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1813 assembler->Goto(&return_result); | 2169 assembler->Goto(&return_result); |
1814 } | 2170 } |
1815 | 2171 |
1816 assembler->Bind(&return_result); | 2172 assembler->Bind(&return_result); |
1817 return var_result.value(); | 2173 return var_result.value(); |
1818 } | 2174 } |
1819 | 2175 |
1820 // static | 2176 // static |
| 2177 compiler::Node* ModulusWithFeedbackStub::Generate( |
| 2178 CodeStubAssembler* assembler, compiler::Node* dividend, |
| 2179 compiler::Node* divisor, compiler::Node* context, |
| 2180 compiler::Node* type_feedback_vector, compiler::Node* slot_id) { |
| 2181 using compiler::Node; |
| 2182 typedef CodeStubAssembler::Label Label; |
| 2183 typedef CodeStubAssembler::Variable Variable; |
| 2184 |
| 2185 // Shared entry point for floating point division. |
| 2186 Label do_fmod(assembler), end(assembler), call_modulus_stub(assembler); |
| 2187 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), |
| 2188 var_divisor_float64(assembler, MachineRepresentation::kFloat64), |
| 2189 var_result(assembler, MachineRepresentation::kTagged), |
| 2190 var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 2191 |
| 2192 Node* number_map = assembler->HeapNumberMapConstant(); |
| 2193 |
| 2194 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); |
| 2195 assembler->Branch(assembler->WordIsSmi(dividend), ÷nd_is_smi, |
| 2196 ÷nd_is_not_smi); |
| 2197 |
| 2198 assembler->Bind(÷nd_is_smi); |
| 2199 { |
| 2200 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 2201 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 2202 &divisor_is_not_smi); |
| 2203 |
| 2204 assembler->Bind(&divisor_is_smi); |
| 2205 { |
| 2206 var_result.Bind(assembler->SmiMod(dividend, divisor)); |
| 2207 var_type_feedback.Bind(assembler->Select( |
| 2208 assembler->WordIsSmi(var_result.value()), |
| 2209 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall), |
| 2210 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); |
| 2211 assembler->Goto(&end); |
| 2212 } |
| 2213 |
| 2214 assembler->Bind(&divisor_is_not_smi); |
| 2215 { |
| 2216 Node* divisor_map = assembler->LoadMap(divisor); |
| 2217 |
| 2218 // Check if {divisor} is a HeapNumber. |
| 2219 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
| 2220 &call_modulus_stub); |
| 2221 |
| 2222 // Convert {dividend} to a double and divide it with the value of |
| 2223 // {divisor}. |
| 2224 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
| 2225 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 2226 assembler->Goto(&do_fmod); |
| 2227 } |
| 2228 } |
| 2229 |
| 2230 assembler->Bind(÷nd_is_not_smi); |
| 2231 { |
| 2232 Node* dividend_map = assembler->LoadMap(dividend); |
| 2233 |
| 2234 // Check if {dividend} is a HeapNumber. |
| 2235 assembler->GotoUnless(assembler->WordEqual(dividend_map, number_map), |
| 2236 &call_modulus_stub); |
| 2237 |
| 2238 // Check if {divisor} is a Smi. |
| 2239 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 2240 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 2241 &divisor_is_not_smi); |
| 2242 |
| 2243 assembler->Bind(&divisor_is_smi); |
| 2244 { |
| 2245 // Convert {divisor} to a double and use it for a floating point |
| 2246 // division. |
| 2247 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 2248 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
| 2249 assembler->Goto(&do_fmod); |
| 2250 } |
| 2251 |
| 2252 assembler->Bind(&divisor_is_not_smi); |
| 2253 { |
| 2254 Node* divisor_map = assembler->LoadMap(divisor); |
| 2255 |
| 2256 // Check if {divisor} is a HeapNumber. |
| 2257 assembler->GotoUnless(assembler->WordEqual(divisor_map, number_map), |
| 2258 &call_modulus_stub); |
| 2259 |
| 2260 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
| 2261 // and divide them. |
| 2262 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 2263 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 2264 assembler->Goto(&do_fmod); |
| 2265 } |
| 2266 } |
| 2267 |
| 2268 assembler->Bind(&do_fmod); |
| 2269 { |
| 2270 var_type_feedback.Bind( |
| 2271 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 2272 Node* value = assembler->Float64Mod(var_dividend_float64.value(), |
| 2273 var_divisor_float64.value()); |
| 2274 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
| 2275 assembler->Goto(&end); |
| 2276 } |
| 2277 |
| 2278 assembler->Bind(&call_modulus_stub); |
| 2279 { |
| 2280 var_type_feedback.Bind( |
| 2281 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 2282 Callable callable = CodeFactory::Modulus(assembler->isolate()); |
| 2283 var_result.Bind(assembler->CallStub(callable, context, dividend, divisor)); |
| 2284 assembler->Goto(&end); |
| 2285 } |
| 2286 |
| 2287 assembler->Bind(&end); |
| 2288 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
| 2289 slot_id); |
| 2290 return var_result.value(); |
| 2291 } |
| 2292 // static |
1821 compiler::Node* ShiftLeftStub::Generate(CodeStubAssembler* assembler, | 2293 compiler::Node* ShiftLeftStub::Generate(CodeStubAssembler* assembler, |
1822 compiler::Node* left, | 2294 compiler::Node* left, |
1823 compiler::Node* right, | 2295 compiler::Node* right, |
1824 compiler::Node* context) { | 2296 compiler::Node* context) { |
1825 using compiler::Node; | 2297 using compiler::Node; |
1826 | 2298 |
1827 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 2299 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1828 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 2300 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1829 Node* shift_count = | 2301 Node* shift_count = |
1830 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 2302 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); |
(...skipping 3514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5345 if (type->Is(Type::UntaggedPointer())) { | 5817 if (type->Is(Type::UntaggedPointer())) { |
5346 return Representation::External(); | 5818 return Representation::External(); |
5347 } | 5819 } |
5348 | 5820 |
5349 DCHECK(!type->Is(Type::Untagged())); | 5821 DCHECK(!type->Is(Type::Untagged())); |
5350 return Representation::Tagged(); | 5822 return Representation::Tagged(); |
5351 } | 5823 } |
5352 | 5824 |
5353 } // namespace internal | 5825 } // namespace internal |
5354 } // namespace v8 | 5826 } // namespace v8 |
OLD | NEW |