Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: runtime/vm/flow_graph_inliner.cc

Issue 790213004: Add inlining ranges/intervals to code objects so that we can map a pc to the inlined stack. The map… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return true; 467 return true;
468 } 468 }
469 } 469 }
470 } 470 }
471 return false; 471 return false;
472 } 472 }
473 473
474 474
475 class CallSiteInliner : public ValueObject { 475 class CallSiteInliner : public ValueObject {
476 public: 476 public:
477 explicit CallSiteInliner(FlowGraph* flow_graph) 477 explicit CallSiteInliner(FlowGraphInliner* inliner)
478 : caller_graph_(flow_graph), 478 : inliner_(inliner),
479 caller_graph_(inliner->flow_graph()),
479 inlined_(false), 480 inlined_(false),
480 initial_size_(flow_graph->InstructionCount()), 481 initial_size_(inliner->flow_graph()->InstructionCount()),
481 inlined_size_(0), 482 inlined_size_(0),
482 inlined_recursive_call_(false), 483 inlined_recursive_call_(false),
483 inlining_depth_(1), 484 inlining_depth_(1),
484 inlining_recursion_depth_(0), 485 inlining_recursion_depth_(0),
485 collected_call_sites_(NULL), 486 collected_call_sites_(NULL),
486 inlining_call_sites_(NULL), 487 inlining_call_sites_(NULL),
487 function_cache_(), 488 function_cache_(),
488 inlined_info_() { } 489 inlined_info_() { }
489 490
490 FlowGraph* caller_graph() const { return caller_graph_; } 491 FlowGraph* caller_graph() const { return caller_graph_; }
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 "const args: %" Pd "\n", 805 "const args: %" Pd "\n",
805 size, 806 size,
806 call_site_count, 807 call_site_count,
807 constants_count)); 808 constants_count));
808 PRINT_INLINING_TREE("Heuristic fail", 809 PRINT_INLINING_TREE("Heuristic fail",
809 &call_data->caller, &function, call_data->call); 810 &call_data->caller, &function, call_data->call);
810 return false; 811 return false;
811 } 812 }
812 813
813 // Inline dispatcher methods regardless of the current depth. 814 // Inline dispatcher methods regardless of the current depth.
814 intptr_t depth = 815 const intptr_t depth =
815 (function.IsInvokeFieldDispatcher() || 816 (function.IsInvokeFieldDispatcher() ||
816 function.IsNoSuchMethodDispatcher()) ? 0 : inlining_depth_; 817 function.IsNoSuchMethodDispatcher()) ? 0 : inlining_depth_;
817 collected_call_sites_->FindCallSites(callee_graph, depth, &inlined_info_); 818 collected_call_sites_->FindCallSites(callee_graph, depth, &inlined_info_);
818 819
819 // Add the function to the cache. 820 // Add the function to the cache.
820 if (!in_cache) { 821 if (!in_cache) {
821 function_cache_.Add(parsed_function); 822 function_cache_.Add(parsed_function);
822 } 823 }
823 824
824 // Build succeeded so we restore the bailout jump. 825 // Build succeeded so we restore the bailout jump.
(...skipping 11 matching lines...) Expand all
836 // When inlined, we add the guarded fields of the callee to the caller's 837 // When inlined, we add the guarded fields of the callee to the caller's
837 // list of guarded fields. 838 // list of guarded fields.
838 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) { 839 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) {
839 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(), 840 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
840 (*callee_graph->guarded_fields())[i]); 841 (*callee_graph->guarded_fields())[i]);
841 } 842 }
842 // When inlined, we add the deferred prefixes of the callee to the 843 // When inlined, we add the deferred prefixes of the callee to the
843 // caller's list of deferred prefixes. 844 // caller's list of deferred prefixes.
844 caller_graph()->AddToDeferredPrefixes(callee_graph->deferred_prefixes()); 845 caller_graph()->AddToDeferredPrefixes(callee_graph->deferred_prefixes());
845 846
847 FlowGraphInliner::SetInliningId(*callee_graph,
848 inliner_->NextInlineId(callee_graph->parsed_function()->function()));
846 // We allocate a ZoneHandle for the unoptimized code so that it cannot be 849 // We allocate a ZoneHandle for the unoptimized code so that it cannot be
847 // disconnected from its function during the rest of compilation. 850 // disconnected from its function during the rest of compilation.
848 Code::ZoneHandle(unoptimized_code.raw()); 851 Code::ZoneHandle(unoptimized_code.raw());
849 TRACE_INLINING(OS::Print(" Success\n")); 852 TRACE_INLINING(OS::Print(" Success\n"));
850 PRINT_INLINING_TREE(NULL, 853 PRINT_INLINING_TREE(NULL,
851 &call_data->caller, &function, call); 854 &call_data->caller, &function, call);
852 return true; 855 return true;
853 } else { 856 } else {
854 Error& error = Error::Handle(); 857 Error& error = Error::Handle();
855 error = isolate()->object_store()->sticky_error(); 858 error = isolate()->object_store()->sticky_error();
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 if (arg != NULL) { 1226 if (arg != NULL) {
1224 param_stubs->Add(CreateParameterStub(i, arg, callee_graph)); 1227 param_stubs->Add(CreateParameterStub(i, arg, callee_graph));
1225 } else { 1228 } else {
1226 param_stubs->Add( 1229 param_stubs->Add(
1227 GetDefaultValue(i - fixed_param_count, parsed_function)); 1230 GetDefaultValue(i - fixed_param_count, parsed_function));
1228 } 1231 }
1229 } 1232 }
1230 return argument_names_count == match_count; 1233 return argument_names_count == match_count;
1231 } 1234 }
1232 1235
1236 FlowGraphInliner* inliner_;
1233 FlowGraph* caller_graph_; 1237 FlowGraph* caller_graph_;
1234 bool inlined_; 1238 bool inlined_;
1235 const intptr_t initial_size_; 1239 const intptr_t initial_size_;
1236 intptr_t inlined_size_; 1240 intptr_t inlined_size_;
1237 bool inlined_recursive_call_; 1241 bool inlined_recursive_call_;
1238 intptr_t inlining_depth_; 1242 intptr_t inlining_depth_;
1239 intptr_t inlining_recursion_depth_; 1243 intptr_t inlining_recursion_depth_;
1240 CallSites* collected_call_sites_; 1244 CallSites* collected_call_sites_;
1241 CallSites* inlining_call_sites_; 1245 CallSites* inlining_call_sites_;
1242 GrowableArray<ParsedFunction*> function_cache_; 1246 GrowableArray<ParsedFunction*> function_cache_;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 GraphInfoCollector info; 1727 GraphInfoCollector info;
1724 info.Collect(*flow_graph); 1728 info.Collect(*flow_graph);
1725 1729
1726 function.set_optimized_instruction_count( 1730 function.set_optimized_instruction_count(
1727 ClampUint16(info.instruction_count())); 1731 ClampUint16(info.instruction_count()));
1728 function.set_optimized_call_site_count(ClampUint16(info.call_site_count())); 1732 function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
1729 } 1733 }
1730 } 1734 }
1731 1735
1732 1736
1737 // TODO(srdjan): This is only needed when disassembling and/or profiling.
1738 void FlowGraphInliner::SetInliningId(const FlowGraph& flow_graph,
1739 intptr_t inlining_id) {
1740 for (BlockIterator block_it = flow_graph.postorder_iterator();
1741 !block_it.Done();
1742 block_it.Advance()) {
1743 for (ForwardInstructionIterator it(block_it.Current());
1744 !it.Done();
1745 it.Advance()) {
1746 Instruction* current = it.Current();
1747 // Do not overwrite owner function.
1748 ASSERT(!current->has_inlining_id());
1749 current->set_inlining_id(inlining_id);
1750 }
1751 }
1752 }
1753
1754
1733 bool FlowGraphInliner::AlwaysInline(const Function& function) { 1755 bool FlowGraphInliner::AlwaysInline(const Function& function) {
1734 const char* kAlwaysInlineAnnotation = "AlwaysInline"; 1756 const char* kAlwaysInlineAnnotation = "AlwaysInline";
1735 if (FLAG_enable_inlining_annotations && 1757 if (FLAG_enable_inlining_annotations &&
1736 HasAnnotation(function, kAlwaysInlineAnnotation)) { 1758 HasAnnotation(function, kAlwaysInlineAnnotation)) {
1737 TRACE_INLINING(OS::Print("AlwaysInline annotation for %s\n", 1759 TRACE_INLINING(OS::Print("AlwaysInline annotation for %s\n",
1738 function.ToCString())); 1760 function.ToCString()));
1739 return true; 1761 return true;
1740 } 1762 }
1741 1763
1742 if (function.IsImplicitGetterFunction() || function.IsGetterFunction() || 1764 if (function.IsImplicitGetterFunction() || function.IsGetterFunction() ||
(...skipping 21 matching lines...) Expand all
1764 TRACE_INLINING(OS::Print("Inlining calls in %s\n", top.ToCString())); 1786 TRACE_INLINING(OS::Print("Inlining calls in %s\n", top.ToCString()));
1765 1787
1766 if (FLAG_trace_inlining && 1788 if (FLAG_trace_inlining &&
1767 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { 1789 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
1768 OS::Print("Before Inlining of %s\n", flow_graph_-> 1790 OS::Print("Before Inlining of %s\n", flow_graph_->
1769 parsed_function()->function().ToFullyQualifiedCString()); 1791 parsed_function()->function().ToFullyQualifiedCString());
1770 FlowGraphPrinter printer(*flow_graph_); 1792 FlowGraphPrinter printer(*flow_graph_);
1771 printer.PrintBlocks(); 1793 printer.PrintBlocks();
1772 } 1794 }
1773 1795
1774 CallSiteInliner inliner(flow_graph_); 1796 CallSiteInliner inliner(this);
1775 inliner.InlineCalls(); 1797 inliner.InlineCalls();
1776 if (FLAG_print_inlining_tree) { 1798 if (FLAG_print_inlining_tree) {
1777 inliner.PrintInlinedInfo(top); 1799 inliner.PrintInlinedInfo(top);
1778 } 1800 }
1779 1801
1780 if (inliner.inlined()) { 1802 if (inliner.inlined()) {
1781 flow_graph_->DiscoverBlocks(); 1803 flow_graph_->DiscoverBlocks();
1782 if (FLAG_trace_inlining) { 1804 if (FLAG_trace_inlining) {
1783 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 1805 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor());
1784 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 1806 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
1785 OS::Print("After Inlining of %s\n", flow_graph_-> 1807 OS::Print("After Inlining of %s\n", flow_graph_->
1786 parsed_function()->function().ToFullyQualifiedCString()); 1808 parsed_function()->function().ToFullyQualifiedCString());
1787 FlowGraphPrinter printer(*flow_graph_); 1809 FlowGraphPrinter printer(*flow_graph_);
1788 printer.PrintBlocks(); 1810 printer.PrintBlocks();
1789 } 1811 }
1790 } 1812 }
1791 } 1813 }
1792 } 1814 }
1793 1815
1816
1817 intptr_t FlowGraphInliner::NextInlineId(const Function& function) {
1818 const intptr_t id = inline_id_to_function_->length();
1819 inline_id_to_function_->Add(&function);
1820 return id;
1821 }
1822
1823
1794 } // namespace dart 1824 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698