| 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 |