mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-03 11:38:44 +00:00
317 lines
13 KiB
Java
317 lines
13 KiB
Java
/*
|
|
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
package gc;
|
|
|
|
/*
|
|
* @test id=parallel
|
|
* @bug 8370947
|
|
* @summary Check no assertion is triggered when UseSingleICacheInvalidation is enabled for ParallelGC
|
|
* @library /test/lib
|
|
* @requires vm.debug
|
|
* @requires vm.gc.Parallel
|
|
* @requires os.arch == "aarch64"
|
|
* @requires os.family == "linux"
|
|
* @build jdk.test.whitebox.WhiteBox
|
|
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C2
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C2
|
|
*/
|
|
|
|
/*
|
|
* @test id=g1
|
|
* @bug 8370947
|
|
* @summary Check no assertion is triggered when UseSingleICacheInvalidation is enabled for G1GC
|
|
* @library /test/lib
|
|
* @requires vm.debug
|
|
* @requires vm.gc.G1
|
|
* @requires os.arch == "aarch64"
|
|
* @requires os.family == "linux"
|
|
* @build jdk.test.whitebox.WhiteBox
|
|
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C2
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C2
|
|
*/
|
|
|
|
/*
|
|
* @test id=shenandoah
|
|
* @bug 8370947
|
|
* @summary Check no assertion is triggered when UseSingleICacheInvalidation is enabled for ShenandoahGC
|
|
* @library /test/lib
|
|
* @requires vm.debug
|
|
* @requires vm.gc.Shenandoah
|
|
* @requires os.arch == "aarch64"
|
|
* @requires os.family == "linux"
|
|
* @build jdk.test.whitebox.WhiteBox
|
|
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C2
|
|
*/
|
|
|
|
/*
|
|
* @test id=genshen
|
|
* @bug 8370947
|
|
* @summary Check no assertion is triggered when UseSingleICacheInvalidation is enabled for generational ShenandoahGC
|
|
* @library /test/lib
|
|
* @requires vm.debug
|
|
* @requires vm.gc.Shenandoah
|
|
* @requires os.arch == "aarch64"
|
|
* @requires os.family == "linux"
|
|
* @build jdk.test.whitebox.WhiteBox
|
|
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C2
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C2
|
|
*/
|
|
|
|
/*
|
|
* @test id=z
|
|
* @bug 8370947
|
|
* @summary Check no assertion is triggered when UseSingleICacheInvalidation is enabled for ZGC
|
|
* @library /test/lib
|
|
* @requires vm.debug
|
|
* @requires vm.gc.Z
|
|
* @requires os.arch == "aarch64"
|
|
* @requires os.family == "linux"
|
|
* @build jdk.test.whitebox.WhiteBox
|
|
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseZGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseZGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C1
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseZGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation youngGC C2
|
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseZGC -XX:-UseCodeCacheFlushing gc.TestDeferredICacheInvalidation fullGC C2
|
|
*/
|
|
|
|
/*
|
|
* Nmethods have GC barriers and OOPs embedded into their code. GCs can patch nmethod's code
|
|
* which requires icache invalidation. Doing invalidation per instruction can be expensive.
|
|
* CPU can support hardware dcache and icache coherence. This would allow to defer cache
|
|
* invalidation.
|
|
*
|
|
* There are assertions for deferred cache invalidation. This test checks that all of them
|
|
* are passed.
|
|
*/
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
import jdk.test.whitebox.WhiteBox;
|
|
import jtreg.SkippedException;
|
|
|
|
public class TestDeferredICacheInvalidation {
|
|
|
|
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
|
|
|
public static class A {
|
|
public String s1;
|
|
public String s2;
|
|
public String s3;
|
|
public String s4;
|
|
public String s5;
|
|
public String s6;
|
|
public String s7;
|
|
public String s8;
|
|
public String s9;
|
|
}
|
|
|
|
public static A a = new A();
|
|
|
|
private static int compLevel;
|
|
|
|
public static class B {
|
|
public static void test0() {
|
|
}
|
|
|
|
public static void test1() {
|
|
a.s1 = a.s1 + "1";
|
|
}
|
|
|
|
public static void test2() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
}
|
|
|
|
public static void test3() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
}
|
|
|
|
public static void test4() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
}
|
|
|
|
public static void test5() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
a.s5 = a.s5 + "5";
|
|
}
|
|
|
|
public static void test6() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
a.s5 = a.s5 + "5";
|
|
a.s6 = a.s6 + "6";
|
|
}
|
|
|
|
public static void test7() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
a.s5 = a.s5 + "5";
|
|
a.s6 = a.s6 + "6";
|
|
a.s7 = a.s7 + "7";
|
|
}
|
|
|
|
public static void test8() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
a.s5 = a.s5 + "5";
|
|
a.s6 = a.s6 + "6";
|
|
a.s7 = a.s7 + "7";
|
|
a.s8 = a.s8 + "8";
|
|
}
|
|
|
|
public static void test9() {
|
|
a.s1 = a.s1 + "1";
|
|
a.s2 = a.s2 + "2";
|
|
a.s3 = a.s3 + "3";
|
|
a.s4 = a.s4 + "4";
|
|
a.s5 = a.s5 + "5";
|
|
a.s6 = a.s6 + "6";
|
|
a.s7 = a.s7 + "7";
|
|
a.s8 = a.s8 + "8";
|
|
a.s9 = a.s9 + "9";
|
|
}
|
|
}
|
|
|
|
private static void compileMethods() throws Exception {
|
|
for (var m : B.class.getDeclaredMethods()) {
|
|
if (!m.getName().startsWith("test")) {
|
|
continue;
|
|
}
|
|
m.invoke(null);
|
|
WB.markMethodProfiled(m);
|
|
WB.enqueueMethodForCompilation(m, compLevel);
|
|
while (WB.isMethodQueuedForCompilation(m)) {
|
|
Thread.sleep(100);
|
|
}
|
|
if (WB.getMethodCompilationLevel(m) != compLevel) {
|
|
throw new IllegalStateException("Method " + m + " is not compiled at the compilation level: " + compLevel + ". Got: " + WB.getMethodCompilationLevel(m));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void youngGC() throws Exception {
|
|
a = null;
|
|
WB.youngGC();
|
|
}
|
|
|
|
public static void fullGC() throws Exception {
|
|
// Thread synchronization
|
|
final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
|
final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
|
|
final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
|
|
final AtomicBoolean running = new AtomicBoolean(true);
|
|
|
|
// Thread 1: GC thread that runs for 1 second with 100ms sleep intervals
|
|
Thread gcThread = new Thread(() -> {
|
|
final long startTime = System.currentTimeMillis();
|
|
final long duration = 1000;
|
|
try {
|
|
while (System.currentTimeMillis() - startTime < duration) {
|
|
writeLock.lock();
|
|
try {
|
|
a = new A();
|
|
WB.fullGC();
|
|
} finally {
|
|
writeLock.unlock();
|
|
}
|
|
Thread.sleep(100);
|
|
}
|
|
} catch (InterruptedException e) {
|
|
// Thread interrupted, exit
|
|
}
|
|
running.set(false);
|
|
});
|
|
|
|
// Threads 2-11: Test threads that execute test0() through test9()
|
|
Thread[] testThreads = new Thread[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
final int testIdx = i;
|
|
testThreads[i] = new Thread(() -> {
|
|
try {
|
|
var method = B.class.getDeclaredMethod("test" + testIdx);
|
|
while (running.get()) {
|
|
readLock.lock();
|
|
try {
|
|
method.invoke(null);
|
|
} finally {
|
|
readLock.unlock();
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
System.exit(10);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Start all threads
|
|
gcThread.start();
|
|
for (Thread t : testThreads) {
|
|
t.start();
|
|
}
|
|
|
|
// Wait for all threads to complete
|
|
gcThread.join();
|
|
for (Thread t : testThreads) {
|
|
t.join();
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
if (!Boolean.TRUE.equals(WB.getBooleanVMFlag("UseSingleICacheInvalidation"))) {
|
|
throw new SkippedException("Skip. Test requires UseSingleICacheInvalidation enabled.");
|
|
}
|
|
compLevel = (args[1].equals("C1")) ? 1 : 4;
|
|
compileMethods();
|
|
TestDeferredICacheInvalidation.class.getMethod(args[0]).invoke(null);
|
|
}
|
|
}
|