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 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 ASSERT(Code::kSCallTableCodeEntry == 2); | 469 ASSERT(Code::kSCallTableCodeEntry == 2); |
470 static_calls_target_table_.Add(Code::Handle()); | 470 static_calls_target_table_.Add(Code::Handle()); |
471 } | 471 } |
472 | 472 |
473 | 473 |
474 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 474 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
475 intptr_t token_pos) { | 475 intptr_t token_pos) { |
476 ASSERT(is_optimizing()); | 476 ASSERT(is_optimizing()); |
477 CompilerDeoptInfo* info = | 477 CompilerDeoptInfo* info = |
478 new CompilerDeoptInfo(deopt_id, | 478 new CompilerDeoptInfo(deopt_id, |
479 kDeoptAtCall, | 479 ICData::kDeoptAtCall, |
480 pending_deoptimization_env_); | 480 pending_deoptimization_env_); |
481 info->set_pc_offset(assembler()->CodeSize()); | 481 info->set_pc_offset(assembler()->CodeSize()); |
482 deopt_infos_.Add(info); | 482 deopt_infos_.Add(info); |
483 } | 483 } |
484 | 484 |
485 | 485 |
486 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters | 486 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters |
487 // and FlowGraphCompiler::SlowPathEnvironmentFor. | 487 // and FlowGraphCompiler::SlowPathEnvironmentFor. |
488 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { | 488 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { |
489 if (is_optimizing()) { | 489 if (is_optimizing()) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 def->AsMaterializeObject()->RemapRegisters(fpu_reg_slots, | 626 def->AsMaterializeObject()->RemapRegisters(fpu_reg_slots, |
627 cpu_reg_slots); | 627 cpu_reg_slots); |
628 } | 628 } |
629 } | 629 } |
630 } | 630 } |
631 return env; | 631 return env; |
632 } | 632 } |
633 | 633 |
634 | 634 |
635 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 635 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
636 DeoptReasonId reason) { | 636 ICData::DeoptReasonId reason) { |
637 ASSERT(is_optimizing_); | 637 ASSERT(is_optimizing_); |
638 CompilerDeoptInfoWithStub* stub = | 638 CompilerDeoptInfoWithStub* stub = |
639 new CompilerDeoptInfoWithStub(deopt_id, | 639 new CompilerDeoptInfoWithStub(deopt_id, |
640 reason, | 640 reason, |
641 pending_deoptimization_env_); | 641 pending_deoptimization_env_); |
642 deopt_infos_.Add(stub); | 642 deopt_infos_.Add(stub); |
643 return stub->entry_label(); | 643 return stub->entry_label(); |
644 } | 644 } |
645 | 645 |
646 | 646 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 intptr_t deopt_id, | 765 intptr_t deopt_id, |
766 intptr_t token_pos, | 766 intptr_t token_pos, |
767 intptr_t argument_count, | 767 intptr_t argument_count, |
768 const Array& argument_names, | 768 const Array& argument_names, |
769 LocationSummary* locs, | 769 LocationSummary* locs, |
770 const ICData& ic_data) { | 770 const ICData& ic_data) { |
771 ASSERT(!ic_data.IsNull()); | 771 ASSERT(!ic_data.IsNull()); |
772 ASSERT(FLAG_propagate_ic_data || (ic_data.NumberOfChecks() == 0)); | 772 ASSERT(FLAG_propagate_ic_data || (ic_data.NumberOfChecks() == 0)); |
773 uword label_address = 0; | 773 uword label_address = 0; |
774 if (is_optimizing() && (ic_data.NumberOfChecks() == 0)) { | 774 if (is_optimizing() && (ic_data.NumberOfChecks() == 0)) { |
775 if (ic_data.is_closure_call()) { | 775 if (ic_data.IsClosureCall()) { |
776 // This IC call may be closure call only. | 776 // This IC call may be closure call only. |
777 label_address = StubCode::ClosureCallInlineCacheEntryPoint(); | 777 label_address = StubCode::ClosureCallInlineCacheEntryPoint(); |
778 ExternalLabel target_label("InlineCache", label_address); | 778 ExternalLabel target_label("InlineCache", label_address); |
779 EmitInstanceCall(&target_label, | 779 EmitInstanceCall(&target_label, |
780 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()), | 780 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()), |
781 argument_count, deopt_id, token_pos, locs); | 781 argument_count, deopt_id, token_pos, locs); |
782 return; | 782 return; |
783 } | 783 } |
784 // Emit IC call that will count and thus may need reoptimization at | 784 // Emit IC call that will count and thus may need reoptimization at |
785 // function entry. | 785 // function entry. |
786 ASSERT(!is_optimizing() | 786 ASSERT(!is_optimizing() |
787 || may_reoptimize() | 787 || may_reoptimize() |
788 || flow_graph().IsCompiledForOsr()); | 788 || flow_graph().IsCompiledForOsr()); |
789 switch (ic_data.num_args_tested()) { | 789 switch (ic_data.NumArgsTested()) { |
790 case 1: | 790 case 1: |
791 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint(); | 791 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint(); |
792 break; | 792 break; |
793 case 2: | 793 case 2: |
794 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint(); | 794 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint(); |
795 break; | 795 break; |
796 case 3: | 796 case 3: |
797 label_address = | 797 label_address = |
798 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint(); | 798 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint(); |
799 break; | 799 break; |
800 default: | 800 default: |
801 UNIMPLEMENTED(); | 801 UNIMPLEMENTED(); |
802 } | 802 } |
803 ExternalLabel target_label("InlineCache", label_address); | 803 ExternalLabel target_label("InlineCache", label_address); |
804 EmitOptimizedInstanceCall(&target_label, ic_data, | 804 EmitOptimizedInstanceCall(&target_label, ic_data, |
805 argument_count, deopt_id, token_pos, locs); | 805 argument_count, deopt_id, token_pos, locs); |
806 return; | 806 return; |
807 } | 807 } |
808 | 808 |
809 if (is_optimizing()) { | 809 if (is_optimizing()) { |
810 EmitMegamorphicInstanceCall(ic_data, argument_count, | 810 EmitMegamorphicInstanceCall(ic_data, argument_count, |
811 deopt_id, token_pos, locs); | 811 deopt_id, token_pos, locs); |
812 return; | 812 return; |
813 } | 813 } |
814 | 814 |
815 switch (ic_data.num_args_tested()) { | 815 switch (ic_data.NumArgsTested()) { |
816 case 1: | 816 case 1: |
817 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); | 817 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
818 break; | 818 break; |
819 case 2: | 819 case 2: |
820 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); | 820 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
821 break; | 821 break; |
822 case 3: | 822 case 3: |
823 label_address = StubCode::ThreeArgsCheckInlineCacheEntryPoint(); | 823 label_address = StubCode::ThreeArgsCheckInlineCacheEntryPoint(); |
824 break; | 824 break; |
825 default: | 825 default: |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 static int HighestCountFirst(const CidTarget* a, const CidTarget* b) { | 1282 static int HighestCountFirst(const CidTarget* a, const CidTarget* b) { |
1283 // Negative if 'a' should sort before 'b'. | 1283 // Negative if 'a' should sort before 'b'. |
1284 return b->count - a->count; | 1284 return b->count - a->count; |
1285 } | 1285 } |
1286 | 1286 |
1287 | 1287 |
1288 // Returns 'sorted' array in decreasing count order. | 1288 // Returns 'sorted' array in decreasing count order. |
1289 // The expected number of elements to sort is less than 10. | 1289 // The expected number of elements to sort is less than 10. |
1290 void FlowGraphCompiler::SortICDataByCount(const ICData& ic_data, | 1290 void FlowGraphCompiler::SortICDataByCount(const ICData& ic_data, |
1291 GrowableArray<CidTarget>* sorted) { | 1291 GrowableArray<CidTarget>* sorted) { |
1292 ASSERT(ic_data.num_args_tested() == 1); | 1292 ASSERT(ic_data.NumArgsTested() == 1); |
1293 const intptr_t len = ic_data.NumberOfChecks(); | 1293 const intptr_t len = ic_data.NumberOfChecks(); |
1294 sorted->Clear(); | 1294 sorted->Clear(); |
1295 | 1295 |
1296 for (int i = 0; i < len; i++) { | 1296 for (int i = 0; i < len; i++) { |
1297 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), | 1297 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), |
1298 &Function::ZoneHandle(ic_data.GetTargetAt(i)), | 1298 &Function::ZoneHandle(ic_data.GetTargetAt(i)), |
1299 ic_data.GetCountAt(i))); | 1299 ic_data.GetCountAt(i))); |
1300 } | 1300 } |
1301 sorted->Sort(HighestCountFirst); | 1301 sorted->Sort(HighestCountFirst); |
1302 } | 1302 } |
1303 | 1303 |
1304 } // namespace dart | 1304 } // namespace dart |
OLD | NEW |