| 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,13 @@
|
| return false;
|
| }
|
|
|
| + const char* kNeverInlineAnnotation = "NeverInline";
|
| + if (FLAG_enable_inlining_annotations &&
|
| + HasAnnotation(function, kNeverInlineAnnotation)) {
|
| + 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 +642,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);
|
| @@ -1685,6 +1712,14 @@
|
|
|
|
|
| bool FlowGraphInliner::AlwaysInline(const Function& function) {
|
| + const char* kAlwaysInlineAnnotation = "AlwaysInline";
|
| + if (FLAG_enable_inlining_annotations &&
|
| + HasAnnotation(function, kAlwaysInlineAnnotation)) {
|
| + 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();
|
|
|