g1-fix-test

This commit is contained in:
Albert Yang 2026-08-01 17:28:16 +08:00
parent 79b0a1c326
commit 5776d7da2e
3 changed files with 65 additions and 71 deletions

View File

@ -44,7 +44,6 @@ vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 829
vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all
gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64
gc/g1/TestCodeCacheUnloadDuringConcurrentMark.java 8388169 generic-all
#############################################################################

View File

@ -27,6 +27,7 @@ package gc;
* @test id=serial
* @summary Tests that one full GC unloads a freshly not-entrant nmethod.
* @requires vm.gc.Serial
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.MethodFlushing != false
@ -44,6 +45,7 @@ package gc;
* @test id=parallel
* @summary Tests that one full GC unloads a freshly not-entrant nmethod.
* @requires vm.gc.Parallel
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.MethodFlushing != false
@ -61,6 +63,7 @@ package gc;
* @test id=g1
* @summary Tests that one full GC unloads a freshly not-entrant nmethod.
* @requires vm.gc.G1
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.MethodFlushing != false
@ -78,6 +81,7 @@ package gc;
* @test id=shenandoah
* @summary Tests that one full GC unloads a freshly not-entrant nmethod.
* @requires vm.gc.Shenandoah
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.MethodFlushing != false
@ -95,6 +99,7 @@ package gc;
* @test id=z
* @summary Tests that one full GC unloads a freshly not-entrant nmethod.
* @requires vm.gc.Z
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.MethodFlushing != false
@ -110,9 +115,10 @@ package gc;
import java.lang.reflect.Method;
import jdk.test.lib.dcmd.JMXExecutor;
import jdk.test.lib.process.OutputAnalyzer;
import gc.testlibrary.CodeCacheUtils;
import jdk.test.whitebox.WhiteBox;
import jdk.test.whitebox.code.NMethod;
import jdk.test.whitebox.gc.GC;
public class TestCodeCacheUnload {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
@ -123,9 +129,7 @@ public class TestCodeCacheUnload {
}
}
private static void compileAndMakeNotEntrant() throws Exception {
Method method = Target.class.getDeclaredMethod("test", int.class);
private static int compileAndMakeNotEntrant(Method method) throws Exception {
method.invoke(null, 1);
if (!WB.enqueueMethodForCompilation(method, 1 /* compLevel */)) {
throw new AssertionError("Failed to enqueue target for compilation");
@ -133,45 +137,44 @@ public class TestCodeCacheUnload {
while (WB.isMethodQueuedForCompilation(method)) {
Thread.sleep(50);
}
if (!WB.isMethodCompiled(method)) {
throw new AssertionError("Target is not compiled");
NMethod nmethod = NMethod.get(method, false);
if (nmethod == null || nmethod.comp_level != 1) {
throw new AssertionError("Target is not compiled at level 1");
}
int deoptimized = WB.deoptimizeMethod(method);
if (deoptimized == 0) {
throw new AssertionError("No target nmethod was made not-entrant");
}
return nmethod.compile_id;
}
private static int countNotEntrantEntries() {
OutputAnalyzer output = new JMXExecutor().execute("Compiler.codelist");
String target = "gc.TestCodeCacheUnload$Target.test";
int result = 0;
for (String line : output.asLines()) {
if (!line.contains(target)) {
continue;
}
System.out.println("Found codelist entry: " + line);
String[] parts = line.trim().split("\\s+");
int codeState = Integer.parseInt(parts[2]);
if (codeState == 1 /* not_entrant */) {
result++;
}
}
return result;
}
public static void main(String[] args) throws Exception {
compileAndMakeNotEntrant();
private static void runTest() throws Exception {
Method method = Target.class.getDeclaredMethod("test", int.class);
int compileId = compileAndMakeNotEntrant(method);
WB.fullGC();
int notEntrantEntries = countNotEntrantEntries();
System.out.println("Target not-entrant entries after 1 full GC: " + notEntrantEntries);
if (notEntrantEntries != 0) {
if (CodeCacheUtils.codelistContains(compileId, method, 1, 1 /* not_entrant */)) {
throw new AssertionError("Expected one full GC to unload the not-entrant nmethod");
}
}
private static void runTestG1() throws Exception {
// Prevent a concurrent mark from owning the code-cache cycle in which
// the target nmethod is created; the full GC must start a later cycle.
WB.concurrentGCAcquireControl();
try {
runTest();
} finally {
WB.concurrentGCReleaseControl();
}
}
public static void main(String[] args) throws Exception {
if (GC.G1.isSelected()) {
runTestG1();
} else {
runTest();
}
}
}

View File

@ -27,11 +27,12 @@ package gc.g1;
* @test TestCodeCacheUnloadDuringConcurrentMark
* @summary Tests that G1 concurrent marking unloads a freshly not-entrant nmethod.
* @requires vm.gc.G1
* @requires vm.flagless
* @requires vm.compiler1.enabled
* @requires vm.opt.ClassUnloading != false
* @requires vm.opt.ClassUnloadingWithConcurrentMark != false
* @requires vm.opt.MethodFlushing != false
* @library /test/lib
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @build jdk.test.whitebox.WhiteBox
@ -45,8 +46,9 @@ package gc.g1;
import java.lang.reflect.Method;
import jdk.test.lib.dcmd.JMXExecutor;
import gc.testlibrary.CodeCacheUtils;
import jdk.test.whitebox.WhiteBox;
import jdk.test.whitebox.code.NMethod;
public class TestCodeCacheUnloadDuringConcurrentMark {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
@ -57,7 +59,7 @@ public class TestCodeCacheUnloadDuringConcurrentMark {
}
}
private static void compileAndMakeNotEntrant(Method method) throws Exception {
private static int compileAndMakeNotEntrant(Method method) throws Exception {
Target.test(1);
if (!WB.enqueueMethodForCompilation(method, 1 /* compLevel */)) {
throw new AssertionError("Failed to enqueue target for compilation");
@ -65,51 +67,41 @@ public class TestCodeCacheUnloadDuringConcurrentMark {
while (WB.isMethodQueuedForCompilation(method)) {
Thread.sleep(50);
}
if (!WB.isMethodCompiled(method)) {
throw new AssertionError("Target is not compiled");
NMethod nmethod = NMethod.get(method, false);
if (nmethod == null || nmethod.comp_level != 1) {
throw new AssertionError("Target is not compiled at level 1");
}
int deoptimized = WB.deoptimizeMethod(method);
if (deoptimized == 0) {
throw new AssertionError("No target nmethod was made not-entrant");
}
}
private static int countNotEntrantEntries() {
String target = TestCodeCacheUnloadDuringConcurrentMark.class.getName() + "$Target.test";
int result = 0;
for (String line : new JMXExecutor().execute("Compiler.codelist", true).asLines()) {
if (!line.contains(target)) {
continue;
}
System.out.println("Found codelist entry: " + line);
String[] parts = line.trim().split("\\s+");
int codeState = Integer.parseInt(parts[2]);
if (codeState == 1 /* not_entrant */) {
result++;
}
}
return result;
return nmethod.compile_id;
}
public static void main(String[] args) throws Exception {
compileAndMakeNotEntrant(Target.class.getDeclaredMethod("test", int.class));
// Keep an automatic cycle from reclaiming the target before the
// test-owned concurrent mark reaches it.
WB.concurrentGCAcquireControl();
try {
Method method = Target.class.getDeclaredMethod("test", int.class);
int compileId = compileAndMakeNotEntrant(method);
if (!CodeCacheUtils.codelistContains(compileId, method, 1, 1 /* not_entrant */)) {
throw new AssertionError("Expected a not-entrant target nmethod before concurrent mark");
}
int notEntrantEntries = countNotEntrantEntries();
System.out.println("Target not-entrant entries before concurrent mark: " + notEntrantEntries);
if (notEntrantEntries == 0) {
throw new AssertionError("Expected a not-entrant target nmethod before concurrent mark");
}
int completedCycles = WB.g1CompletedConcurrentMarkCycles();
WB.concurrentGCRunTo(WB.AFTER_MARKING_STARTED);
WB.concurrentGCRunToIdle();
if (completedCycles >= WB.g1CompletedConcurrentMarkCycles()) {
throw new AssertionError("Concurrent GC aborted");
}
WB.g1RunConcurrentGC();
notEntrantEntries = countNotEntrantEntries();
System.out.println("Target not-entrant entries after concurrent mark: " + notEntrantEntries);
if (notEntrantEntries != 0) {
throw new AssertionError("Expected concurrent mark to unload the not-entrant target nmethod");
if (CodeCacheUtils.codelistContains(compileId, method, 1, 1 /* not_entrant */)) {
throw new AssertionError("Expected concurrent mark to unload the not-entrant target nmethod");
}
} finally {
WB.concurrentGCReleaseControl();
}
}
}