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 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 Node* rhs_value = var_fsub_rhs.value(); | 1075 Node* rhs_value = var_fsub_rhs.value(); |
1076 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1076 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
1077 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1077 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1078 assembler->Goto(&end); | 1078 assembler->Goto(&end); |
1079 } | 1079 } |
1080 assembler->Bind(&end); | 1080 assembler->Bind(&end); |
1081 return var_result.value(); | 1081 return var_result.value(); |
1082 } | 1082 } |
1083 | 1083 |
1084 // static | 1084 // static |
| 1085 compiler::Node* SubtractWithFeedbackStub::Generate( |
| 1086 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs, |
| 1087 compiler::Node* context, compiler::Node* type_feedback_vector, |
| 1088 compiler::Node* slot_id) { |
| 1089 typedef CodeStubAssembler::Label Label; |
| 1090 typedef compiler::Node Node; |
| 1091 typedef CodeStubAssembler::Variable Variable; |
| 1092 |
| 1093 // Shared entry for floating point subtraction. |
| 1094 Label do_fsub(assembler), record_feedback(assembler), |
| 1095 call_subtract_stub(assembler, Label::kDeferred); |
| 1096 Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), |
| 1097 var_fsub_rhs(assembler, MachineRepresentation::kFloat64); |
| 1098 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
| 1099 Variable var_result(assembler, MachineRepresentation::kTagged); |
| 1100 |
| 1101 // Check if the {lhs} is a Smi or a HeapObject. |
| 1102 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
| 1103 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
| 1104 |
| 1105 assembler->Bind(&if_lhsissmi); |
| 1106 { |
| 1107 // Check if the {rhs} is also a Smi. |
| 1108 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 1109 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
| 1110 |
| 1111 assembler->Bind(&if_rhsissmi); |
| 1112 { |
| 1113 // Try a fast Smi subtraction first. |
| 1114 Node* pair = assembler->SmiSubWithOverflow(lhs, rhs); |
| 1115 Node* overflow = assembler->Projection(1, pair); |
| 1116 |
| 1117 // Check if the Smi subtraction overflowed. |
| 1118 Label if_overflow(assembler), if_notoverflow(assembler); |
| 1119 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
| 1120 |
| 1121 assembler->Bind(&if_overflow); |
| 1122 { |
| 1123 // lhs, rhs - smi and result - number. combined - number. |
| 1124 // 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)); |
| 1128 var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
| 1129 assembler->Goto(&do_fsub); |
| 1130 } |
| 1131 |
| 1132 assembler->Bind(&if_notoverflow); |
| 1133 // lhs, rhs, result smi. combined - smi. |
| 1134 var_type_feedback.Bind( |
| 1135 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)); |
| 1136 var_result.Bind(assembler->Projection(0, pair)); |
| 1137 assembler->Goto(&record_feedback); |
| 1138 } |
| 1139 |
| 1140 assembler->Bind(&if_rhsisnotsmi); |
| 1141 { |
| 1142 // Load the map of the {rhs}. |
| 1143 Node* rhs_map = assembler->LoadMap(rhs); |
| 1144 |
| 1145 // Check if {rhs} is a HeapNumber. |
| 1146 Label if_rhsisnumber(assembler), |
| 1147 if_rhsisnotnumber(assembler, Label::kDeferred); |
| 1148 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1149 assembler->Branch(assembler->WordEqual(rhs_map, number_map), |
| 1150 &if_rhsisnumber, &if_rhsisnotnumber); |
| 1151 |
| 1152 assembler->Bind(&if_rhsisnumber); |
| 1153 { |
| 1154 var_type_feedback.Bind( |
| 1155 assembler->Int32Constant(BinaryOperationFeedback::kNumber)); |
| 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 } |
| 1169 } |
| 1170 |
| 1171 assembler->Bind(&if_lhsisnotsmi); |
| 1172 { |
| 1173 // Load the map of the {lhs}. |
| 1174 Node* lhs_map = assembler->LoadMap(lhs); |
| 1175 |
| 1176 // Check if the {lhs} is a HeapNumber. |
| 1177 Label if_lhsisnumber(assembler), |
| 1178 if_lhsisnotnumber(assembler, Label::kDeferred); |
| 1179 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1180 assembler->Branch(assembler->WordEqual(lhs_map, number_map), |
| 1181 &if_lhsisnumber, &if_lhsisnotnumber); |
| 1182 |
| 1183 assembler->Bind(&if_lhsisnumber); |
| 1184 { |
| 1185 // Check if the {rhs} is a Smi. |
| 1186 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); |
| 1187 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, |
| 1188 &if_rhsisnotsmi); |
| 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 } |
| 1229 |
| 1230 assembler->Bind(&if_lhsisnotnumber); |
| 1231 { |
| 1232 var_type_feedback.Bind( |
| 1233 assembler->Int32Constant(BinaryOperationFeedback::kAny)); |
| 1234 assembler->Goto(&call_subtract_stub); |
| 1235 } |
| 1236 } |
| 1237 |
| 1238 assembler->Bind(&do_fsub); |
| 1239 { |
| 1240 Node* lhs_value = var_fsub_lhs.value(); |
| 1241 Node* rhs_value = var_fsub_rhs.value(); |
| 1242 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
| 1243 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
| 1244 assembler->Goto(&record_feedback); |
| 1245 } |
| 1246 |
| 1247 assembler->Bind(&call_subtract_stub); |
| 1248 { |
| 1249 Callable callable = CodeFactory::Subtract(assembler->isolate()); |
| 1250 var_result.Bind(assembler->CallStub(callable, context, lhs, rhs)); |
| 1251 assembler->Goto(&record_feedback); |
| 1252 } |
| 1253 |
| 1254 assembler->Bind(&record_feedback); |
| 1255 Label combine_feedback(assembler), initialize_feedback(assembler), |
| 1256 return_value(assembler); |
| 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(); |
| 1288 } |
| 1289 |
| 1290 // static |
1085 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, | 1291 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
1086 compiler::Node* left, | 1292 compiler::Node* left, |
1087 compiler::Node* right, | 1293 compiler::Node* right, |
1088 compiler::Node* context) { | 1294 compiler::Node* context) { |
1089 using compiler::Node; | 1295 using compiler::Node; |
1090 typedef CodeStubAssembler::Label Label; | 1296 typedef CodeStubAssembler::Label Label; |
1091 typedef CodeStubAssembler::Variable Variable; | 1297 typedef CodeStubAssembler::Variable Variable; |
1092 | 1298 |
1093 // Shared entry point for floating point multiplication. | 1299 // Shared entry point for floating point multiplication. |
1094 Label do_fmul(assembler), return_result(assembler); | 1300 Label do_fmul(assembler), return_result(assembler); |
(...skipping 3959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5054 if (type->Is(Type::UntaggedPointer())) { | 5260 if (type->Is(Type::UntaggedPointer())) { |
5055 return Representation::External(); | 5261 return Representation::External(); |
5056 } | 5262 } |
5057 | 5263 |
5058 DCHECK(!type->Is(Type::Untagged())); | 5264 DCHECK(!type->Is(Type::Untagged())); |
5059 return Representation::Tagged(); | 5265 return Representation::Tagged(); |
5060 } | 5266 } |
5061 | 5267 |
5062 } // namespace internal | 5268 } // namespace internal |
5063 } // namespace v8 | 5269 } // namespace v8 |
OLD | NEW |