< prev index next >

test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java

Print this page

 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 {}
< prev index next >