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 | |
rmcilroy
2016/08/09 14:59:50
"division {dividend}" -> "division if {dividend}"
| |
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 3449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5280 if (type->Is(Type::UntaggedPointer())) { | 5752 if (type->Is(Type::UntaggedPointer())) { |
5281 return Representation::External(); | 5753 return Representation::External(); |
5282 } | 5754 } |
5283 | 5755 |
5284 DCHECK(!type->Is(Type::Untagged())); | 5756 DCHECK(!type->Is(Type::Untagged())); |
5285 return Representation::Tagged(); | 5757 return Representation::Tagged(); |
5286 } | 5758 } |
5287 | 5759 |
5288 } // namespace internal | 5760 } // namespace internal |
5289 } // namespace v8 | 5761 } // namespace v8 |
OLD | NEW |