Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_inliner.cc (revision 41687) |
| +++ runtime/vm/flow_graph_inliner.cc (working copy) |
| @@ -51,6 +51,8 @@ |
| DEFINE_FLAG(int, max_inlined_per_depth, 500, |
| "Max. number of inlined calls per depth"); |
| DEFINE_FLAG(bool, print_inlining_tree, false, "Print inlining tree"); |
| +DEFINE_FLAG(bool, enable_inlining_annotations, false, |
| + "Enable inlining annotations"); |
| DECLARE_FLAG(bool, compiler_stats); |
| DECLARE_FLAG(bool, enable_type_checks); |
| @@ -448,6 +450,25 @@ |
| }; |
| +static bool HasAnnotation(const Function& function, const char* annotation) { |
| + const Class& owner = Class::Handle(function.Owner()); |
| + const Library& library = Library::Handle(owner.library()); |
| + const Array& metadata = |
| + Array::Cast(Object::Handle(library.GetMetadata(function))); |
| + |
| + if (metadata.Length() > 0) { |
| + Object& val = Object::Handle(); |
| + for (intptr_t i = 0; i < metadata.Length(); i++) { |
| + val = metadata.At(i); |
| + if (val.IsString() && String::Cast(val).Equals(annotation)) { |
| + return true; |
| + } |
| + } |
| + } |
| + return false; |
| +} |
| + |
| + |
| class CallSiteInliner : public ValueObject { |
| public: |
| explicit CallSiteInliner(FlowGraph* flow_graph) |
| @@ -593,6 +614,12 @@ |
| return false; |
| } |
| + if (FLAG_enable_inlining_annotations && |
| + HasAnnotation(function, "NeverInline")) { |
|
Vyacheslav Egorov (Google)
2014/11/13 13:01:42
Maybe make a Symbol for this?
Florian Schneider
2014/11/13 13:38:53
I'll make it a constant variable. Symbol is not ne
|
| + TRACE_INLINING(OS::Print(" Bailout: NeverInline annotation\n")); |
| + return false; |
| + } |
| + |
| GrowableArray<Value*>* arguments = call_data->arguments; |
| const intptr_t constant_arguments = CountConstants(*arguments); |
| if (!ShouldWeInline(function, |
| @@ -614,7 +641,6 @@ |
| // Abort if this is a recursive occurrence. |
| Definition* call = call_data->call; |
| if (!FLAG_inline_recursive && IsCallRecursive(unoptimized_code, call)) { |
| - function.set_is_inlinable(false); |
| TRACE_INLINING(OS::Print(" Bailout: recursive function\n")); |
| PRINT_INLINING_TREE("Recursive function", |
| &call_data->caller, &function, call_data->call); |
| @@ -763,6 +789,7 @@ |
| &call_data->caller, &function, call_data->call); |
| return false; |
| } |
| + |
| if (function.IsInvokeFieldDispatcher() || |
| function.IsNoSuchMethodDispatcher()) { |
| // Append call sites to the currently processed list so that dispatcher |
| @@ -1685,6 +1712,13 @@ |
| bool FlowGraphInliner::AlwaysInline(const Function& function) { |
| + if (FLAG_enable_inlining_annotations && |
| + HasAnnotation(function, "AlwaysInline")) { |
|
Vyacheslav Egorov (Google)
2014/11/13 13:01:42
Maybe make a symbol for this?
Florian Schneider
2014/11/13 13:38:53
Done. Same as above.
|
| + TRACE_INLINING(OS::Print("AlwaysInline annotation for %s\n", |
| + function.ToCString())); |
| + return true; |
| + } |
| + |
| if (function.IsImplicitGetterFunction() || function.IsGetterFunction() || |
| function.IsImplicitSetterFunction() || function.IsSetterFunction()) { |
| const intptr_t count = function.optimized_instruction_count(); |