| 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/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 exception_handlers_list_(NULL), | 91 exception_handlers_list_(NULL), |
| 92 pc_descriptors_list_(NULL), | 92 pc_descriptors_list_(NULL), |
| 93 stackmap_table_builder_( | 93 stackmap_table_builder_( |
| 94 is_optimizing ? new StackmapTableBuilder() : NULL), | 94 is_optimizing ? new StackmapTableBuilder() : NULL), |
| 95 block_info_(block_order_.length()), | 95 block_info_(block_order_.length()), |
| 96 deopt_infos_(), | 96 deopt_infos_(), |
| 97 static_calls_target_table_(GrowableObjectArray::ZoneHandle( | 97 static_calls_target_table_(GrowableObjectArray::ZoneHandle( |
| 98 GrowableObjectArray::New())), | 98 GrowableObjectArray::New())), |
| 99 is_optimizing_(is_optimizing), | 99 is_optimizing_(is_optimizing), |
| 100 may_reoptimize_(false), | 100 may_reoptimize_(false), |
| 101 intrinsic_mode_(false), |
| 101 double_class_(Class::ZoneHandle( | 102 double_class_(Class::ZoneHandle( |
| 102 isolate_->object_store()->double_class())), | 103 isolate_->object_store()->double_class())), |
| 103 mint_class_(Class::ZoneHandle( | 104 mint_class_(Class::ZoneHandle( |
| 104 isolate_->object_store()->mint_class())), | 105 isolate_->object_store()->mint_class())), |
| 105 float32x4_class_(Class::ZoneHandle( | 106 float32x4_class_(Class::ZoneHandle( |
| 106 isolate_->object_store()->float32x4_class())), | 107 isolate_->object_store()->float32x4_class())), |
| 107 float64x2_class_(Class::ZoneHandle( | 108 float64x2_class_(Class::ZoneHandle( |
| 108 isolate_->object_store()->float64x2_class())), | 109 isolate_->object_store()->float64x2_class())), |
| 109 int32x4_class_(Class::ZoneHandle( | 110 int32x4_class_(Class::ZoneHandle( |
| 110 isolate_->object_store()->int32x4_class())), | 111 isolate_->object_store()->int32x4_class())), |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 ASSERT(Code::kSCallTableFunctionEntry == 1); | 541 ASSERT(Code::kSCallTableFunctionEntry == 1); |
| 541 static_calls_target_table_.Add(func); | 542 static_calls_target_table_.Add(func); |
| 542 ASSERT(Code::kSCallTableCodeEntry == 2); | 543 ASSERT(Code::kSCallTableCodeEntry == 2); |
| 543 static_calls_target_table_.Add(Code::Handle()); | 544 static_calls_target_table_.Add(Code::Handle()); |
| 544 } | 545 } |
| 545 | 546 |
| 546 | 547 |
| 547 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 548 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
| 548 intptr_t token_pos) { | 549 intptr_t token_pos) { |
| 549 ASSERT(is_optimizing()); | 550 ASSERT(is_optimizing()); |
| 551 ASSERT(!intrinsic_mode()); |
| 550 CompilerDeoptInfo* info = | 552 CompilerDeoptInfo* info = |
| 551 new CompilerDeoptInfo(deopt_id, | 553 new CompilerDeoptInfo(deopt_id, |
| 552 ICData::kDeoptAtCall, | 554 ICData::kDeoptAtCall, |
| 553 pending_deoptimization_env_); | 555 pending_deoptimization_env_); |
| 554 info->set_pc_offset(assembler()->CodeSize()); | 556 info->set_pc_offset(assembler()->CodeSize()); |
| 555 deopt_infos_.Add(info); | 557 deopt_infos_.Add(info); |
| 556 } | 558 } |
| 557 | 559 |
| 558 | 560 |
| 559 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters | 561 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 cpu_reg_slots); | 722 cpu_reg_slots); |
| 721 } | 723 } |
| 722 } | 724 } |
| 723 } | 725 } |
| 724 return env; | 726 return env; |
| 725 } | 727 } |
| 726 | 728 |
| 727 | 729 |
| 728 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 730 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 729 ICData::DeoptReasonId reason) { | 731 ICData::DeoptReasonId reason) { |
| 732 if (intrinsic_mode()) { |
| 733 return &intrinsic_deopt_label_; |
| 734 } |
| 735 |
| 730 ASSERT(is_optimizing_); | 736 ASSERT(is_optimizing_); |
| 731 CompilerDeoptInfoWithStub* stub = | 737 CompilerDeoptInfoWithStub* stub = |
| 732 new CompilerDeoptInfoWithStub(deopt_id, | 738 new CompilerDeoptInfoWithStub(deopt_id, |
| 733 reason, | 739 reason, |
| 734 pending_deoptimization_env_); | 740 pending_deoptimization_env_); |
| 735 deopt_infos_.Add(stub); | 741 deopt_infos_.Add(stub); |
| 736 return stub->entry_label(); | 742 return stub->entry_label(); |
| 737 } | 743 } |
| 738 | 744 |
| 739 | 745 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); | 854 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); |
| 849 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); | 855 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); |
| 850 const StoreInstanceFieldNode& store_node = | 856 const StoreInstanceFieldNode& store_node = |
| 851 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); | 857 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); |
| 852 if (store_node.field().guarded_cid() == kDynamicCid) { | 858 if (store_node.field().guarded_cid() == kDynamicCid) { |
| 853 GenerateInlinedSetter(store_node.field().Offset()); | 859 GenerateInlinedSetter(store_node.field().Offset()); |
| 854 return; | 860 return; |
| 855 } | 861 } |
| 856 } | 862 } |
| 857 } | 863 } |
| 858 // Even if an intrinsified version of the function was successfully | 864 |
| 859 // generated, it may fall through to the non-intrinsified method body. | 865 EnterIntrinsicMode(); |
| 860 Intrinsifier::Intrinsify(parsed_function().function(), assembler()); | 866 |
| 867 Intrinsifier::Intrinsify(&parsed_function(), this); |
| 868 |
| 869 ExitIntrinsicMode(); |
| 870 // "Deoptimization" from intrinsic continues here. All deoptimization |
| 871 // branches from intrinsic code redirect to here where the slow-path |
| 872 // (normal function body) starts. |
| 873 // This means that there must not be any side-effects in intrinsic code |
| 874 // before any deoptimization point. |
| 875 ASSERT(!intrinsic_deopt_label_.IsBound()); |
| 876 assembler()->Bind(&intrinsic_deopt_label_); |
| 861 } | 877 } |
| 862 | 878 |
| 863 | 879 |
| 864 void FlowGraphCompiler::GenerateInstanceCall( | 880 void FlowGraphCompiler::GenerateInstanceCall( |
| 865 intptr_t deopt_id, | 881 intptr_t deopt_id, |
| 866 intptr_t token_pos, | 882 intptr_t token_pos, |
| 867 intptr_t argument_count, | 883 intptr_t argument_count, |
| 868 LocationSummary* locs, | 884 LocationSummary* locs, |
| 869 const ICData& ic_data) { | 885 const ICData& ic_data) { |
| 870 ASSERT(!ic_data.IsNull()); | 886 ASSERT(!ic_data.IsNull()); |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 : resolver_(resolver), | 1377 : resolver_(resolver), |
| 1362 reg_(kNoRegister), | 1378 reg_(kNoRegister), |
| 1363 spilled_(false) { | 1379 spilled_(false) { |
| 1364 uword blocked_mask = MaskBit(blocked) | 1380 uword blocked_mask = MaskBit(blocked) |
| 1365 | MaskBit(CTX) | 1381 | MaskBit(CTX) |
| 1366 | MaskBit(SPREG) | 1382 | MaskBit(SPREG) |
| 1367 | MaskBit(FPREG) | 1383 | MaskBit(FPREG) |
| 1368 | MaskBit(TMP) | 1384 | MaskBit(TMP) |
| 1369 | MaskBit(TMP2) | 1385 | MaskBit(TMP2) |
| 1370 | MaskBit(PP); | 1386 | MaskBit(PP); |
| 1387 if (resolver->compiler_->intrinsic_mode()) { |
| 1388 // Block additional registers that must be preserved for intrinsics. |
| 1389 blocked_mask |= MaskBit(ARGS_DESC_REG); |
| 1390 } |
| 1371 reg_ = static_cast<Register>( | 1391 reg_ = static_cast<Register>( |
| 1372 resolver_->AllocateScratchRegister(Location::kRegister, | 1392 resolver_->AllocateScratchRegister(Location::kRegister, |
| 1373 blocked_mask, | 1393 blocked_mask, |
| 1374 kFirstFreeCpuRegister, | 1394 kFirstFreeCpuRegister, |
| 1375 kLastFreeCpuRegister, | 1395 kLastFreeCpuRegister, |
| 1376 &spilled_)); | 1396 &spilled_)); |
| 1377 | 1397 |
| 1378 if (spilled_) { | 1398 if (spilled_) { |
| 1379 resolver->SpillScratch(reg_); | 1399 resolver->SpillScratch(reg_); |
| 1380 } | 1400 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 threshold = FLAG_optimization_counter_scale * basic_blocks + | 1484 threshold = FLAG_optimization_counter_scale * basic_blocks + |
| 1465 FLAG_min_optimization_counter_threshold; | 1485 FLAG_min_optimization_counter_threshold; |
| 1466 if (threshold > FLAG_optimization_counter_threshold) { | 1486 if (threshold > FLAG_optimization_counter_threshold) { |
| 1467 threshold = FLAG_optimization_counter_threshold; | 1487 threshold = FLAG_optimization_counter_threshold; |
| 1468 } | 1488 } |
| 1469 } | 1489 } |
| 1470 return threshold; | 1490 return threshold; |
| 1471 } | 1491 } |
| 1472 | 1492 |
| 1473 } // namespace dart | 1493 } // namespace dart |
| OLD | NEW |