xref: /aosp_15_r20/art/test/2251-checker-irreducible-loop-do-not-inline/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.lang.reflect.Method;
18 
19 public class Main {
main(String[] args)20     public static void main(String[] args) throws Exception {
21         Object[] arguments = {new Object()};
22         Object result = Class.forName("IrreducibleLoop")
23                                 .getMethod("testDoNotInlineInner", Object.class)
24                                 .invoke(null, arguments);
25         if (result == null) {
26             throw new Exception("Expected non-null result");
27         }
28     }
29 
30     // Simple method to have a call inside of the synchronized block.
$noinline$call()31     private static Object $noinline$call() {
32         return new Object();
33     }
34 
35     // `inner` has a Return -> TryBoundary -> Exit chain, which means that when we inline it we
36     // would need to recompute the loop information.
37 
38     // Consistency check: Three try boundary kind:exit. One for the explicit try catch, and two for
39     // the synchronized block (normal, and exceptional path).
40 
41     /// CHECK-START: java.lang.Object Main.inner(java.lang.Object) builder (after)
42     /// CHECK:     TryBoundary kind:exit
43     /// CHECK:     TryBoundary kind:exit
44     /// CHECK:     TryBoundary kind:exit
45     /// CHECK-NOT: TryBoundary kind:exit
46 
47     /// CHECK-START: java.lang.Object Main.inner(java.lang.Object) builder (after)
48     /// CHECK: Return loop:B2
49 
50     /// CHECK-START: java.lang.Object Main.inner(java.lang.Object) builder (after)
51     /// CHECK: TryBoundary kind:exit loop:B2
52     /// CHECK: TryBoundary kind:exit loop:B2
53     /// CHECK: TryBoundary kind:exit loop:B2
inner(Object o)54     public static Object inner(Object o) {
55         for (int i = 0; i < 4; i++) {
56             try {
57                 synchronized (o) {
58                     return $noinline$call();
59                 }
60             } catch (Error e) {
61                 continue;
62             }
63         }
64         return null;
65     }
66 }
67