diff options
-rw-r--r-- | compiler/optimizing/inliner.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 5 | ||||
-rw-r--r-- | test/2241-checker-inline-try-catch/src/Main.java | 37 |
3 files changed, 39 insertions, 19 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index e8b9b583ba..3e3b2d46ca 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1440,17 +1440,17 @@ bool HInliner::IsInliningSupported(const HInvoke* invoke_instruction, << " is not inlined because inlining try catches is disabled globally"; return false; } - const bool inlined_into_try_catch = - // Direct parent is a try catch. - invoke_instruction->GetBlock()->GetTryCatchInformation() != nullptr || - // Indirect parent is a try catch. + const bool disallowed_try_catch_inlining = + // Direct parent is a try block. + invoke_instruction->GetBlock()->IsTryBlock() || + // Indirect parent disallows try catch inlining. !try_catch_inlining_allowed_; - if (inlined_into_try_catch) { + if (disallowed_try_catch_inlining) { LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedTryCatchCallee) << "Method " << method->PrettyMethod() << " is not inlined because it has a try catch and we are not supporting it for this" << " particular call. This is could be because e.g. it would be inlined inside another" - << " try catch, we arrived here from TryInlinePolymorphicCall, etc."; + << " try block, we arrived here from TryInlinePolymorphicCall, etc."; return false; } } @@ -2139,8 +2139,8 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, const bool try_catch_inlining_allowed_for_recursive_inline = // It was allowed previously. try_catch_inlining_allowed_ && - // The current invoke is not in a try or a catch. - invoke_instruction->GetBlock()->GetTryCatchInformation() == nullptr; + // The current invoke is not a try block. + !invoke_instruction->GetBlock()->IsTryBlock(); RunOptimizations(callee_graph, code_item, dex_compilation_unit, diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 4a0ec93663..270bb4fb86 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2740,8 +2740,8 @@ void HGraph::UpdateLoopAndTryInformationOfNewBlock(HBasicBlock* block, } } - DCHECK_IMPLIES(has_more_specific_try_catch_info, reference->GetTryCatchInformation() == nullptr) - << "We don't allow to inline try catches inside of other try catches."; + DCHECK_IMPLIES(has_more_specific_try_catch_info, !reference->IsTryBlock()) + << "We don't allow to inline try catches inside of other try blocks."; // Update the TryCatchInformation, if we are not inlining a try catch. if (!has_more_specific_try_catch_info) { @@ -2832,6 +2832,7 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { HBasicBlock* first = entry_block_->GetSuccessors()[0]; DCHECK(!first->IsInLoop()); + DCHECK(first->GetTryCatchInformation() == nullptr); at->MergeWithInlined(first); exit_block_->ReplaceWith(to); diff --git a/test/2241-checker-inline-try-catch/src/Main.java b/test/2241-checker-inline-try-catch/src/Main.java index a76a99bd89..a80fbd7053 100644 --- a/test/2241-checker-inline-try-catch/src/Main.java +++ b/test/2241-checker-inline-try-catch/src/Main.java @@ -23,7 +23,8 @@ public class Main { $noinline$testTryCatchFinally(); $noinline$testTryCatchFinallyDifferentInputs(); $noinline$testRecursiveTryCatch(); - $noinline$testDoNotInlineInsideTryOrCatch(); + $noinline$testDoNotInlineInsideTryInlineInsideCatch(); + $noinline$testInlineInsideNestedCatches(); $noinline$testBeforeAfterTryCatch(); $noinline$testDifferentTypes(); $noinline$testRawThrow(); @@ -88,28 +89,46 @@ public class Main { $noinline$assertEquals(1, $inline$OOBTryCatchLevel4(numbers)); } - // Tests that we don't inline inside outer tries or catches. - /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryOrCatch() inliner (before) - /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch + // Tests that we don't inline inside outer tries, but we do inline inside of catches. + /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryInlineInsideCatch() inliner (before) /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch + /// CHECK: InvokeStaticOrDirect method_name:Main.$inline$OOBTryCatch - /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryOrCatch() inliner (after) - /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch + /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryInlineInsideCatch() inliner (after) /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch - private static void $noinline$testDoNotInlineInsideTryOrCatch() { + private static void $noinline$testDoNotInlineInsideTryInlineInsideCatch() { int val = 0; try { int[] numbers = {}; val = DoNotInlineOOBTryCatch(numbers); } catch (Exception ex) { unreachable(); - // This is unreachable but we will still compile it so it works for checker purposes + // This is unreachable but we will still compile it so it works for checking that it inlines. int[] numbers = {}; - DoNotInlineOOBTryCatch(numbers); + $inline$OOBTryCatch(numbers); } $noinline$assertEquals(1, val); } + private static void $noinline$emptyMethod() {} + + private static void $inline$testInlineInsideNestedCatches_inner() { + try { + $noinline$emptyMethod(); + } catch (Exception ex) { + int[] numbers = {}; + $noinline$assertEquals(1, $inline$OOBTryCatch(numbers)); + } + } + + private static void $noinline$testInlineInsideNestedCatches() { + try { + $noinline$emptyMethod(); + } catch (Exception ex) { + $inline$testInlineInsideNestedCatches_inner(); + } + } + // Tests that outer tries or catches don't affect as long as we are not inlining the inner // try/catch inside of them. private static void $noinline$testBeforeAfterTryCatch() { |