summaryrefslogtreecommitdiff
path: root/compiler/optimizing/inliner.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/inliner.cc')
-rw-r--r--compiler/optimizing/inliner.cc20
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),