Skip to content

Commit bbac8f2

Browse files
committedMar 7, 2025
8351100: [leyden] -XX:AOTEndTrainingOnMethodEntry crashes with large count
1 parent 46c825a commit bbac8f2

File tree

3 files changed

+124
-16
lines changed

3 files changed

+124
-16
lines changed
 

‎src/hotspot/share/cds/metaspaceShared.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -884,8 +884,10 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
884884

885885
if (CDSConfig::new_aot_flags_used()) {
886886
if (CDSConfig::is_dumping_preimage_static_archive()) {
887+
// We are in the JVM that runs the training run. Continue execution,
888+
// so that it can finish all clean-up and return the correct exit
889+
// code to the OS.
887890
tty->print_cr("AOTConfiguration recorded: %s", AOTConfiguration);
888-
vm_exit(0);
889891
} else {
890892
// The JLI launcher only recognizes the "old" -Xshare:dump flag.
891893
// When the new -XX:AOTMode=create flag is used, we can't return
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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
27+
* @summary -XX:AOTMode=record should not interfere with app execution: (1) thread creation; (2) exit code
28+
* @requires vm.cds.supports.aot.class.linking
29+
* @comment work around JDK-8345635
30+
* @requires !vm.jvmci.enabled
31+
* @library /test/jdk/lib/testlibrary /test/lib
32+
* @build TrainingRun
33+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp
34+
* @run driver TrainingRun AOT
35+
*/
36+
37+
import jdk.test.lib.cds.CDSAppTester;
38+
import jdk.test.lib.helpers.ClassFileInstaller;
39+
import jdk.test.lib.process.OutputAnalyzer;
40+
41+
public class TrainingRun {
42+
static final String appJar = ClassFileInstaller.getJarPath("app.jar");
43+
static final String mainClass = "MyTestApp";
44+
45+
public static void main(String[] args) throws Exception {
46+
(new Tester()).run(args);
47+
}
48+
49+
static class Tester extends CDSAppTester {
50+
public Tester() {
51+
super(mainClass);
52+
53+
// CDSAppTester usually wants the app to return exit value 0, but this test
54+
// checks whether the training run can return 2.
55+
setCheckExitValue(false);
56+
}
57+
58+
@Override
59+
public String classpath(RunMode runMode) {
60+
return appJar;
61+
}
62+
63+
@Override
64+
public String[] appCommandLine(RunMode runMode) {
65+
return new String[] {
66+
mainClass,
67+
};
68+
}
69+
70+
@Override
71+
public void checkExecution(OutputAnalyzer out, RunMode runMode) {
72+
if (runMode.isApplicationExecuted()) {
73+
out.shouldHaveExitValue(2);
74+
out.shouldContain("Hello: x is 1");
75+
}
76+
}
77+
}
78+
}
79+
80+
class MyTestApp {
81+
volatile static int x = 0;
82+
83+
public static void main(String args[]) throws Exception {
84+
Thread t = new Thread(() -> {
85+
x = 1;
86+
});
87+
t.start();
88+
t.join();
89+
90+
if (x != 1) {
91+
throw new RuntimeException("x should be 1 but is " + x);
92+
}
93+
System.out.println("Hello: x is " + x);
94+
System.out.println("I am calling System.exit(2)");
95+
System.exit(2);
96+
}
97+
}

‎test/hotspot/jtreg/runtime/cds/appcds/leyden/EndTrainingOnMethodEntry.java

+24-15
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
/*
2626
* @test id=aot
27-
* @requires vm.cds.write.archived.java.heap
27+
* @requires vm.cds.supports.aot.class.linking
28+
* @comment work around JDK-8345635
29+
* @requires !vm.jvmci.enabled
2830
* @library /test/jdk/lib/testlibrary /test/lib
2931
* @build EndTrainingOnMethodEntry
3032
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp ShouldBeCached ShouldNotBeCached
@@ -33,7 +35,9 @@
3335

3436
/*
3537
* @test id=leyden
36-
* @requires vm.cds.write.archived.java.heap
38+
* @requires vm.cds.supports.aot.class.linking
39+
* @comment work around JDK-8345635
40+
* @requires !vm.jvmci.enabled
3741
* @library /test/jdk/lib/testlibrary /test/lib
3842
* @build EndTrainingOnMethodEntry
3943
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp ShouldBeCached ShouldNotBeCached
@@ -49,16 +53,18 @@ public class EndTrainingOnMethodEntry {
4953
static final String mainClass = "MyTestApp";
5054

5155
public static void main(String[] args) throws Exception {
52-
(new Tester(false)).run(args);
53-
(new Tester(true)).run(args);
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.
5460
}
5561

5662
static class Tester extends CDSAppTester {
57-
boolean useCount;
63+
int count;
5864

59-
public Tester(boolean useCount) {
65+
public Tester(int count) {
6066
super(mainClass);
61-
this.useCount = useCount;
67+
this.count = count;
6268
}
6369

6470
@Override
@@ -67,7 +73,7 @@ public String classpath(RunMode runMode) {
6773
}
6874

6975
public String[] vmArgs(RunMode runMode) {
70-
String stop = useCount ? ("stopTrainingOnMeWithCount,count=" + MyTestApp.COUNT) : "stopTrainingOnMe";
76+
String stop = count > 1 ? ("stopTrainingOnMeWithCount,count=" + count) : "stopTrainingOnMe";
7177
return new String[] {
7278
"-Xlog:cds+class=debug",
7379
"-XX:AOTEndTrainingOnMethodEntry=MyTestApp." + stop,
@@ -77,14 +83,16 @@ public String[] vmArgs(RunMode runMode) {
7783
@Override
7884
public String[] appCommandLine(RunMode runMode) {
7985
return new String[] {
80-
mainClass, runMode.name(), Boolean.toString(useCount),
86+
mainClass, runMode.name(), Integer.toString(count),
8187
};
8288
}
8389

8490
@Override
8591
public void checkExecution(OutputAnalyzer out, RunMode runMode) {
8692
if (runMode.isApplicationExecuted()) {
8793
out.shouldContain("Hello Leyden " + runMode.name());
94+
out.shouldContain("ShouldBeCached.dummy()");
95+
out.shouldContain("ShouldNotBeCached.dummy()");
8896
}
8997
if (isDumping(runMode)) {
9098
out.shouldMatch("cds,class.* ShouldBeCached");
@@ -95,11 +103,13 @@ public void checkExecution(OutputAnalyzer out, RunMode runMode) {
95103
}
96104

97105
class MyTestApp {
98-
public static final int COUNT = 10; // FIXME (JDK-8351100): debug build crashes with COUNT = 10000;
99-
public static void main(String args[]) {
100-
System.out.println("Hello Leyden " + args[0] + ", useCount = " + args[1]);
101-
if (args[1].equals("true")) {
102-
for (int i = 0; i < COUNT + 10; i++) {
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++) {
103113
stopTrainingOnMeWithCount(i);
104114
}
105115
} else {
@@ -117,7 +127,6 @@ static void stopTrainingOnMe() {
117127

118128
static void stopTrainingOnMeWithCount(int i) {
119129
if (i >= COUNT - 2) {
120-
System.out.println("COUNT = " + COUNT + ", i = " + i);
121130
ShouldBeCached.dummy();
122131
}
123132
if (i >= COUNT) {

0 commit comments

Comments
 (0)
Please sign in to comment.