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

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

Issue 2224343002: [interpreter] Collect type feedback in Add, Mul, Div and Mod. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixes test-interpreter/InterpreterParameter8. 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
« no previous file with comments | « src/code-stubs.h ('k') | src/globals.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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), &dividend_is_smi,
1861 &dividend_is_not_smi);
1862
1863 assembler->Bind(&dividend_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 &dividend_is_zero, &dividend_is_not_zero);
1884
1885 assembler->Bind(&dividend_is_zero);
1886 {
1887 assembler->GotoIf(
1888 assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)),
1889 &bailout);
1890 assembler->Goto(&dividend_is_not_zero);
1891 }
1892 assembler->Bind(&dividend_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(&dividend_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
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), &dividend_is_smi,
2196 &dividend_is_not_smi);
2197
2198 assembler->Bind(&dividend_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(&dividend_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
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
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698