aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authoriignatyev <none@none>2014-04-11 00:35:23 +0400
committeriignatyev <none@none>2014-04-11 00:35:23 +0400
commit9d043f30941131d15128f8862bc0e50d45964acf (patch)
treeaf6e561e0a03c5d7a14614339dcbcd0d3bebfe24 /test
parent0edbde80cb94c2d88259a7c9c669b183fc7a72a8 (diff)
8037860: Add tests to cover Intel RTM instructions support
Reviewed-by: kvn, iignatyev Contributed-by: filipp.zhinkin@oracle.com
Diffstat (limited to 'test')
-rw-r--r--test/compiler/rtm/locking/TestRTMAbortRatio.java163
-rw-r--r--test/compiler/rtm/locking/TestRTMAbortThreshold.java102
-rw-r--r--test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java210
-rw-r--r--test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java114
-rw-r--r--test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java167
-rw-r--r--test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java106
-rw-r--r--test/compiler/rtm/locking/TestRTMLockingThreshold.java179
-rw-r--r--test/compiler/rtm/locking/TestRTMRetryCount.java102
-rw-r--r--test/compiler/rtm/locking/TestRTMSpinLoopCount.java115
-rw-r--r--test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java150
-rw-r--r--test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java127
-rw-r--r--test/compiler/rtm/locking/TestUseRTMDeopt.java88
-rw-r--r--test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java92
-rw-r--r--test/compiler/rtm/locking/TestUseRTMForStackLocks.java95
-rw-r--r--test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java111
-rw-r--r--test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java102
-rw-r--r--test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java116
-rw-r--r--test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java142
18 files changed, 2281 insertions, 0 deletions
diff --git a/test/compiler/rtm/locking/TestRTMAbortRatio.java b/test/compiler/rtm/locking/TestRTMAbortRatio.java
new file mode 100644
index 000000000..2c179d8ee
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMAbortRatio.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMAbortRatio affects amount of aborts before
+ * deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that method will be deoptimized on high abort ratio
+ * as soon as abort ratio reaches RTMAbortRatio's value.
+ */
+public class TestRTMAbortRatio extends CommandLineOptionTest {
+ private TestRTMAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyAbortRatio(0, false);
+ verifyAbortRatio(10, false);
+ verifyAbortRatio(50, false);
+ verifyAbortRatio(100, false);
+
+ verifyAbortRatio(0, true);
+ verifyAbortRatio(10, true);
+ verifyAbortRatio(50, true);
+ verifyAbortRatio(100, true);
+ }
+
+ private void verifyAbortRatio(int abortRatio, boolean useStackLock)
+ throws Throwable {
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMAbortThreshold=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ 10 * Test.TOTAL_ITERATIONS),
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortRatio",
+ abortRatio),
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ test.getClass().getName(),
+ Boolean.toString(!useStackLock));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry.");
+
+ RTMLockingStatistics lock = statistics.get(0);
+ int actualRatio;
+
+ if (lock.getTotalAborts() == 1L) {
+ actualRatio = 0;
+ } else {
+ actualRatio = (int) (lock.getTotalLocks()
+ / (lock.getTotalAborts() - 1L));
+ }
+
+ Asserts.assertLTE(actualRatio, abortRatio, String.format(
+ "Actual abort ratio (%d) should lower or equal to "
+ + "specified (%d).", actualRatio, abortRatio));
+ }
+
+ /**
+ * Force abort after {@code Test.WARMUP_ITERATIONS} is done.
+ */
+ public static class Test implements CompilableTest {
+ private static final int TOTAL_ITERATIONS = 10000;
+ private static final int WARMUP_ITERATIONS = 1000;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void lock(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test &lt;inflate monitor&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+ t.lock(i >= Test.WARMUP_ITERATIONS);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortRatio().test();
+ }
+}
+
diff --git a/test/compiler/rtm/locking/TestRTMAbortThreshold.java b/test/compiler/rtm/locking/TestRTMAbortThreshold.java
new file mode 100644
index 000000000..dbed5f0fb
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMAbortThreshold.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMAbortThreshold option affects
+ * amount of aborts after which abort ratio is calculated.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on RTMAbortThreshold option actually affects how soon
+ * method will be deoptimized on high abort ratio.
+ */
+public class TestRTMAbortThreshold extends CommandLineOptionTest {
+ private TestRTMAbortThreshold() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyAbortThreshold(false, 1);
+ verifyAbortThreshold(false, 10);
+ verifyAbortThreshold(false, 1000);
+
+ verifyAbortThreshold(true, 1);
+ verifyAbortThreshold(true, 10);
+ verifyAbortThreshold(true, 1000);
+ }
+
+ private void verifyAbortThreshold(boolean useStackLock,
+ long abortThreshold) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMAbortRatio=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ abortThreshold),
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalLocks(), abortThreshold,
+ String.format("Expected that method with rtm lock elision was"
+ + " deoptimized after %d lock attempts",
+ abortThreshold));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortThreshold().test();
+ }
+}
+
diff --git a/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java
new file mode 100644
index 000000000..2cf81f7f6
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that if we use RTMDeopt, then deoptimization
+ * caused by reason other then rtm_state_change will reset
+ * method's RTM state. And if we don't use RTMDeopt, then
+ * RTM state remain the same after such deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAfterNonRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAfterNonRTMDeopt
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * To verify that with +UseRTMDeopt method's RTM state will be
+ * changed to ProfileRTM on deoptimization unrelated to
+ * rtm_state_change following sequence of events is used:
+ * <pre>
+ *
+ * rtm state ^
+ * |
+ * UseRTM | ******| ******
+ * | |
+ * ProfileRTM |******| |*****|
+ * | | | |
+ * 0-------|-----|-----|---------------------&gt; time
+ * | | \ force abort
+ * | |
+ * | \ force deoptimization
+ * |
+ * \ force xabort
+ * </pre>
+ * When xabort is forced by native method call method should
+ * change it's state to UseRTM, because we use RTMAbortRatio=100
+ * and low RTMLockingThreshold, so at this point actual abort
+ * ratio will be below 100% and there should be enough lock
+ * attempts to recompile method without RTM profiling.
+ */
+public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest {
+ private static final int ABORT_THRESHOLD = 1000;
+ private static final String RANGE_CHECK = "range_check";
+
+ private TestRTMAfterNonRTMDeopt() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMAfterDeopt(false, false);
+ verifyRTMAfterDeopt(true, false);
+
+ verifyRTMAfterDeopt(false, true);
+ verifyRTMAfterDeopt(true, true);
+ }
+
+ private void verifyRTMAfterDeopt(boolean useStackLock,
+ boolean useRTMDeopt) throws Throwable {
+ CompilableTest test = new Test();
+ String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml",
+ (useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no"));
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFile,
+ test,
+ "-XX:CompileThreshold=1",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+ useRTMDeopt),
+ "-XX:RTMAbortRatio=100",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int traps = RTMTestBase.firedRTMStateChangeTraps(logFile);
+
+ if (useRTMDeopt) {
+ Asserts.assertEQ(traps, 2, "Two uncommon traps with "
+ + "reason rtm_state_change should be fired.");
+ } else {
+ Asserts.assertEQ(traps, 0, "No uncommon traps with "
+ + "reason rtm_state_change should be fired.");
+ }
+
+ int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile,
+ TestRTMAfterNonRTMDeopt.RANGE_CHECK);
+
+ Asserts.assertEQ(rangeCheckTraps, 1,
+ "One range_check uncommon trap should be fired.");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ int expectedStatEntries = (useRTMDeopt ? 4 : 2);
+
+ Asserts.assertEQ(statistics.size(), expectedStatEntries,
+ String.format("VM output should contain %d RTM locking "
+ + "statistics entries.", expectedStatEntries));
+ }
+
+ public static class Test implements CompilableTest {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final int ITERATIONS = 10000;
+ private static final int RANGE_CHECK_AT = ITERATIONS / 2;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::forceAbort";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::forceAbort"
+ };
+ }
+
+ public void forceAbort(int a[], boolean abort) {
+ try {
+ synchronized(monitor) {
+ a[0]++;
+ if (abort) {
+ Test.field = Test.UNSAFE.addressSize();
+ }
+ }
+ } catch (Throwable t) {
+ // suppress any throwables
+ }
+ }
+
+ /**
+ * Usage:
+ * Test &lt;inflate monitor&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+
+ int tmp[] = new int[1];
+
+ for (int i = 0; i < Test.ITERATIONS; i++ ) {
+ if (i == Test.RANGE_CHECK_AT) {
+ t.forceAbort(new int[0], false);
+ } else {
+ boolean isThreshold
+ = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD);
+ boolean isThresholdPlusRange
+ = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD
+ + Test.RANGE_CHECK_AT);
+ t.forceAbort(tmp, isThreshold || isThresholdPlusRange);
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAfterNonRTMDeopt().test();
+ }
+}
+
diff --git a/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java b/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java
new file mode 100644
index 000000000..911cc21a9
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that on high abort ratio method will be recompiled
+ * without rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnHighAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMDeoptOnHighAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on high abort ratio method wil be deoptimized with
+ * <i>rtm_state_change</i> reason and after that RTM-based lock elision will not
+ * be used for that method.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnHighAbortRatio extends CommandLineOptionTest {
+ private static final long ABORT_THRESHOLD
+ = AbortProvoker.DEFAULT_ITERATIONS / 2L;
+
+ private TestRTMDeoptOnHighAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyDeopt(false);
+ verifyDeopt(true);
+ }
+
+ private void verifyDeopt(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:RTMRetryCount=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD),
+ "-XX:RTMAbortRatio=100",
+ "-XX:CompileThreshold=1",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 1, "Expected to get only one "
+ + "deoptimization due to rtm state change");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalLocks(),
+ TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD,
+ "After AbortThreshold was reached, method should be"
+ + " recompiled without rtm lock eliding.");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMDeoptOnHighAbortRatio().test();
+ }
+}
+
diff --git a/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java
new file mode 100644
index 000000000..bcadaab6c
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that on low abort ratio method will be recompiled.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnLowAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMDeoptOnLowAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that low abort ratio method will be deoptimized with
+ * <i>rtm_state_change</i> reason and will continue to use RTM-based lock
+ * elision after that.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest {
+ private static final long LOCKING_THRESHOLD = 100L;
+
+ private TestRTMDeoptOnLowAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMDeopt(false);
+ verifyRTMDeopt(true);
+ }
+
+ private void verifyRTMDeopt(boolean useStackLock) throws Throwable {
+ CompilableTest test = new Test();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ useStackLock ? "use" : "no");
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ test,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD),
+ "-XX:RTMAbortThreshold=1",
+ "-XX:RTMAbortRatio=100",
+ "-XX:CompileThreshold=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 1,
+ "Expected to get only one deoptimization due to rtm"
+ + " state change");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2,
+ "VM output should contain two RTM locking "
+ + "statistics entries for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics statisticsBeforeDeopt = null;
+
+ for (RTMLockingStatistics s : statistics) {
+ if (s.getTotalLocks()
+ == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD + 1L) {
+ Asserts.assertNull(statisticsBeforeDeopt,
+ "Only one abort was expected during test run");
+ statisticsBeforeDeopt = s;
+ }
+ }
+
+ Asserts.assertNotNull(statisticsBeforeDeopt,
+ "After LockThreshold was reached, method should be recompiled "
+ + "with rtm lock eliding.");
+ }
+
+ public static class Test implements CompilableTest {
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::forceAbort";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void forceAbort(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test &lt;inflate monitor&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ t.forceAbort(
+ i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMDeoptOnLowAbortRatio().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java b/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java
new file mode 100644
index 000000000..61f84e430
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMLockingCalculationDelay affect when
+ * abort ratio calculation is started.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingCalculationDelay
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMLockingCalculationDelay
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that abort ratio calculation could be delayed using
+ * RTMLockingCalculationDelay option.
+ */
+public class TestRTMLockingCalculationDelay extends CommandLineOptionTest {
+ private static final boolean INFLATE_MONITOR = true;
+
+ private TestRTMLockingCalculationDelay() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ // verify that calculation will be started immediately
+ verifyLockingCalculationDelay(0, 0, true);
+
+ // verify that calculation will not be started during
+ // first 10 minutes, while test will be started immediately
+ verifyLockingCalculationDelay(600000, 0, false);
+
+ // verify that calculation will be started after a second
+ verifyLockingCalculationDelay(1000, 1000, true);
+ }
+
+ private void verifyLockingCalculationDelay(long delay, long testDelay,
+ boolean deoptExpected) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_delay_%d_%d.xml", delay,
+ testDelay);
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareNumericFlag(
+ "RTMLockingCalculationDelay", delay),
+ "-XX:RTMAbortRatio=0",
+ "-XX:RTMAbortThreshold=0",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(
+ TestRTMLockingCalculationDelay.INFLATE_MONITOR),
+ Long.toString(AbortProvoker.DEFAULT_ITERATIONS),
+ Long.toString(testDelay)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int deopts = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ if (deoptExpected) {
+ Asserts.assertGT(deopts, 0, "At least one deoptimization due to "
+ + "rtm_state_chage is expected");
+ } else {
+ Asserts.assertEQ(deopts, 0, "No deoptimizations due to "
+ + "rtm_state_chage are expected");
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMLockingCalculationDelay().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/test/compiler/rtm/locking/TestRTMLockingThreshold.java
new file mode 100644
index 000000000..548a09c6e
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMLockingThreshold.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMLockingThreshold affects rtm state transition
+ * ProfileRTM => UseRTM.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMLockingThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that RTMLockingThreshold option actually affects how soon
+ * method will be deoptimized on low abort ratio.
+ */
+public class TestRTMLockingThreshold extends CommandLineOptionTest {
+ private TestRTMLockingThreshold() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ /**
+ * We use non-zero abort threshold to avoid abort related to
+ * interrupts, VMM calls, etc. during first lock attempt.
+ *
+ */
+ private static final int ABORT_THRESHOLD = 10;
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyLockingThreshold(0, false);
+ verifyLockingThreshold(100, false);
+ verifyLockingThreshold(1000, false);
+
+ verifyLockingThreshold(0, true);
+ verifyLockingThreshold(100, true);
+ verifyLockingThreshold(1000, true);
+ }
+
+ private void verifyLockingThreshold(int lockingThreshold,
+ boolean useStackLock) throws Throwable {
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ "-XX:CompileThreshold=1",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMLockingThreshold.ABORT_THRESHOLD),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ lockingThreshold),
+ "-XX:RTMAbortRatio=100",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock),
+ Integer.toString(lockingThreshold)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2, "VM output should contain two "
+ + "RTM locking statistics entries.");
+
+ /**
+ * We force abort on each odd iteration, so if RTMLockingThreshold==0,
+ * then we have to make 1 call without abort to avoid rtm state
+ * transition to NoRTM (otherwise actual abort ratio will be 100%),
+ * and after that make 1 call with abort to force deoptimization.
+ * This leads us to two locks for threshold 0.
+ * For other threshold values we have to make RTMLockingThreshold + 1
+ * locks if locking threshold is even, or + 0 if odd.
+ */
+ long expectedValue = lockingThreshold +
+ (lockingThreshold == 0L ? 2L : lockingThreshold % 2L);
+
+ RTMLockingStatistics statBeforeDeopt = null;
+ for (RTMLockingStatistics s : statistics) {
+ if (s.getTotalLocks() == expectedValue) {
+ Asserts.assertNull(statBeforeDeopt,
+ "Only one statistics entry should contain aborts");
+ statBeforeDeopt = s;
+ }
+ }
+
+ Asserts.assertNotNull(statBeforeDeopt, "There should be exactly one "
+ + "statistics entry corresponding to ProfileRTM state.");
+ }
+
+ public static class Test implements CompilableTest {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final int TOTAL_ITERATIONS = 10000;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void lock(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.field += Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test &lt;inflate monitor&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+ t.lock(i % 2 == 1);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMLockingThreshold().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestRTMRetryCount.java b/test/compiler/rtm/locking/TestRTMRetryCount.java
new file mode 100644
index 000000000..1a0c20cd7
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMRetryCount.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMRetryCount affects actual amount of retries.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMRetryCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMRetryCount
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMRetryCount option actually affects amount of
+ * retries on lock busy.
+ */
+public class TestRTMRetryCount extends CommandLineOptionTest {
+ /**
+ * Time in ms, during which busy lock will be locked.
+ */
+ private static final int LOCKING_TIME = 5000;
+ private static final boolean INFLATE_MONITOR = true;
+
+ private TestRTMRetryCount() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMRetryCount(0);
+ verifyRTMRetryCount(1);
+ verifyRTMRetryCount(5);
+ verifyRTMRetryCount(10);
+ }
+
+ private void verifyRTMRetryCount(int retryCount) throws Throwable {
+ CompilableTest busyLock = new BusyLock();
+ long expectedAborts = retryCount + 1L;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ busyLock,
+ "-XX:-UseRTMXendForLockBusy",
+ "-XX:RTMTotalCountIncrRate=1",
+ CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+ retryCount),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(TestRTMRetryCount.INFLATE_MONITOR),
+ Integer.toString(TestRTMRetryCount.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ busyLock.getMethodWithLockName(), outputAnalyzer.getStdout());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one rtm locking statistics entry for method "
+ + busyLock.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalAborts(), expectedAborts,
+ String.format("It is expected to get %d aborts",
+ expectedAborts));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMRetryCount().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestRTMSpinLoopCount.java b/test/compiler/rtm/locking/TestRTMSpinLoopCount.java
new file mode 100644
index 000000000..8cb4bbbe9
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMSpinLoopCount.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMSpinLoopCount affects time spent
+ * between locking attempts.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMSpinLoopCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMSpinLoopCount
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMSpinLoopCount increase time spent between retries
+ * by comparing amount of retries done with different RTMSpinLoopCount's values.
+ */
+public class TestRTMSpinLoopCount extends CommandLineOptionTest {
+ private static final int LOCKING_TIME = 1000;
+ private static final int RTM_RETRY_COUNT = 1000;
+ private static final boolean INFLATE_MONITOR = true;
+ private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
+ private static final int[] SPIN_LOOP_COUNTS
+ = new int[] { 0, 100, 1_000, 1_000_000, 10_000_000 };
+
+ private TestRTMSpinLoopCount() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
+ for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
+ aborts[i] = getAbortsCountOnLockBusy(
+ TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);
+ }
+
+ for (int i = 1; i < aborts.length; i++) {
+ Asserts.assertLTE(aborts[i], aborts[i - 1], "Increased spin loop "
+ + "count should not increase retries count.");
+ }
+ }
+
+ private long getAbortsCountOnLockBusy(int spinLoopCount) throws Throwable {
+ CompilableTest test = new BusyLock();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+ TestRTMSpinLoopCount.RTM_RETRY_COUNT),
+ CommandLineOptionTest.prepareNumericFlag("RTMSpinLoopCount",
+ spinLoopCount),
+ "-XX:-UseRTMXendForLockBusy",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(TestRTMSpinLoopCount.INFLATE_MONITOR),
+ Integer.toString(TestRTMSpinLoopCount.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one entry for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertLTE(lock.getTotalAborts(),
+ TestRTMSpinLoopCount.MAX_ABORTS, String.format("Total aborts "
+ + "count (%d) should be less or equal to %d",
+ lock.getTotalAborts(),
+ TestRTMSpinLoopCount.MAX_ABORTS));
+
+ return lock.getTotalAborts();
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMSpinLoopCount().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java
new file mode 100644
index 000000000..e1f94d31d
--- /dev/null
+++ b/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMTotalCountIncrRate option affects
+ * RTM locking statistics.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRate
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with RTMTotalCountIncrRate=1 RTM locking statistics
+ * contains precise information abort attempted locks and that with other values
+ * statistics contains information abort non-zero locking attempts.
+ * Since assert done for RTMTotalCountIncrRate=1 is pretty strict, test uses
+ * -XX:RTMRetryCount=0 to avoid issue with retriable aborts. For more details on
+ * that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMTotalCountIncrRate extends CommandLineOptionTest {
+ private TestRTMTotalCountIncrRate() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyLocksCount(1, false);
+ verifyLocksCount(64, false);
+ verifyLocksCount(128, false);
+ verifyLocksCount(1, true);
+ verifyLocksCount(64, true);
+ verifyLocksCount(128, true);
+ }
+
+ private void verifyLocksCount(int incrRate, boolean useStackLock)
+ throws Throwable{
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareNumericFlag(
+ "RTMTotalCountIncrRate", incrRate),
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+ if (incrRate == 1) {
+ Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS,
+ "Total locks should be exactly the same as amount of "
+ + "iterations.");
+ } else {
+ Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics "
+ + "should contain information for at least on lock.");
+ }
+ }
+
+ public static class Test implements CompilableTest {
+ private static final long TOTAL_ITERATIONS = 10000L;
+ private final Object monitor = new Object();
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName()
+ };
+ }
+
+ public void lock() {
+ synchronized(monitor) {
+ Test.field++;
+ }
+ }
+
+ /**
+ * Usage:
+ * Test &lt;inflate monitor&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test test = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(test.monitor);
+ }
+ for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) {
+ test.lock();
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMTotalCountIncrRate().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java b/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java
new file mode 100644
index 000000000..f1fa1393f
--- /dev/null
+++ b/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for stack locks before
+ * inflation and after it used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMAfterLockInflation
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMAfterLockInflation
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM is used after lock inflation by executing compiled
+ * method with RTM-based lock elision using stack lock first, then that lock
+ * is inflated and the same compiled method invoked again.
+ *
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before
+ * lock inflation and the same amount of times after inflation.
+ * As a result total locks count should be equal to
+ * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}.
+ * It is a pretty strict assertion which could fail if some retriable abort
+ * happened: it could be {@code AbortType.RETRIABLE} or
+ * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these
+ * reasons simultaneously. In order to avoid false negative failures related
+ * to incorrect aborts counting, -XX:RTMRetryCount=0 is used.
+ */
+public class TestUseRTMAfterLockInflation extends CommandLineOptionTest {
+ private static final long EXPECTED_LOCKS
+ = 2L * AbortProvoker.DEFAULT_ITERATIONS;
+
+ private TestUseRTMAfterLockInflation() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ long totalLocksCount = 0;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ AbortType.XABORT.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2,
+ "VM output should contain two rtm locking statistics entries "
+ + "for method " + provoker.getMethodWithLockName());
+
+ for (RTMLockingStatistics s : statistics) {
+ totalLocksCount += s.getTotalLocks();
+ }
+
+ Asserts.assertEQ(totalLocksCount,
+ TestUseRTMAfterLockInflation.EXPECTED_LOCKS,
+ "Total lock count should be greater or equal to "
+ + TestUseRTMAfterLockInflation.EXPECTED_LOCKS);
+ }
+
+ public static class Test {
+
+ /**
+ * Usage:
+ * Test &lt;provoker type&gt;
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGT(args.length, 0,
+ "AbortType name is expected as first argument.");
+
+ AbortProvoker provoker
+ = AbortType.lookup(Integer.valueOf(args[0])).provoker();
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ provoker.forceAbort();
+ }
+ provoker.inflateMonitor();
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ provoker.forceAbort();
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMAfterLockInflation().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestUseRTMDeopt.java b/test/compiler/rtm/locking/TestUseRTMDeopt.java
new file mode 100644
index 000000000..2e0dcbc71
--- /dev/null
+++ b/test/compiler/rtm/locking/TestUseRTMDeopt.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMDeopt affects uncommon trap installation in
+ * copmpiled methods with synchronized block.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMDeopt
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that usage of UseRTMDeopt option affects uncommon traps usage
+ * for methods that use locking.
+ */
+public class TestUseRTMDeopt extends CommandLineOptionTest {
+ private TestUseRTMDeopt() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyUseRTMDeopt(false);
+ verifyUseRTMDeopt(true);
+ }
+
+ private void verifyUseRTMDeopt(boolean useRTMDeopt) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_%s_deopt.xml",
+ useRTMDeopt ? "use" : "no");
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+ useRTMDeopt),
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString()
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int expectedUncommonTraps = useRTMDeopt ? 1 : 0;
+ int installedUncommonTraps
+ = RTMTestBase.installedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(expectedUncommonTraps, installedUncommonTraps,
+ String.format("Expected to find %d uncommon traps "
+ + "installed with reason rtm_state_change.",
+ expectedUncommonTraps));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMDeopt().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java b/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java
new file mode 100644
index 000000000..34fa34c55
--- /dev/null
+++ b/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForInflatedLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMForInflatedLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for inflated locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * manually inflated lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForInflatedLocks extends CommandLineOptionTest {
+ private TestUseRTMForInflatedLocks() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ RTMLockingStatistics lock;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:-UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one rtm locking statistics "
+ + "entry for method " + provoker.getMethodWithLockName());
+
+ lock = statistics.get(0);
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Total lock count should be greater or equal to "
+ + AbortProvoker.DEFAULT_ITERATIONS);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForInflatedLocks().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestUseRTMForStackLocks.java b/test/compiler/rtm/locking/TestUseRTMForStackLocks.java
new file mode 100644
index 000000000..0a54511a7
--- /dev/null
+++ b/test/compiler/rtm/locking/TestUseRTMForStackLocks.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for stack locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMForStackLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for stack locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * stack lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForStackLocks extends CommandLineOptionTest {
+ private static final boolean INFLATE_MONITOR = false;
+
+ private TestUseRTMForStackLocks() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ RTMLockingStatistics lock;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(TestUseRTMForStackLocks.INFLATE_MONITOR));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one rtm locking statistics "
+ + "entry for method " + provoker.getMethodWithLockName());
+
+ lock = statistics.get(0);
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Total locks count should be greater or equal to "
+ + AbortProvoker.DEFAULT_ITERATIONS);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForStackLocks().test();
+ }
+}
diff --git a/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java b/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java
new file mode 100644
index 000000000..4fc5d999b
--- /dev/null
+++ b/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMXendForLockBusy option affects
+ * method behaviour if lock is busy.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMXendForLockBusy
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMXendForLockBusy
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with +UseRTMXendForLockBusy there will be no aborts
+ * forced by the test.
+ */
+public class TestUseRTMXendForLockBusy extends CommandLineOptionTest {
+ private final static int LOCKING_TIME = 5000;
+
+ private TestUseRTMXendForLockBusy() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ // inflated lock, xabort on lock busy
+ verifyXendForLockBusy(true, false);
+ // inflated lock, xend on lock busy
+ verifyXendForLockBusy(true, true);
+ // stack lock, xabort on lock busy
+ verifyXendForLockBusy(false, false);
+ // stack lock, xend on lock busy
+ verifyXendForLockBusy(false, true);
+ }
+
+ private void verifyXendForLockBusy(boolean inflateMonitor,
+ boolean useXend) throws Throwable {
+ CompilableTest test = new BusyLock();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ inflateMonitor),
+ CommandLineOptionTest.prepareBooleanFlag(
+ "UseRTMXendForLockBusy",
+ useXend),
+ "-XX:RTMRetryCount=0",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(inflateMonitor),
+ Integer.toString(TestUseRTMXendForLockBusy.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one rtm locking statistics entry for method "
+ + test.getMethodWithLockName());
+
+ long aborts = statistics.get(0).getAborts(AbortType.XABORT);
+
+ if (useXend) {
+ Asserts.assertEQ(aborts, 0L,
+ "Expected to get no aborts on busy lock");
+ } else {
+ Asserts.assertGT(aborts, 0L,
+ "Expected to get at least one abort on busy lock");
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMXendForLockBusy().test();
+ }
+}
diff --git a/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java b/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java
new file mode 100644
index 000000000..46c9482dc
--- /dev/null
+++ b/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that NoRTMLockEliding option could be applied to
+ * specified method and that such method will not use rtm.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestNoRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestNoRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>NoRTMLockElidingOption</i>
+ * will not use RTM-based lock elision.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * does not contain RTM locking statistics for compiled method.
+ */
+public class TestNoRTMLockElidingOption extends CommandLineOptionTest {
+ private TestNoRTMLockElidingOption() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyOption(false);
+ verifyOption(true);
+ }
+
+ public void verifyOption(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+ String methodOption = String.format("-XX:CompileCommand=option," +
+ "%s,NoRTMLockEliding", provoker.getMethodWithLockName());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ methodOption,
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+UseRTMDeopt",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 0,
+ "No deoptimizations with rtm_state_change reason are expected");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 0,
+ "VM output should not contain RTM locking statistics entries "
+ + "for method " + provoker.getMethodWithLockName());
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestNoRTMLockElidingOption().test();
+ }
+}
diff --git a/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java b/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java
new file mode 100644
index 000000000..701cf8d06
--- /dev/null
+++ b/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMLockEliding option could be applied to
+ * specified method and that such method will not be deoptimized
+ * on high abort ratio.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>UseRTMLockElidingOption</i>
+ * will use RTM-based lock elision, but will be never deoptimized with
+ * <i>rtm_state_change reason</i>.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * contains RTM locking statistics for compiled method and that total locks
+ * count equals to method's invocations.
+ * Since last assert is pretty strict, test uses -XX:RTMRetryCount=0 in order
+ * to avoid issue with retriable aborts described in
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMLockElidingOption extends CommandLineOptionTest {
+ private TestUseRTMLockElidingOption() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyOption(false);
+ verifyOption(true);
+ }
+
+ public void verifyOption(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+ String methodOption = String.format("-XX:CompileCommand=option," +
+ "%s,UseRTMLockEliding", provoker.getMethodWithLockName());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ methodOption,
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+UseRTMDeopt",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ provoker.getClass().getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 0,
+ "Method deoptimization with rtm_state_change is unexpected");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one RTM locking "
+ + "statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Expected to get total locks count equal to total amount of "
+ + "lock attempts.");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockElidingOption().test();
+ }
+}
diff --git a/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java b/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java
new file mode 100644
index 000000000..eebaac23b
--- /dev/null
+++ b/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, Oracle and/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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking statistics contain proper information
+ * on overall aborts and locks count and count of aborts of
+ * different types. Test also verify that VM output does not
+ * contain rtm locking statistics when it should not.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatistics
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestPrintPreciseRTMLockingStatistics
+ */
+
+import java.util.*;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that VM output does not contain RTM locking statistics when it
+ * should not (when PrintPreciseRTMLockingStatistics is off) and that with
+ * -XX:+PrintPreciseRTMLockingStatistics locking statistics contains sane
+ * total locks and aborts count as well as for specific abort types.
+ */
+public class TestPrintPreciseRTMLockingStatistics
+ extends CommandLineOptionTest {
+ private TestPrintPreciseRTMLockingStatistics() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyNoStatistics();
+ verifyStatistics();
+ }
+
+ // verify that VM output does not contain
+ // rtm locking statistics
+ private void verifyNoStatistics() throws Throwable {
+ verifyNoStatistics(AbortType.XABORT);
+
+ verifyNoStatistics(AbortType.XABORT,
+ "-XX:-PrintPreciseRTMLockingStatistics");
+
+ verifyNoStatistics(AbortType.XABORT, "-XX:-UseRTMLocking",
+ "-XX:+PrintPreciseRTMLockingStatistics");
+ }
+
+ // verify that rtm locking statistics contain information
+ // about each type of aborts
+ private void verifyStatistics() throws Throwable {
+ verifyAbortsCount(AbortType.XABORT);
+ verifyAbortsCount(AbortType.MEM_CONFLICT);
+ verifyAbortsCount(AbortType.BUF_OVERFLOW);
+ verifyAbortsCount(AbortType.NESTED_ABORT);
+ }
+
+ private void verifyNoStatistics(AbortType abortProvokerType,
+ String... vmOpts) throws Throwable {
+ AbortProvoker provoker = abortProvokerType.provoker();
+ List<String> finalVMOpts = new LinkedList<>();
+ Collections.addAll(finalVMOpts, vmOpts);
+ Collections.addAll(finalVMOpts, AbortProvoker.class.getName(),
+ abortProvokerType.toString());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(provoker,
+ finalVMOpts.toArray(new String[finalVMOpts.size()]));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 0, "VM output should not contain "
+ + "any RTM locking statistics");
+ }
+
+ private void verifyAbortsCount(AbortType abortType) throws Throwable {
+ AbortProvoker provoker = abortType.provoker();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ abortType.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(),outputAnalyzer.getOutput());
+
+ Asserts.assertGT(statistics.size(), 0, "VM output should contain one "
+ + "rtm locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics "
+ + "should contain non zero total locks count");
+
+ Asserts.assertGT(lock.getTotalAborts(), 0L,
+ "RTM locking statistics should contain non zero total aborts "
+ + "count");
+
+ Asserts.assertGT(lock.getAborts(abortType), 0L, String.format(
+ "RTM locking statistics should contain non zero aborts count "
+ + "for abort reason %s", abortType));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestPrintPreciseRTMLockingStatistics().test();
+ }
+}