1 /* 2 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 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 id=aot 27 * @requires vm.cds.supports.aot.class.linking 28 * @comment work around JDK-8345635 29 * @requires !vm.jvmci.enabled 30 * @library /test/jdk/lib/testlibrary /test/lib 31 * @build EndTrainingOnMethodEntry 32 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp ShouldBeCached ShouldNotBeCached 33 * @run driver EndTrainingOnMethodEntry AOT 34 */ 35 36 /* 37 * @test id=leyden 38 * @requires vm.cds.supports.aot.class.linking 39 * @comment work around JDK-8345635 40 * @requires !vm.jvmci.enabled 41 * @library /test/jdk/lib/testlibrary /test/lib 42 * @build EndTrainingOnMethodEntry 43 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp ShouldBeCached ShouldNotBeCached 44 * @run driver EndTrainingOnMethodEntry LEYDEN 45 */ 46 47 import jdk.test.lib.cds.CDSAppTester; 48 import jdk.test.lib.helpers.ClassFileInstaller; 49 import jdk.test.lib.process.OutputAnalyzer; 50 51 public class EndTrainingOnMethodEntry { 52 static final String appJar = ClassFileInstaller.getJarPath("app.jar"); 53 static final String mainClass = "MyTestApp"; 54 55 public static void main(String[] args) throws Exception { 56 // We want to test the entry count implementation in both interpreter and compiler. 57 (new Tester(1)).run(args); 58 (new Tester(10)).run(args); // the loop will probably be interpreted 59 (new Tester(10000)).run(args); // the loop will probably be compiled. 60 } 61 62 static class Tester extends CDSAppTester { 63 int count; 64 65 public Tester(int count) { 66 super(mainClass); 67 this.count = count; 68 } 69 70 @Override 71 public String classpath(RunMode runMode) { 72 return appJar; 73 } 74 75 public String[] vmArgs(RunMode runMode) { 76 String stop = count > 1 ? ("stopTrainingOnMeWithCount,count=" + count) : "stopTrainingOnMe"; 77 return new String[] { 78 "-Xlog:cds+class=debug", 79 "-XX:AOTEndTrainingOnMethodEntry=MyTestApp." + stop, 80 }; 81 } 82 83 @Override 84 public String[] appCommandLine(RunMode runMode) { 85 return new String[] { 86 mainClass, runMode.name(), Integer.toString(count), 87 }; 88 } 89 90 @Override 91 public void checkExecution(OutputAnalyzer out, RunMode runMode) { 92 if (runMode.isApplicationExecuted()) { 93 out.shouldContain("Hello Leyden " + runMode.name()); 94 out.shouldContain("ShouldBeCached.dummy()"); 95 out.shouldContain("ShouldNotBeCached.dummy()"); 96 } 97 if (isDumping(runMode)) { 98 out.shouldMatch("cds,class.* ShouldBeCached"); 99 out.shouldNotMatch("cds,class.* ShouldNotBeCached"); 100 } 101 } 102 } 103 } 104 105 class MyTestApp { 106 public static int COUNT; 107 public static void main(String args[]) throws Exception { 108 System.out.println("Hello Leyden " + args[0] + ", count = " + args[1]); 109 COUNT = Integer.parseInt(args[1]); 110 if (COUNT > 1) { 111 int max = COUNT + 10; 112 for (int i = 0; i < max; i++) { 113 stopTrainingOnMeWithCount(i); 114 } 115 } else { 116 ShouldBeCached.dummy(); 117 stopTrainingOnMe(); 118 } 119 } 120 121 static void stopTrainingOnMe() { 122 // The AOT configuration file should have been recorded before the body 123 // of this method is executed, so the ShouldNotBeCached class should not be 124 // recorded in the config. 125 ShouldNotBeCached.dummy(); 126 } 127 128 static void stopTrainingOnMeWithCount(int i) { 129 if (i >= COUNT - 2) { 130 ShouldBeCached.dummy(); 131 } 132 if (i >= COUNT) { 133 // The AOT configuration file should have been recorded before this block is entered, 134 // so the ShouldNotBeCached class should not be recorded in the config. 135 ShouldNotBeCached.dummy(); 136 } 137 } 138 } 139 140 class ShouldBeCached { 141 static void dummy() { 142 System.out.println("ShouldBeCached.dummy()"); 143 } 144 } 145 146 class ShouldNotBeCached { 147 static void dummy() { 148 System.out.println("ShouldNotBeCached.dummy()"); 149 } 150 }