Chromium Code Reviews| 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), end(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(&end); | |
| 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(&end); | |
| 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(&end); | |
| 1252 } | |
| 1253 | |
| 1254 assembler->Bind(&end); | |
|
rmcilroy
2016/08/08 08:27:31
Could we rename this variable since its no longer
mythria
2016/08/09 00:51:59
Done.
| |
| 1255 Label combine_feedback(assembler), record_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, &record_feedback, &combine_feedback); | |
| 1265 | |
| 1266 assembler->Bind(&record_feedback); | |
| 1267 { | |
| 1268 assembler->StoreFixedArrayElement( | |
| 1269 type_feedback_vector, slot_id, | |
| 1270 assembler->SmiTag(var_type_feedback.value()), SKIP_WRITE_BARRIER); | |
| 1271 assembler->Goto(&return_value); | |
| 1272 } | |
| 1273 | |
| 1274 assembler->Bind(&combine_feedback); | |
| 1275 { | |
| 1276 Node* previous_feedback_int = assembler->SmiUntag(previous_feedback); | |
| 1277 Node* combined_feedback = | |
| 1278 assembler->Word32Or(previous_feedback_int, var_type_feedback.value()); | |
| 1279 assembler->StoreFixedArrayElement(type_feedback_vector, slot_id, | |
| 1280 assembler->SmiTag(combined_feedback), | |
| 1281 SKIP_WRITE_BARRIER); | |
| 1282 assembler->Goto(&return_value); | |
| 1283 } | |
| 1284 | |
| 1285 assembler->Bind(&return_value); | |
| 1286 return var_result.value(); | |
| 1287 } | |
| 1288 | |
| 1289 // static | |
| 1085 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, | 1290 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
| 1086 compiler::Node* left, | 1291 compiler::Node* left, |
| 1087 compiler::Node* right, | 1292 compiler::Node* right, |
| 1088 compiler::Node* context) { | 1293 compiler::Node* context) { |
| 1089 using compiler::Node; | 1294 using compiler::Node; |
| 1090 typedef CodeStubAssembler::Label Label; | 1295 typedef CodeStubAssembler::Label Label; |
| 1091 typedef CodeStubAssembler::Variable Variable; | 1296 typedef CodeStubAssembler::Variable Variable; |
| 1092 | 1297 |
| 1093 // Shared entry point for floating point multiplication. | 1298 // Shared entry point for floating point multiplication. |
| 1094 Label do_fmul(assembler), return_result(assembler); | 1299 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())) { | 5259 if (type->Is(Type::UntaggedPointer())) { |
| 5055 return Representation::External(); | 5260 return Representation::External(); |
| 5056 } | 5261 } |
| 5057 | 5262 |
| 5058 DCHECK(!type->Is(Type::Untagged())); | 5263 DCHECK(!type->Is(Type::Untagged())); |
| 5059 return Representation::Tagged(); | 5264 return Representation::Tagged(); |
| 5060 } | 5265 } |
| 5061 | 5266 |
| 5062 } // namespace internal | 5267 } // namespace internal |
| 5063 } // namespace v8 | 5268 } // namespace v8 |
| OLD | NEW |