1 /*
2  * Copyright (C) 2024 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.Constructor;
18 import java.lang.reflect.Method;
19 
20 public class Main {
21     public static String TEST_NAME = "732-checker-app-image";
22 
getSecondaryClassLoader()23     public static ClassLoader getSecondaryClassLoader() throws Exception {
24         String location = System.getenv("DEX_LOCATION");
25         try {
26             Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader");
27             Constructor<?> ctor =
28                     class_loader_class.getConstructor(String.class, ClassLoader.class);
29             return (ClassLoader) ctor.newInstance(location + "/" + TEST_NAME + "-ex.jar",
30                                                   Main.class.getClassLoader());
31         } catch (ClassNotFoundException e) {
32             // Running on RI. Use URLClassLoader.
33             return new java.net.URLClassLoader(
34                     new java.net.URL[] { new java.net.URL("file://" + location + "/classes-ex/") });
35         }
36     }
37 
main(String args[])38     public static void main(String args[]) throws Exception {
39         System.out.println($noinline$getAppImageClass().getName());
40         System.out.println($noinline$getNonAppImageClass().getName());
41 
42         $noinline$callAppImageClassNop();
43         $noinline$callAppImageClassWithClinitNop();
44         $noinline$callNonAppImageClassNop();
45 
46         ClassLoader secondaryLoader = getSecondaryClassLoader();
47         Class<?> secondaryClass = Class.forName("Secondary", true, secondaryLoader);
48         Method secondaryMain = secondaryClass.getMethod("main");
49         secondaryMain.invoke(null);
50     }
51 
52     /// CHECK-START: java.lang.Class Main.$noinline$getAppImageClass() builder (after)
53     /// CHECK:            LoadClass load_kind:AppImageRelRo in_image:true
$noinline$getAppImageClass()54     public static Class<?> $noinline$getAppImageClass() {
55         return AppImageClass.class;
56     }
57 
58     /// CHECK-START: java.lang.Class Main.$noinline$getNonAppImageClass() builder (after)
59     /// CHECK:            LoadClass load_kind:BssEntry in_image:false
$noinline$getNonAppImageClass()60     public static Class<?> $noinline$getNonAppImageClass() {
61         return NonAppImageClass.class;
62     }
63 
64     /// CHECK-START: void Main.$noinline$callAppImageClassNop() builder (after)
65     /// CHECK:            InvokeStaticOrDirect clinit_check:none
66 
67     /// CHECK-START: void Main.$noinline$callAppImageClassNop() builder (after)
68     /// CHECK-NOT:        LoadClass
69     /// CHECK-NOT:        ClinitCheck
70 
71     /// CHECK-START: void Main.$noinline$callAppImageClassNop() inliner (after)
72     /// CHECK-NOT:        LoadClass
73     /// CHECK-NOT:        ClinitCheck
74     /// CHECK-NOT:        InvokeStaticOrDirect
$noinline$callAppImageClassNop()75     public static void $noinline$callAppImageClassNop() {
76         AppImageClass.$inline$nop();
77     }
78 
79     /// CHECK-START: void Main.$noinline$callAppImageClassWithClinitNop() builder (after)
80     /// CHECK:            LoadClass load_kind:AppImageRelRo in_image:true gen_clinit_check:false
81     /// CHECK:            ClinitCheck
82     /// CHECK:            InvokeStaticOrDirect clinit_check:explicit
83 
84     /// CHECK-START: void Main.$noinline$callAppImageClassWithClinitNop() inliner (after)
85     /// CHECK:            LoadClass load_kind:AppImageRelRo in_image:true gen_clinit_check:false
86     /// CHECK:            ClinitCheck
87 
88     /// CHECK-START: void Main.$noinline$callAppImageClassWithClinitNop() inliner (after)
89     /// CHECK-NOT:        InvokeStaticOrDirect
90 
91     /// CHECK-START: void Main.$noinline$callAppImageClassWithClinitNop() prepare_for_register_allocation (after)
92     /// CHECK:            LoadClass load_kind:AppImageRelRo in_image:true gen_clinit_check:false
93     /// CHECK:            ClinitCheck
$noinline$callAppImageClassWithClinitNop()94     public static void $noinline$callAppImageClassWithClinitNop() {
95         AppImageClassWithClinit.$inline$nop();
96     }
97 
98     /// CHECK-START: void Main.$noinline$callNonAppImageClassNop() builder (after)
99     /// CHECK:            LoadClass load_kind:BssEntry in_image:false gen_clinit_check:false
100     /// CHECK:            ClinitCheck
101     /// CHECK:            InvokeStaticOrDirect clinit_check:explicit
102 
103     /// CHECK-START: void Main.$noinline$callNonAppImageClassNop() inliner (after)
104     /// CHECK:            LoadClass load_kind:BssEntry in_image:false gen_clinit_check:false
105     /// CHECK:            ClinitCheck
106 
107     /// CHECK-START: void Main.$noinline$callNonAppImageClassNop() inliner (after)
108     /// CHECK-NOT:        InvokeStaticOrDirect
109 
110     /// CHECK-START: void Main.$noinline$callNonAppImageClassNop() prepare_for_register_allocation (after)
111     /// CHECK:            LoadClass load_kind:BssEntry in_image:false gen_clinit_check:true
112 
113     /// CHECK-START: void Main.$noinline$callNonAppImageClassNop() prepare_for_register_allocation (after)
114     /// CHECK-NOT:        ClinitCheck
$noinline$callNonAppImageClassNop()115     public static void $noinline$callNonAppImageClassNop() {
116         NonAppImageClass.$inline$nop();
117     }
118 }
119 
120 class AppImageClass {  // Included in the profile.
$inline$nop()121     public static void $inline$nop() {}
122 }
123 
124 class AppImageClassWithClinit {  // Included in the profile.
125     static boolean doThrow = false;
126     static {
127         if (doThrow) {
Error()128             throw new Error();
129         }
130     }
131 
$inline$nop()132     public static void $inline$nop() {}
133 }
134 
135 class NonAppImageClass {  // Not included in the profile.
$inline$nop()136     public static void $inline$nop() {}
137 }
138