| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 exception_handlers_list_(NULL), | 85 exception_handlers_list_(NULL), |
| 86 pc_descriptors_list_(NULL), | 86 pc_descriptors_list_(NULL), |
| 87 stackmap_table_builder_( | 87 stackmap_table_builder_( |
| 88 is_optimizing ? new StackmapTableBuilder() : NULL), | 88 is_optimizing ? new StackmapTableBuilder() : NULL), |
| 89 block_info_(block_order_.length()), | 89 block_info_(block_order_.length()), |
| 90 deopt_infos_(), | 90 deopt_infos_(), |
| 91 static_calls_target_table_(GrowableObjectArray::ZoneHandle( | 91 static_calls_target_table_(GrowableObjectArray::ZoneHandle( |
| 92 GrowableObjectArray::New())), | 92 GrowableObjectArray::New())), |
| 93 is_optimizing_(is_optimizing), | 93 is_optimizing_(is_optimizing), |
| 94 may_reoptimize_(false), | 94 may_reoptimize_(false), |
| 95 intrinsic_mode_(false), |
| 95 double_class_(Class::ZoneHandle( | 96 double_class_(Class::ZoneHandle( |
| 96 isolate_->object_store()->double_class())), | 97 isolate_->object_store()->double_class())), |
| 97 mint_class_(Class::ZoneHandle( | 98 mint_class_(Class::ZoneHandle( |
| 98 isolate_->object_store()->mint_class())), | 99 isolate_->object_store()->mint_class())), |
| 99 float32x4_class_(Class::ZoneHandle( | 100 float32x4_class_(Class::ZoneHandle( |
| 100 isolate_->object_store()->float32x4_class())), | 101 isolate_->object_store()->float32x4_class())), |
| 101 float64x2_class_(Class::ZoneHandle( | 102 float64x2_class_(Class::ZoneHandle( |
| 102 isolate_->object_store()->float64x2_class())), | 103 isolate_->object_store()->float64x2_class())), |
| 103 int32x4_class_(Class::ZoneHandle( | 104 int32x4_class_(Class::ZoneHandle( |
| 104 isolate_->object_store()->int32x4_class())), | 105 isolate_->object_store()->int32x4_class())), |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 ASSERT(Code::kSCallTableFunctionEntry == 1); | 509 ASSERT(Code::kSCallTableFunctionEntry == 1); |
| 509 static_calls_target_table_.Add(func); | 510 static_calls_target_table_.Add(func); |
| 510 ASSERT(Code::kSCallTableCodeEntry == 2); | 511 ASSERT(Code::kSCallTableCodeEntry == 2); |
| 511 static_calls_target_table_.Add(Code::Handle()); | 512 static_calls_target_table_.Add(Code::Handle()); |
| 512 } | 513 } |
| 513 | 514 |
| 514 | 515 |
| 515 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 516 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
| 516 intptr_t token_pos) { | 517 intptr_t token_pos) { |
| 517 ASSERT(is_optimizing()); | 518 ASSERT(is_optimizing()); |
| 519 ASSERT(!intrinsic_mode()); |
| 518 CompilerDeoptInfo* info = | 520 CompilerDeoptInfo* info = |
| 519 new CompilerDeoptInfo(deopt_id, | 521 new CompilerDeoptInfo(deopt_id, |
| 520 ICData::kDeoptAtCall, | 522 ICData::kDeoptAtCall, |
| 521 pending_deoptimization_env_); | 523 pending_deoptimization_env_); |
| 522 info->set_pc_offset(assembler()->CodeSize()); | 524 info->set_pc_offset(assembler()->CodeSize()); |
| 523 deopt_infos_.Add(info); | 525 deopt_infos_.Add(info); |
| 524 } | 526 } |
| 525 | 527 |
| 526 | 528 |
| 527 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters | 529 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 cpu_reg_slots); | 690 cpu_reg_slots); |
| 689 } | 691 } |
| 690 } | 692 } |
| 691 } | 693 } |
| 692 return env; | 694 return env; |
| 693 } | 695 } |
| 694 | 696 |
| 695 | 697 |
| 696 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 698 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 697 ICData::DeoptReasonId reason) { | 699 ICData::DeoptReasonId reason) { |
| 700 if (intrinsic_mode()) return &intrinsic_deopt_label_; |
| 701 |
| 698 ASSERT(is_optimizing_); | 702 ASSERT(is_optimizing_); |
| 699 CompilerDeoptInfoWithStub* stub = | 703 CompilerDeoptInfoWithStub* stub = |
| 700 new CompilerDeoptInfoWithStub(deopt_id, | 704 new CompilerDeoptInfoWithStub(deopt_id, |
| 701 reason, | 705 reason, |
| 702 pending_deoptimization_env_); | 706 pending_deoptimization_env_); |
| 703 deopt_infos_.Add(stub); | 707 deopt_infos_.Add(stub); |
| 704 return stub->entry_label(); | 708 return stub->entry_label(); |
| 705 } | 709 } |
| 706 | 710 |
| 707 | 711 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); | 820 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); |
| 817 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); | 821 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); |
| 818 const StoreInstanceFieldNode& store_node = | 822 const StoreInstanceFieldNode& store_node = |
| 819 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); | 823 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); |
| 820 if (store_node.field().guarded_cid() == kDynamicCid) { | 824 if (store_node.field().guarded_cid() == kDynamicCid) { |
| 821 GenerateInlinedSetter(store_node.field().Offset()); | 825 GenerateInlinedSetter(store_node.field().Offset()); |
| 822 return; | 826 return; |
| 823 } | 827 } |
| 824 } | 828 } |
| 825 } | 829 } |
| 826 // Even if an intrinsified version of the function was successfully | 830 |
| 827 // generated, it may fall through to the non-intrinsified method body. | 831 EnterIntrinsicMode(); |
| 828 Intrinsifier::Intrinsify(parsed_function().function(), assembler()); | 832 |
| 833 Intrinsifier::Intrinsify(parsed_function(), this); |
| 834 |
| 835 ExitIntrinsicMode(); |
| 836 // "Deoptimization" from intrinsic continues here. |
| 837 ASSERT(!intrinsic_deopt_label_.IsBound()); |
| 838 assembler()->Bind(&intrinsic_deopt_label_); |
| 829 } | 839 } |
| 830 | 840 |
| 831 | 841 |
| 832 void FlowGraphCompiler::GenerateInstanceCall( | 842 void FlowGraphCompiler::GenerateInstanceCall( |
| 833 intptr_t deopt_id, | 843 intptr_t deopt_id, |
| 834 intptr_t token_pos, | 844 intptr_t token_pos, |
| 835 intptr_t argument_count, | 845 intptr_t argument_count, |
| 836 LocationSummary* locs, | 846 LocationSummary* locs, |
| 837 const ICData& ic_data) { | 847 const ICData& ic_data) { |
| 838 ASSERT(!ic_data.IsNull()); | 848 ASSERT(!ic_data.IsNull()); |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 return true; | 1261 return true; |
| 1252 } | 1262 } |
| 1253 } | 1263 } |
| 1254 | 1264 |
| 1255 return false; | 1265 return false; |
| 1256 } | 1266 } |
| 1257 | 1267 |
| 1258 | 1268 |
| 1259 intptr_t ParallelMoveResolver::AllocateScratchRegister( | 1269 intptr_t ParallelMoveResolver::AllocateScratchRegister( |
| 1260 Location::Kind kind, | 1270 Location::Kind kind, |
| 1261 intptr_t blocked, | 1271 uword blocked_mask, |
| 1262 intptr_t first_free_register, | 1272 intptr_t first_free_register, |
| 1263 intptr_t last_free_register, | 1273 intptr_t last_free_register, |
| 1264 bool* spilled) { | 1274 bool* spilled) { |
| 1275 COMPILE_ASSERT(static_cast<intptr_t>(sizeof(blocked_mask)) * kBitsPerByte >= |
| 1276 kNumberOfFpuRegisters); |
| 1277 COMPILE_ASSERT(static_cast<intptr_t>(sizeof(blocked_mask)) * kBitsPerByte >= |
| 1278 kNumberOfCpuRegisters); |
| 1265 intptr_t scratch = -1; | 1279 intptr_t scratch = -1; |
| 1266 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { | 1280 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { |
| 1267 if ((blocked != reg) && | 1281 if ((((1u << reg) & blocked_mask) == 0) && |
| 1268 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) { | 1282 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) { |
| 1269 scratch = reg; | 1283 scratch = reg; |
| 1270 break; | 1284 break; |
| 1271 } | 1285 } |
| 1272 } | 1286 } |
| 1273 | 1287 |
| 1274 if (scratch == -1) { | 1288 if (scratch == -1) { |
| 1275 *spilled = true; | 1289 *spilled = true; |
| 1276 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { | 1290 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { |
| 1277 if (blocked != reg) { | 1291 if (((1u << reg) & blocked_mask) == 0) { |
| 1278 scratch = reg; | 1292 scratch = reg; |
| 1279 break; | 1293 break; |
| 1280 } | 1294 } |
| 1281 } | 1295 } |
| 1282 } else { | 1296 } else { |
| 1283 *spilled = false; | 1297 *spilled = false; |
| 1284 } | 1298 } |
| 1285 | 1299 |
| 1286 return scratch; | 1300 return scratch; |
| 1287 } | 1301 } |
| 1288 | 1302 |
| 1289 | 1303 |
| 1290 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( | 1304 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( |
| 1291 ParallelMoveResolver* resolver, FpuRegister blocked) | 1305 ParallelMoveResolver* resolver, FpuRegister blocked) |
| 1292 : resolver_(resolver), | 1306 : resolver_(resolver), |
| 1293 reg_(kNoFpuRegister), | 1307 reg_(kNoFpuRegister), |
| 1294 spilled_(false) { | 1308 spilled_(false) { |
| 1295 reg_ = static_cast<FpuRegister>( | 1309 reg_ = static_cast<FpuRegister>( |
| 1296 resolver_->AllocateScratchRegister(Location::kFpuRegister, | 1310 resolver_->AllocateScratchRegister(Location::kFpuRegister, |
| 1297 blocked, | 1311 1u << blocked, |
| 1298 0, | 1312 0, |
| 1299 kNumberOfFpuRegisters - 1, | 1313 kNumberOfFpuRegisters - 1, |
| 1300 &spilled_)); | 1314 &spilled_)); |
| 1301 | 1315 |
| 1302 if (spilled_) { | 1316 if (spilled_) { |
| 1303 resolver->SpillFpuScratch(reg_); | 1317 resolver->SpillFpuScratch(reg_); |
| 1304 } | 1318 } |
| 1305 } | 1319 } |
| 1306 | 1320 |
| 1307 | 1321 |
| 1308 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { | 1322 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { |
| 1309 if (spilled_) { | 1323 if (spilled_) { |
| 1310 resolver_->RestoreFpuScratch(reg_); | 1324 resolver_->RestoreFpuScratch(reg_); |
| 1311 } | 1325 } |
| 1312 } | 1326 } |
| 1313 | 1327 |
| 1314 | 1328 |
| 1315 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( | 1329 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( |
| 1316 ParallelMoveResolver* resolver, Register blocked) | 1330 ParallelMoveResolver* resolver, Register blocked) |
| 1317 : resolver_(resolver), | 1331 : resolver_(resolver), |
| 1318 reg_(kNoRegister), | 1332 reg_(kNoRegister), |
| 1319 spilled_(false) { | 1333 spilled_(false) { |
| 1334 uword blocked_mask = 1u << blocked; |
| 1335 if (resolver->compiler_->intrinsic_mode()) { |
| 1336 // Block additional registers that must be preserved for intrinsics. |
| 1337 blocked_mask |= 1u << ICREG; |
| 1338 blocked_mask |= 1u << ARGS_DESC_REG; |
| 1339 } |
| 1320 reg_ = static_cast<Register>( | 1340 reg_ = static_cast<Register>( |
| 1321 resolver_->AllocateScratchRegister(Location::kRegister, | 1341 resolver_->AllocateScratchRegister(Location::kRegister, |
| 1322 blocked, | 1342 1u << blocked, |
| 1323 kFirstFreeCpuRegister, | 1343 kFirstFreeCpuRegister, |
| 1324 kLastFreeCpuRegister, | 1344 kLastFreeCpuRegister, |
| 1325 &spilled_)); | 1345 &spilled_)); |
| 1326 | 1346 |
| 1327 if (spilled_) { | 1347 if (spilled_) { |
| 1328 resolver->SpillScratch(reg_); | 1348 resolver->SpillScratch(reg_); |
| 1329 } | 1349 } |
| 1330 } | 1350 } |
| 1331 | 1351 |
| 1332 | 1352 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 } | 1416 } |
| 1397 const ICData& ic_data = ICData::ZoneHandle(isolate(), ICData::New( | 1417 const ICData& ic_data = ICData::ZoneHandle(isolate(), ICData::New( |
| 1398 parsed_function().function(), String::Handle(isolate(), target.name()), | 1418 parsed_function().function(), String::Handle(isolate(), target.name()), |
| 1399 arguments_descriptor, deopt_id, num_args_tested)); | 1419 arguments_descriptor, deopt_id, num_args_tested)); |
| 1400 ic_data.AddTarget(target); | 1420 ic_data.AddTarget(target); |
| 1401 (*deopt_id_to_ic_data_)[deopt_id] = &ic_data; | 1421 (*deopt_id_to_ic_data_)[deopt_id] = &ic_data; |
| 1402 return &ic_data; | 1422 return &ic_data; |
| 1403 } | 1423 } |
| 1404 | 1424 |
| 1405 } // namespace dart | 1425 } // namespace dart |
| OLD | NEW |