16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 /*
26 * @test
27 * @summary Test how various AOT optimizations handle classes that are excluded from the AOT cache.
28 * @requires vm.cds.write.archived.java.heap
29 * @library /test/jdk/lib/testlibrary /test/lib
30 * /test/hotspot/jtreg/runtime/cds/appcds/aotCache/test-classes
31 * @build ExcludedClasses CustyWithLoop
32 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
33 * TestApp
34 * TestApp$Foo
35 * TestApp$Foo$A
36 * TestApp$Foo$Bar
37 * TestApp$Foo$ShouldBeExcluded
38 * TestApp$Foo$ShouldBeExcludedChild
39 * TestApp$Foo$Taz
40 * TestApp$MyInvocationHandler
41 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar cust.jar
42 * CustyWithLoop
43 * @run driver ExcludedClasses
44 */
45
46 import java.io.File;
47 import java.lang.invoke.MethodHandle;
48 import java.lang.invoke.MethodHandles;
49 import java.lang.reflect.Array;
50 import java.lang.reflect.InvocationHandler;
51 import java.lang.reflect.Method;
52 import java.lang.reflect.Proxy;
53 import java.net.URL;
54 import java.net.URLClassLoader;
55 import java.security.ProtectionDomain;
56 import java.util.Map;
57
58 import jdk.jfr.Event;
59 import jdk.test.lib.cds.CDSAppTester;
60 import jdk.test.lib.helpers.ClassFileInstaller;
61 import jdk.test.lib.process.OutputAnalyzer;
62
63 public class ExcludedClasses {
64 static final String appJar = ClassFileInstaller.getJarPath("app.jar");
65 static final String mainClass = "TestApp";
66
67 public static void main(String[] args) throws Exception {
68 Tester tester = new Tester();
69 tester.runAOTWorkflow("AOT", "--two-step-training");
84 return new String[] {
85 "-Xlog:aot=debug",
86 "-Xlog:aot+class=debug",
87 "-Xlog:aot+resolve=trace",
88 "-Xlog:aot+verification=trace",
89 "-Xlog:class+load",
90 };
91 }
92
93 @Override
94 public String[] appCommandLine(RunMode runMode) {
95 return new String[] {
96 mainClass, runMode.name()
97 };
98 }
99
100 @Override
101 public void checkExecution(OutputAnalyzer out, RunMode runMode) {
102 if (runMode == RunMode.ASSEMBLY) {
103 out.shouldNotMatch("aot,resolve.*archived field.*TestApp.Foo => TestApp.Foo.ShouldBeExcluded.f:I");
104 } else if (runMode == RunMode.PRODUCTION) {
105 out.shouldContain("jdk.jfr.Event source: jrt:/jdk.jfr");
106 out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcluded source: .*/app.jar");
107 out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcludedChild source: .*/app.jar");
108 }
109 }
110 }
111 }
112
113 class TestApp {
114 static volatile Object custInstance;
115 static volatile Object custArrayInstance;
116
117 public static void main(String args[]) throws Exception {
118 // In AOT workflow, classes from custom loaders are passed from the preimage
119 // to the final image. See FinalImageRecipes::record_all_classes().
120 custInstance = initFromCustomLoader();
121 custArrayInstance = Array.newInstance(custInstance.getClass(), 0);
122 System.out.println(custArrayInstance);
123 System.out.println("Counter = " + Foo.hotSpot());
156 volatile static int counter;
157 static Class c = ShouldBeExcluded.class;
158
159 static Map mapProxy = (Map) Proxy.newProxyInstance(
160 Foo.class.getClassLoader(),
161 new Class[] { Map.class },
162 new MyInvocationHandler());
163
164 static int hotSpot() {
165 ShouldBeExcluded s = new ShouldBeExcluded();
166 Bar b = new Bar();
167
168 long start = System.currentTimeMillis();
169 while (System.currentTimeMillis() - start < 1000) {
170 lambdaHotSpot();
171 lambdaHotSpot2();
172 invokeHandleHotSpot();
173 s.hotSpot2();
174 b.hotSpot3();
175 Taz.hotSpot4();
176
177 // In JDK mainline, generated proxy classes are excluded from the AOT cache.
178 // In Leyden/premain, generated proxy classes included. The following code should
179 // work with either repos.
180 Integer i = (Integer)mapProxy.get(null);
181 counter += i.intValue();
182
183 if (custInstance != null) {
184 // Classes loaded by custom loaders are included in the AOT cache
185 // but their array classes are excluded.
186 counter += custInstance.equals(null) ? 1 : 2;
187 }
188
189 if (custArrayInstance != null) {
190 if ((counter % 3) == 0) {
191 counter += (custArrayInstance instanceof String) ? 0 : 1;
192 } else {
193 counter += (custArrayInstance instanceof Object) ? 0 : 1;
194 }
195 }
301 }
302 }
303
304 static class Taz {
305 static ShouldBeExcluded m() {
306 // Taz should be excluded from the AOT cache because it has a verification constraint that
307 // "ShouldBeExcludedChild must be a subtype of ShouldBeExcluded", but ShouldBeExcluded is
308 // excluded from the AOT cache.
309 return new ShouldBeExcludedChild();
310 }
311 static void hotSpot4() {
312 long start = System.currentTimeMillis();
313 while (System.currentTimeMillis() - start < 20) {
314 for (int i = 0; i < 50000; i++) {
315 counter += i;
316 }
317 f();
318 }
319 }
320 }
321 }
322 }
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 /*
26 * @test
27 * @summary Test how various AOT optimizations handle classes that are excluded from the AOT cache.
28 * @requires vm.cds.write.archived.java.heap
29 * @library /test/jdk/lib/testlibrary /test/lib
30 * /test/hotspot/jtreg/runtime/cds/appcds/aotCache/test-classes
31 * @build ExcludedClasses CustyWithLoop
32 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
33 * TestApp
34 * TestApp$Foo
35 * TestApp$Foo$A
36 * TestApp$Foo$BadFieldSig
37 * TestApp$Foo$BadMethodSig
38 * TestApp$Foo$Bar
39 * TestApp$Foo$GoodSig1
40 * TestApp$Foo$GoodSig2
41 * TestApp$Foo$ShouldBeExcluded
42 * TestApp$Foo$ShouldBeExcludedChild
43 * TestApp$Foo$Taz
44 * TestApp$MyInvocationHandler
45 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar cust.jar
46 * CustyWithLoop
47 * @run driver ExcludedClasses
48 */
49
50 import java.io.File;
51 import java.lang.invoke.MethodHandle;
52 import java.lang.invoke.MethodHandles;
53 import java.lang.reflect.Array;
54 import java.lang.reflect.Field;
55 import java.lang.reflect.InvocationHandler;
56 import java.lang.reflect.Method;
57 import java.lang.reflect.Proxy;
58 import java.net.URL;
59 import java.net.URLClassLoader;
60 import java.security.ProtectionDomain;
61 import java.util.Map;
62
63 import jdk.jfr.Event;
64 import jdk.test.lib.cds.CDSAppTester;
65 import jdk.test.lib.helpers.ClassFileInstaller;
66 import jdk.test.lib.process.OutputAnalyzer;
67
68 public class ExcludedClasses {
69 static final String appJar = ClassFileInstaller.getJarPath("app.jar");
70 static final String mainClass = "TestApp";
71
72 public static void main(String[] args) throws Exception {
73 Tester tester = new Tester();
74 tester.runAOTWorkflow("AOT", "--two-step-training");
89 return new String[] {
90 "-Xlog:aot=debug",
91 "-Xlog:aot+class=debug",
92 "-Xlog:aot+resolve=trace",
93 "-Xlog:aot+verification=trace",
94 "-Xlog:class+load",
95 };
96 }
97
98 @Override
99 public String[] appCommandLine(RunMode runMode) {
100 return new String[] {
101 mainClass, runMode.name()
102 };
103 }
104
105 @Override
106 public void checkExecution(OutputAnalyzer out, RunMode runMode) {
107 if (runMode == RunMode.ASSEMBLY) {
108 out.shouldNotMatch("aot,resolve.*archived field.*TestApp.Foo => TestApp.Foo.ShouldBeExcluded.f:I");
109 out.shouldContain("Archived reflection data in TestApp$Foo$GoodSig1");
110 out.shouldContain("Archived reflection data in TestApp$Foo$GoodSig2");
111 out.shouldContain("Cannot archive reflection data in TestApp$Foo$BadMethodSig");
112 out.shouldContain("Cannot archive reflection data in TestApp$Foo$BadFieldSig");
113 } else if (runMode == RunMode.PRODUCTION) {
114 out.shouldContain("jdk.jfr.Event source: jrt:/jdk.jfr");
115 out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcluded source: .*/app.jar");
116 out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcludedChild source: .*/app.jar");
117 }
118 }
119 }
120 }
121
122 class TestApp {
123 static volatile Object custInstance;
124 static volatile Object custArrayInstance;
125
126 public static void main(String args[]) throws Exception {
127 // In AOT workflow, classes from custom loaders are passed from the preimage
128 // to the final image. See FinalImageRecipes::record_all_classes().
129 custInstance = initFromCustomLoader();
130 custArrayInstance = Array.newInstance(custInstance.getClass(), 0);
131 System.out.println(custArrayInstance);
132 System.out.println("Counter = " + Foo.hotSpot());
165 volatile static int counter;
166 static Class c = ShouldBeExcluded.class;
167
168 static Map mapProxy = (Map) Proxy.newProxyInstance(
169 Foo.class.getClassLoader(),
170 new Class[] { Map.class },
171 new MyInvocationHandler());
172
173 static int hotSpot() {
174 ShouldBeExcluded s = new ShouldBeExcluded();
175 Bar b = new Bar();
176
177 long start = System.currentTimeMillis();
178 while (System.currentTimeMillis() - start < 1000) {
179 lambdaHotSpot();
180 lambdaHotSpot2();
181 invokeHandleHotSpot();
182 s.hotSpot2();
183 b.hotSpot3();
184 Taz.hotSpot4();
185 reflectHotSpots();
186
187 // In JDK mainline, generated proxy classes are excluded from the AOT cache.
188 // In Leyden/premain, generated proxy classes included. The following code should
189 // work with either repos.
190 Integer i = (Integer)mapProxy.get(null);
191 counter += i.intValue();
192
193 if (custInstance != null) {
194 // Classes loaded by custom loaders are included in the AOT cache
195 // but their array classes are excluded.
196 counter += custInstance.equals(null) ? 1 : 2;
197 }
198
199 if (custArrayInstance != null) {
200 if ((counter % 3) == 0) {
201 counter += (custArrayInstance instanceof String) ? 0 : 1;
202 } else {
203 counter += (custArrayInstance instanceof Object) ? 0 : 1;
204 }
205 }
311 }
312 }
313
314 static class Taz {
315 static ShouldBeExcluded m() {
316 // Taz should be excluded from the AOT cache because it has a verification constraint that
317 // "ShouldBeExcludedChild must be a subtype of ShouldBeExcluded", but ShouldBeExcluded is
318 // excluded from the AOT cache.
319 return new ShouldBeExcludedChild();
320 }
321 static void hotSpot4() {
322 long start = System.currentTimeMillis();
323 while (System.currentTimeMillis() - start < 20) {
324 for (int i = 0; i < 50000; i++) {
325 counter += i;
326 }
327 f();
328 }
329 }
330 }
331
332 static volatile Object dummyObj;
333
334 static void reflectHotSpots() {
335 try {
336 // f.clazz points to an excluded class, so we should not archive any fields in
337 // the BadFieldSig
338 Field f = BadFieldSig.class.getDeclaredField("myField");
339 Method m = BadMethodSig.class.getDeclaredMethod("myMethod", Object.class, ShouldBeExcluded.class);
340
341 // It's OK to archive the reflection data of this class even if its method signatures
342 // refers to a class that's not loaded at all during the assembly phase.
343 // Note: because the app did not reflect on the methods of GoodSig1, we don't
344 // AOT-generate method reflection data for GoodSig.
345 Field f2 = GoodSig1.class.getDeclaredField("myField");
346
347 // Opposite case as GoodSig1. We should archive its reflection data
348 Method m2 = GoodSig2.class.getDeclaredMethod("myMethod", Object.class, Object.class);
349
350 long start = System.currentTimeMillis();
351 while (System.currentTimeMillis() - start < 50) {
352 for (int i = 0; i < 50000; i++) {
353 dummyObj = f.get(null);
354 dummyObj = m.invoke(null, null, null);
355 dummyObj = f2.get(null);
356 dummyObj = m2.invoke(null, null, null);
357 }
358 }
359 } catch (Throwable t) {
360 throw new RuntimeException("Unexpected exception", t);
361 }
362 }
363
364 static class BadFieldSig {
365 static ShouldBeExcluded myField = new ShouldBeExcluded();
366 }
367
368 static class BadMethodSig {
369 static String myMethod(Object o, ShouldBeExcluded s) {
370 return "Foofoo";
371 }
372 }
373
374 static class GoodSig1 {
375 static Object myField = new Object();
376 static void method(UnavailableClass1 arg) {}
377 static void method(UnavailableClass2[] arg) {}
378 }
379
380 static class GoodSig2 {
381 static String myMethod(Object o, Object o2) {
382 return "Foofoo";
383 }
384
385 UnavailableClass2[] unusedField;
386
387 // This field has never been reflected up or resolved during the training run, so the
388 // array type GoodSig2[][][][] is not resolved during either the training run or the
389 // assembly phase.
390 GoodSig2[][][][] unusedField2;
391 }
392 }
393 }
394
395 // These classes are NOT part of app.jar, so they cannot be resolved by the app.
396 class UnavailableClass1 {}
397 class UnavailableClass2 {}
|