xref: /aosp_15_r20/art/test/823-cha-inlining/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker interface Itf {
18*795d594fSAndroid Build Coastguard Worker   // We make the methods below directly throw instead of using the $noinline$
19*795d594fSAndroid Build Coastguard Worker   // directive to get the inliner actually try to inline but decide not to.
20*795d594fSAndroid Build Coastguard Worker   // This will then make the compiler try to generate an HInvokeVirtual instead
21*795d594fSAndroid Build Coastguard Worker   // of an HInvokeInterface.
22*795d594fSAndroid Build Coastguard Worker 
m()23*795d594fSAndroid Build Coastguard Worker   public default void m() throws Exception {
24*795d594fSAndroid Build Coastguard Worker     throw new Exception("Don't inline me");
25*795d594fSAndroid Build Coastguard Worker   }
mConflict()26*795d594fSAndroid Build Coastguard Worker   public default void mConflict() throws Exception {
27*795d594fSAndroid Build Coastguard Worker     throw new Exception("Don't inline me");
28*795d594fSAndroid Build Coastguard Worker   }
29*795d594fSAndroid Build Coastguard Worker }
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker // This is redefined in src2 with a mConflict method.
32*795d594fSAndroid Build Coastguard Worker interface Itf2 {
33*795d594fSAndroid Build Coastguard Worker }
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker interface Itf3 extends Itf, Itf2 {
36*795d594fSAndroid Build Coastguard Worker }
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker class Itf3Impl implements Itf3 {
39*795d594fSAndroid Build Coastguard Worker }
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker interface Itf4 extends Itf, Itf2 {
m()42*795d594fSAndroid Build Coastguard Worker   public default void m() throws Exception {
43*795d594fSAndroid Build Coastguard Worker     throw new Exception("Don't inline me");
44*795d594fSAndroid Build Coastguard Worker   }
45*795d594fSAndroid Build Coastguard Worker }
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker class Itf4Impl implements Itf4 {
48*795d594fSAndroid Build Coastguard Worker }
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker public class Main implements Itf, Itf2 {
52*795d594fSAndroid Build Coastguard Worker 
main(String[] args)53*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
54*795d594fSAndroid Build Coastguard Worker     System.loadLibrary(args[0]);
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker     // Execute enough time to populate inline caches.
57*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100000; ++i) {
58*795d594fSAndroid Build Coastguard Worker       try {
59*795d594fSAndroid Build Coastguard Worker         $noinline$doCallDefault();
60*795d594fSAndroid Build Coastguard Worker       } catch (Exception e) {
61*795d594fSAndroid Build Coastguard Worker         // Expected.
62*795d594fSAndroid Build Coastguard Worker       }
63*795d594fSAndroid Build Coastguard Worker     }
64*795d594fSAndroid Build Coastguard Worker     ensureJitCompiled(Main.class, "$noinline$doCallDefault");
65*795d594fSAndroid Build Coastguard Worker     try {
66*795d594fSAndroid Build Coastguard Worker       $noinline$doCallDefault();
67*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected exception");
68*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
69*795d594fSAndroid Build Coastguard Worker       // Expected.
70*795d594fSAndroid Build Coastguard Worker     }
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker     ensureJitCompiled(Main.class, "$noinline$doCallDefaultConflict");
73*795d594fSAndroid Build Coastguard Worker     try {
74*795d594fSAndroid Build Coastguard Worker       $noinline$doCallDefaultConflict();
75*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected IncompatibleClassChangeError");
76*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
77*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected exception");
78*795d594fSAndroid Build Coastguard Worker     } catch (IncompatibleClassChangeError e) {
79*795d594fSAndroid Build Coastguard Worker       // Expected.
80*795d594fSAndroid Build Coastguard Worker     }
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker     // Execute enough time to populate inline caches.
83*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100000; ++i) {
84*795d594fSAndroid Build Coastguard Worker       try {
85*795d594fSAndroid Build Coastguard Worker         $noinline$doCallDefaultConflictItf3();
86*795d594fSAndroid Build Coastguard Worker       } catch (Throwable t) {
87*795d594fSAndroid Build Coastguard Worker         // Expected.
88*795d594fSAndroid Build Coastguard Worker       }
89*795d594fSAndroid Build Coastguard Worker     }
90*795d594fSAndroid Build Coastguard Worker     ensureJitCompiled(Main.class, "$noinline$doCallDefaultConflictItf3");
91*795d594fSAndroid Build Coastguard Worker     try {
92*795d594fSAndroid Build Coastguard Worker       $noinline$doCallDefaultConflictItf3();
93*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected IncompatibleClassChangeError");
94*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
95*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected exception " + e);
96*795d594fSAndroid Build Coastguard Worker     } catch (IncompatibleClassChangeError e) {
97*795d594fSAndroid Build Coastguard Worker       // Expected.
98*795d594fSAndroid Build Coastguard Worker     }
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker     ensureJitCompiled(Main.class, "$noinline$doCallDefaultConflictItf4");
101*795d594fSAndroid Build Coastguard Worker     try {
102*795d594fSAndroid Build Coastguard Worker       $noinline$doCallDefaultConflictItf4();
103*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected IncompatibleClassChangeError");
104*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
105*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected exception");
106*795d594fSAndroid Build Coastguard Worker     } catch (IncompatibleClassChangeError e) {
107*795d594fSAndroid Build Coastguard Worker       // Expected.
108*795d594fSAndroid Build Coastguard Worker     }
109*795d594fSAndroid Build Coastguard Worker   }
110*795d594fSAndroid Build Coastguard Worker 
$noinline$doCallDefault()111*795d594fSAndroid Build Coastguard Worker   public static void $noinline$doCallDefault() throws Exception {
112*795d594fSAndroid Build Coastguard Worker     itf.m();
113*795d594fSAndroid Build Coastguard Worker   }
114*795d594fSAndroid Build Coastguard Worker 
$noinline$doCallDefaultConflict()115*795d594fSAndroid Build Coastguard Worker   public static void $noinline$doCallDefaultConflict() throws Exception {
116*795d594fSAndroid Build Coastguard Worker     itf.mConflict();
117*795d594fSAndroid Build Coastguard Worker   }
118*795d594fSAndroid Build Coastguard Worker 
$noinline$doCallDefaultConflictItf3()119*795d594fSAndroid Build Coastguard Worker   public static void $noinline$doCallDefaultConflictItf3() throws Exception {
120*795d594fSAndroid Build Coastguard Worker     itf3.mConflict();
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker 
$noinline$doCallDefaultConflictItf4()123*795d594fSAndroid Build Coastguard Worker   public static void $noinline$doCallDefaultConflictItf4() throws Exception {
124*795d594fSAndroid Build Coastguard Worker     itf4.mConflict();
125*795d594fSAndroid Build Coastguard Worker   }
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker   static Itf itf = new Main();
128*795d594fSAndroid Build Coastguard Worker   static Itf3 itf3 = new Itf3Impl();
129*795d594fSAndroid Build Coastguard Worker   static Itf4 itf4 = new Itf4Impl();
130*795d594fSAndroid Build Coastguard Worker 
ensureJitCompiled(Class<?> cls, String methodName)131*795d594fSAndroid Build Coastguard Worker   private static native void ensureJitCompiled(Class<?> cls, String methodName);
132*795d594fSAndroid Build Coastguard Worker }
133