summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/inliner.cc16
-rw-r--r--compiler/optimizing/nodes.cc5
-rw-r--r--test/2241-checker-inline-try-catch/src/Main.java37
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() {