d52a995f35
Reviewed-by: lmesnik, dholmes, rriggs, stefank
356 lines
12 KiB
Java
356 lines
12 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.
|
|
*/
|
|
|
|
import jdk.test.lib.process.OutputAnalyzer;
|
|
import jdk.test.lib.process.ProcessTools;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
/*
|
|
* @test id=defaults
|
|
* @bug 8305994 8306825
|
|
* @summary Test the deflation intervals options
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest defaults
|
|
*/
|
|
|
|
/*
|
|
* @test id=allIntervalsZero
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest allIntervalsZero
|
|
*/
|
|
|
|
/*
|
|
* @test id=allThresholdsZero
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest allThresholdsZero
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_noThresholdMUDT_noSafepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_noThresholdMUDT_noSafepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_noThresholdMUDT_safepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_noThresholdMUDT_safepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_noThresholdADI_noSafepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_noThresholdADI_noSafepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_noThresholdADI_safepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_noThresholdADI_safepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=noGuaranteedGADT_threshold_noSafepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest noGuaranteedGADT_threshold_noSafepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=noGuaranteedGADT_threshold_safepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest noGuaranteedGADT_threshold_safepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_threshold_noSafepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_threshold_noSafepoint
|
|
*/
|
|
|
|
/*
|
|
* @test id=guaranteed_threshold_safepoint
|
|
* @requires vm.flagless
|
|
* @library /test/lib
|
|
* @run driver DeflationIntervalsTest guaranteed_threshold_safepoint
|
|
*/
|
|
|
|
public class DeflationIntervalsTest {
|
|
|
|
public static class Test {
|
|
// Inflate a lot of monitors, so that threshold heuristics definitely fires
|
|
private static final int MONITORS = 10_000;
|
|
|
|
// Use a handful of threads to inflate the monitors, to eat the cost of
|
|
// wait(1) calls. This can be larger than available parallelism, since threads
|
|
// would be time-waiting.
|
|
private static final int THREADS = 16;
|
|
|
|
private static Thread[] threads;
|
|
private static Object[] monitors;
|
|
|
|
public static void main(String... args) throws Exception {
|
|
monitors = new Object[MONITORS];
|
|
threads = new Thread[THREADS];
|
|
|
|
for (int t = 0; t < THREADS; t++) {
|
|
int monStart = t * MONITORS / THREADS;
|
|
int monEnd = (t + 1) * MONITORS / THREADS;
|
|
threads[t] = new Thread(() -> {
|
|
for (int m = monStart; m < monEnd; m++) {
|
|
Object o = new Object();
|
|
synchronized (o) {
|
|
try {
|
|
o.wait(1);
|
|
} catch (InterruptedException e) {
|
|
}
|
|
}
|
|
monitors[m] = o;
|
|
}
|
|
});
|
|
threads[t].start();
|
|
}
|
|
|
|
for (Thread t : threads) {
|
|
t.join();
|
|
}
|
|
|
|
try {
|
|
Thread.sleep(10_000);
|
|
} catch (InterruptedException ie) {
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
if (args.length < 1) {
|
|
throw new IllegalArgumentException("Expect the test label");
|
|
}
|
|
|
|
String test = args[0];
|
|
switch (test) {
|
|
case "defaults":
|
|
// Try with all defaults
|
|
test(Disabled.NO, Guaranteed.MAYBE, Threshold.MAYBE);
|
|
break;
|
|
|
|
case "allIntervalsZero":
|
|
// Try with all deflation intervals at zero
|
|
test(Disabled.YES, Guaranteed.NO, Threshold.NO,
|
|
"-XX:GuaranteedAsyncDeflationInterval=0",
|
|
"-XX:AsyncDeflationInterval=0",
|
|
"-XX:GuaranteedSafepointInterval=0"
|
|
);
|
|
break;
|
|
|
|
case "allThresholdsZero":
|
|
// Try with all heuristics thresholds at zero
|
|
test(Disabled.NO, Guaranteed.MAYBE, Threshold.NO,
|
|
"-XX:MonitorUsedDeflationThreshold=0"
|
|
);
|
|
break;
|
|
|
|
// Try with guaranteed interval only enabled, threshold heuristics disabled via MUDT,
|
|
// with and without guaranteed safepoints
|
|
|
|
case "guaranteed_noThresholdMUDT_noSafepoint":
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.NO,
|
|
"-XX:GuaranteedAsyncDeflationInterval=100",
|
|
"-XX:MonitorUsedDeflationThreshold=0",
|
|
"-XX:GuaranteedSafepointInterval=0"
|
|
);
|
|
break;
|
|
|
|
case "guaranteed_noThresholdMUDT_safepoint":
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.NO,
|
|
"-XX:GuaranteedAsyncDeflationInterval=100",
|
|
"-XX:MonitorUsedDeflationThreshold=0"
|
|
);
|
|
break;
|
|
|
|
// Try with guaranteed interval only enabled, threshold heuristics disabled via ADI
|
|
// with and without guaranteed safepoints
|
|
|
|
case "guaranteed_noThresholdADI_noSafepoint":
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.NO,
|
|
"-XX:GuaranteedAsyncDeflationInterval=100",
|
|
"-XX:AsyncDeflationInterval=0",
|
|
"-XX:GuaranteedSafepointInterval=0"
|
|
);
|
|
break;
|
|
|
|
case "guaranteed_noThresholdADI_safepoint":
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.NO,
|
|
"-XX:GuaranteedAsyncDeflationInterval=100",
|
|
"-XX:AsyncDeflationInterval=0"
|
|
);
|
|
break;
|
|
|
|
// Try with only threshold heuristics, guaranteed is disabled with GADT
|
|
// with and without guaranteed safepoints
|
|
|
|
case "noGuaranteedGADT_threshold_noSafepoint":
|
|
test(Disabled.NO, Guaranteed.NO, Threshold.YES,
|
|
"-XX:GuaranteedAsyncDeflationInterval=0",
|
|
"-XX:MonitorUsedDeflationThreshold=1",
|
|
"-XX:GuaranteedSafepointInterval=0"
|
|
);
|
|
break;
|
|
|
|
case "noGuaranteedGADT_threshold_safepoint":
|
|
test(Disabled.NO, Guaranteed.NO, Threshold.YES,
|
|
"-XX:GuaranteedAsyncDeflationInterval=0",
|
|
"-XX:MonitorUsedDeflationThreshold=1"
|
|
);
|
|
break;
|
|
|
|
// Try with both threshold heuristics and guaranteed interval enabled
|
|
// with and without guaranteed safepoints
|
|
|
|
case "guaranteed_threshold_noSafepoint":
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.YES,
|
|
"-XX:GuaranteedAsyncDeflationInterval=5000",
|
|
"-XX:MonitorUsedDeflationThreshold=1",
|
|
"-XX:GuaranteedSafepointInterval=0"
|
|
);
|
|
break;
|
|
|
|
case "guaranteed_threshold_safepoint":
|
|
// Try with both threshold heuristics and guaranteed interval enabled
|
|
test(Disabled.NO, Guaranteed.YES, Threshold.YES,
|
|
"-XX:GuaranteedAsyncDeflationInterval=5000",
|
|
"-XX:MonitorUsedDeflationThreshold=1"
|
|
);
|
|
break;
|
|
|
|
default:
|
|
throw new IllegalArgumentException("Unknown test: " + test);
|
|
}
|
|
}
|
|
|
|
static final String MSG_THRESHOLD = "Async deflation needed: monitors used are above the threshold";
|
|
static final String MSG_GUARANTEED = "Async deflation needed: guaranteed interval";
|
|
static final String MSG_DISABLED = "Async deflation is disabled";
|
|
|
|
public static void test(Disabled disabled, Guaranteed guaranteed, Threshold threshold, String... args) throws Exception {
|
|
List<String> opts = new ArrayList<>();
|
|
opts.add("-Xmx128M");
|
|
opts.add("-XX:+UnlockDiagnosticVMOptions");
|
|
opts.add("-Xlog:monitorinflation=info");
|
|
opts.addAll(Arrays.asList(args));
|
|
opts.add("DeflationIntervalsTest$Test");
|
|
|
|
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(opts);
|
|
OutputAnalyzer oa = new OutputAnalyzer(pb.start());
|
|
oa.shouldHaveExitValue(0);
|
|
|
|
switch (disabled) {
|
|
case YES: oa.shouldContain(MSG_DISABLED); break;
|
|
case NO: oa.shouldNotContain(MSG_DISABLED); break;
|
|
case MAYBE: break;
|
|
}
|
|
|
|
switch (threshold) {
|
|
case YES: oa.shouldContain(MSG_THRESHOLD); break;
|
|
case NO: oa.shouldNotContain(MSG_THRESHOLD); break;
|
|
case MAYBE: break;
|
|
}
|
|
|
|
switch (guaranteed) {
|
|
case YES: oa.shouldContain(MSG_GUARANTEED); break;
|
|
case NO: oa.shouldNotContain(MSG_GUARANTEED); break;
|
|
case MAYBE: break;
|
|
}
|
|
|
|
if (threshold == Threshold.YES || guaranteed == Guaranteed.YES) {
|
|
assertDeflations(oa);
|
|
} else if (threshold == Threshold.NO && guaranteed == Guaranteed.NO) {
|
|
assertNoDeflations(oa);
|
|
} else {
|
|
// Don't know
|
|
}
|
|
}
|
|
|
|
static final String MSG_FINAL_AUDIT = "Starting the final audit";
|
|
static final String MSG_BEGIN_DEFLATING = "begin deflating";
|
|
|
|
private static void assertNoDeflations(OutputAnalyzer oa) {
|
|
for (String line : oa.asLines()) {
|
|
if (line.contains(MSG_FINAL_AUDIT)) {
|
|
// Final deflations started, with no prior deflations, good.
|
|
return;
|
|
}
|
|
if (line.contains(MSG_BEGIN_DEFLATING)) {
|
|
// Deflations detected before final ones, bad
|
|
oa.reportDiagnosticSummary();
|
|
throw new IllegalStateException("FAILED");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void assertDeflations(OutputAnalyzer oa) {
|
|
for (String line : oa.asLines()) {
|
|
if (line.contains(MSG_FINAL_AUDIT)) {
|
|
// Final deflations started, with no prior deflations, bad.
|
|
oa.reportDiagnosticSummary();
|
|
throw new IllegalStateException("FAILED");
|
|
}
|
|
if (line.contains(MSG_BEGIN_DEFLATING)) {
|
|
// Deflations detected before final ones, good
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
enum Disabled {
|
|
YES,
|
|
NO,
|
|
MAYBE,
|
|
}
|
|
|
|
enum Threshold {
|
|
YES,
|
|
NO,
|
|
MAYBE,
|
|
}
|
|
|
|
enum Guaranteed {
|
|
YES,
|
|
NO,
|
|
MAYBE,
|
|
}
|
|
|
|
}
|