diff options
Diffstat (limited to 'compiler/optimizing/inliner.cc')
-rw-r--r-- | compiler/optimizing/inliner.cc | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index ac71ce9b8a..0157d654e2 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -64,6 +64,11 @@ static constexpr size_t kMaximumNumberOfCumulatedDexRegisters = 32; // much inlining compared to code locality. static constexpr size_t kMaximumNumberOfRecursiveCalls = 4; +// Limit recursive polymorphic call inlining to prevent code bloat, since it can quickly get out of +// hand in the presence of multiple Wrapper classes. We set this to 0 to disallow polymorphic +// recursive calls at all. +static constexpr size_t kMaximumNumberOfPolymorphicRecursiveCalls = 0; + // Controls the use of inline caches in AOT mode. static constexpr bool kUseAOTInlineCaches = true; @@ -952,8 +957,19 @@ bool HInliner::TryInlinePolymorphicCall( dex::TypeIndex class_index = FindClassIndexIn(handle.Get(), caller_compilation_unit_); HInstruction* return_replacement = nullptr; - LOG_NOTE() << "Try inline polymorphic call to " << method->PrettyMethod(); - if (!class_index.IsValid() || + + const bool too_many_polymorphic_recursive_calls = + CountRecursiveCallsOf(method) > kMaximumNumberOfPolymorphicRecursiveCalls; + if (too_many_polymorphic_recursive_calls) { + LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedPolymorphicRecursiveBudget) + << "Method " << method->PrettyMethod() + << " is not inlined because it has reached its polymorphic recursive call budget."; + } else if (class_index.IsValid()) { + LOG_NOTE() << "Try inline polymorphic call to " << method->PrettyMethod(); + } + + if (too_many_polymorphic_recursive_calls || + !class_index.IsValid() || !TryBuildAndInline(invoke_instruction, method, ReferenceTypeInfo::Create(handle, /* is_exact= */ true), |