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/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
6 | 6 |
7 #include "vm/block_scheduler.h" | 7 #include "vm/block_scheduler.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 !block_it.Done(); | 294 !block_it.Done(); |
295 block_it.Advance()) { | 295 block_it.Advance()) { |
296 for (ForwardInstructionIterator it(block_it.Current()); | 296 for (ForwardInstructionIterator it(block_it.Current()); |
297 !it.Done(); | 297 !it.Done(); |
298 it.Advance()) { | 298 it.Advance()) { |
299 Instruction* current = it.Current(); | 299 Instruction* current = it.Current(); |
300 if (current->IsPolymorphicInstanceCall()) { | 300 if (current->IsPolymorphicInstanceCall()) { |
301 PolymorphicInstanceCallInstr* instance_call = | 301 PolymorphicInstanceCallInstr* instance_call = |
302 current->AsPolymorphicInstanceCall(); | 302 current->AsPolymorphicInstanceCall(); |
303 if (!inline_only_recognized_methods || | 303 if (!inline_only_recognized_methods || |
304 instance_call->HasSingleRecognizedTarget()) { | 304 instance_call->HasSingleRecognizedTarget() || |
| 305 instance_call->HasSingleDispatcherTarget()) { |
305 instance_calls_.Add(InstanceCallInfo(instance_call, graph)); | 306 instance_calls_.Add(InstanceCallInfo(instance_call, graph)); |
306 } else { | 307 } else { |
307 // Method not inlined because inlining too deep and method | 308 // Method not inlined because inlining too deep and method |
308 // not recognized. | 309 // not recognized. |
309 if (FLAG_print_inlining_tree) { | 310 if (FLAG_print_inlining_tree) { |
310 const Function* caller = &graph->parsed_function().function(); | 311 const Function* caller = &graph->parsed_function().function(); |
311 const Function* target = | 312 const Function* target = |
312 &Function::ZoneHandle( | 313 &Function::ZoneHandle( |
313 instance_call->ic_data().GetTargetAt(0)); | 314 instance_call->ic_data().GetTargetAt(0)); |
314 inlined_info->Add(InlinedInfo( | 315 inlined_info->Add(InlinedInfo( |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 &inlined_info_); | 467 &inlined_info_); |
467 while (collected_call_sites_->HasCalls()) { | 468 while (collected_call_sites_->HasCalls()) { |
468 TRACE_INLINING(OS::Print(" Depth %" Pd " ----------\n", | 469 TRACE_INLINING(OS::Print(" Depth %" Pd " ----------\n", |
469 inlining_depth_)); | 470 inlining_depth_)); |
470 // Swap collected and inlining arrays and clear the new collecting array. | 471 // Swap collected and inlining arrays and clear the new collecting array. |
471 call_sites_temp = collected_call_sites_; | 472 call_sites_temp = collected_call_sites_; |
472 collected_call_sites_ = inlining_call_sites_; | 473 collected_call_sites_ = inlining_call_sites_; |
473 inlining_call_sites_ = call_sites_temp; | 474 inlining_call_sites_ = call_sites_temp; |
474 collected_call_sites_->Clear(); | 475 collected_call_sites_->Clear(); |
475 // Inline call sites at the current depth. | 476 // Inline call sites at the current depth. |
| 477 InlineInstanceCalls(); |
476 InlineStaticCalls(); | 478 InlineStaticCalls(); |
477 InlineClosureCalls(); | 479 InlineClosureCalls(); |
478 InlineInstanceCalls(); | |
479 // Increment the inlining depth. Checked before recursive inlining. | 480 // Increment the inlining depth. Checked before recursive inlining. |
480 ++inlining_depth_; | 481 ++inlining_depth_; |
481 } | 482 } |
482 collected_call_sites_ = NULL; | 483 collected_call_sites_ = NULL; |
483 inlining_call_sites_ = NULL; | 484 inlining_call_sites_ = NULL; |
484 } | 485 } |
485 | 486 |
486 bool inlined() const { return inlined_; } | 487 bool inlined() const { return inlined_; } |
487 | 488 |
488 double GrowthFactor() const { | 489 double GrowthFactor() const { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 call_site_count, | 706 call_site_count, |
706 constants_count)); | 707 constants_count)); |
707 if (FLAG_print_inlining_tree) { | 708 if (FLAG_print_inlining_tree) { |
708 inlined_info_.Add(InlinedInfo( | 709 inlined_info_.Add(InlinedInfo( |
709 &call_data->caller, &function, inlining_depth_, call_data->call, | 710 &call_data->caller, &function, inlining_depth_, call_data->call, |
710 "Heuristic fail")); | 711 "Heuristic fail")); |
711 } | 712 } |
712 return false; | 713 return false; |
713 } | 714 } |
714 | 715 |
715 collected_call_sites_->FindCallSites(callee_graph, | 716 if (function.IsInvokeFieldDispatcher() || |
716 inlining_depth_, | 717 function.IsNoSuchMethodDispatcher()) { |
717 &inlined_info_); | 718 // Append call sites to the currently processed list so that dispatcher |
| 719 // methods get inlined regardless of the current depth. |
| 720 inlining_call_sites_->FindCallSites(callee_graph, |
| 721 0, |
| 722 &inlined_info_); |
| 723 } else { |
| 724 collected_call_sites_->FindCallSites(callee_graph, |
| 725 inlining_depth_, |
| 726 &inlined_info_); |
| 727 } |
718 | 728 |
719 // Add the function to the cache. | 729 // Add the function to the cache. |
720 if (!in_cache) { | 730 if (!in_cache) { |
721 function_cache_.Add(parsed_function); | 731 function_cache_.Add(parsed_function); |
722 } | 732 } |
723 | 733 |
724 // Build succeeded so we restore the bailout jump. | 734 // Build succeeded so we restore the bailout jump. |
725 inlined_ = true; | 735 inlined_ = true; |
726 inlined_size_ += size; | 736 inlined_size_ += size; |
727 isolate->set_deopt_id(prev_deopt_id); | 737 isolate->set_deopt_id(prev_deopt_id); |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 OS::Print("After Inlining of %s\n", flow_graph_-> | 1658 OS::Print("After Inlining of %s\n", flow_graph_-> |
1649 parsed_function().function().ToFullyQualifiedCString()); | 1659 parsed_function().function().ToFullyQualifiedCString()); |
1650 FlowGraphPrinter printer(*flow_graph_); | 1660 FlowGraphPrinter printer(*flow_graph_); |
1651 printer.PrintBlocks(); | 1661 printer.PrintBlocks(); |
1652 } | 1662 } |
1653 } | 1663 } |
1654 } | 1664 } |
1655 } | 1665 } |
1656 | 1666 |
1657 } // namespace dart | 1667 } // namespace dart |
OLD | NEW |