8129937: compiler/codecache/jmx/UsageThresholdIncreasedTest.java fails with "Usage threshold was hit"
Summary: Tests should not assume that usage of non-profiled code heap is predictable.
Reviewed-by: kvn, dpochepk
--- a/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java Wed Jul 01 09:07:10 2015 +0200
@@ -21,6 +21,7 @@
* questions.
*/
+import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import java.lang.management.MemoryPoolMXBean;
import javax.management.Notification;
@@ -80,19 +81,42 @@
}
/**
- * A "non-nmethods" code heap is used by interpreter during bytecode
- * execution, thus, it can't be predicted if this code heap usage will be
- * increased or not. Same goes for 'All'.
+ * Checks if the usage of the code heap corresponding to 'btype' can be
+ * predicted at runtime if we disable compilation. The usage of the
+ * 'NonNMethod' code heap can not be predicted because we generate adapters
+ * and buffers at runtime. The 'MethodNonProfiled' code heap is also not
+ * predictable because we may generate compiled versions of method handle
+ * intrinsics while resolving methods at runtime. Same applies to 'All'.
*
* @param btype BlobType to be checked
* @return boolean value, true if respective code heap is predictable
*/
public static boolean isCodeHeapPredictable(BlobType btype) {
- return btype == BlobType.MethodNonProfiled
- || btype == BlobType.MethodProfiled;
+ return btype == BlobType.MethodProfiled;
}
- public static void disableCollectionUsageThresholds(){
+ /**
+ * Verifies that 'newValue' is equal to 'oldValue' if usage of the
+ * corresponding code heap is predictable. Checks the weaker condition
+ * 'newValue >= oldValue' if usage is not predictable because intermediate
+ * allocations may happen.
+ *
+ * @param btype BlobType of the code heap to be checked
+ * @param newValue New value to be verified
+ * @param oldValue Old value to be verified
+ * @param msg Error message if verification fails
+ */
+ public static void assertEQorGTE(BlobType btype, long newValue, long oldValue, String msg) {
+ if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
+ // Usage is predictable, check strong == condition
+ Asserts.assertEQ(newValue, oldValue, msg);
+ } else {
+ // Usage is not predictable, check weaker >= condition
+ Asserts.assertGTE(newValue, oldValue, msg);
+ }
+ }
+
+ public static void disableCollectionUsageThresholds() {
BlobType.getAvailable().stream()
.map(BlobType::getMemoryPool)
.filter(MemoryPoolMXBean::isCollectionUsageThresholdSupported)
--- a/hotspot/test/compiler/codecache/jmx/GetUsageTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -52,10 +52,8 @@
public static void main(String[] args) throws Exception {
for (BlobType btype : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
- for (int allocSize = 10; allocSize < 100000; allocSize *= 10) {
- new GetUsageTest(btype, allocSize).runTest();
- }
+ for (int allocSize = 10; allocSize < 100000; allocSize *= 10) {
+ new GetUsageTest(btype, allocSize).runTest();
}
}
}
@@ -87,13 +85,15 @@
for (MemoryPoolMXBean entry : predictableBeans) {
long diff = current.get(entry) - initial.get(entry);
if (entry.equals(btype.getMemoryPool())) {
- Asserts.assertFalse(diff <= 0L || diff > usageUpperEstimate,
- String.format("Pool %s usage increase was reported "
- + "unexpectedly as increased by %d using "
- + "allocation size %d", entry.getName(),
- diff, allocateSize));
+ if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
+ Asserts.assertFalse(diff <= 0L || diff > usageUpperEstimate,
+ String.format("Pool %s usage increase was reported "
+ + "unexpectedly as increased by %d using "
+ + "allocation size %d", entry.getName(),
+ diff, allocateSize));
+ }
} else {
- Asserts.assertEQ(diff, 0L,
+ CodeCacheUtils.assertEQorGTE(btype, diff, 0L,
String.format("Pool %s usage changed unexpectedly while"
+ " trying to increase: %s using allocation "
+ "size %d", entry.getName(),
--- a/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -52,9 +52,7 @@
public static void main(String[] args) {
for (BlobType btype : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
- new PeakUsageTest(btype).runTest();
- }
+ new PeakUsageTest(btype).runTest();
}
}
@@ -65,7 +63,7 @@
CodeCacheUtils.ALLOCATION_SIZE, btype.id);
long newPeakUsage = bean.getPeakUsage().getUsed();
try {
- Asserts.assertEQ(newPeakUsage, bean.getUsage().getUsed(),
+ CodeCacheUtils.assertEQorGTE(btype, newPeakUsage, bean.getUsage().getUsed(),
"Peak usage does not match usage after allocation for "
+ bean.getName());
} finally {
@@ -73,18 +71,18 @@
CodeCacheUtils.WB.freeCodeBlob(addr);
}
}
- Asserts.assertEQ(newPeakUsage, bean.getPeakUsage().getUsed(),
+ CodeCacheUtils.assertEQorGTE(btype, newPeakUsage, bean.getPeakUsage().getUsed(),
"Code cache peak usage has changed after usage decreased for "
+ bean.getName());
bean.resetPeakUsage();
- Asserts.assertEQ(bean.getPeakUsage().getUsed(),
+ CodeCacheUtils.assertEQorGTE(btype, bean.getPeakUsage().getUsed(),
bean.getUsage().getUsed(),
"Code cache peak usage is not equal to usage after reset for "
+ bean.getName());
long addr2 = CodeCacheUtils.WB.allocateCodeBlob(
CodeCacheUtils.ALLOCATION_SIZE, btype.id);
try {
- Asserts.assertEQ(bean.getPeakUsage().getUsed(),
+ CodeCacheUtils.assertEQorGTE(btype, bean.getPeakUsage().getUsed(),
bean.getUsage().getUsed(),
"Code cache peak usage is not equal to usage after fresh "
+ "allocation for " + bean.getName());
--- a/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -97,13 +97,11 @@
return false;
});
for (BlobType bt : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
- int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
- Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(),
- expectedNotificationsAmount, String.format("Unexpected "
- + "amount of notifications for pool: %s",
- bt.getMemoryPool().getName()));
- }
+ int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
+ CodeCacheUtils.assertEQorGTE(btype, counters.get(bt.getMemoryPool().getName()).get(),
+ expectedNotificationsAmount, String.format("Unexpected "
+ + "amount of notifications for pool: %s",
+ bt.getMemoryPool().getName()));
}
try {
((NotificationEmitter) ManagementFactory.getMemoryMXBean()).
--- a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -54,9 +54,7 @@
public static void main(String[] args) {
for (BlobType bt : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
- new ThresholdNotificationsTest(bt).runTest();
- }
+ new ThresholdNotificationsTest(bt).runTest();
}
}
@@ -92,7 +90,9 @@
}
Asserts.assertTrue(
Utils.waitForCondition(
- () -> counter == iterationsCount, WAIT_TIME),
+ () -> (CodeCacheUtils.isCodeHeapPredictable(btype) ?
+ (counter == iterationsCount) : (counter >= iterationsCount)),
+ WAIT_TIME),
"Couldn't receive expected notifications count");
try {
((NotificationEmitter) ManagementFactory.getMemoryMXBean()).
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -51,13 +51,9 @@
}
public static void main(String[] args) {
- int iterationsCount =
- Integer.getInteger("jdk.test.lib.iterations", 1);
+ int iterationsCount = Integer.getInteger("jdk.test.lib.iterations", 1);
for (BlobType btype : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
- new UsageThresholdExceededTest(btype, iterationsCount)
- .runTest();
- }
+ new UsageThresholdExceededTest(btype, iterationsCount).runTest();
}
}
@@ -67,9 +63,8 @@
for (int i = 0; i < iterations; i++) {
CodeCacheUtils.hitUsageThreshold(bean, btype);
}
- Asserts.assertEQ(bean.getUsageThresholdCount(), oldValue + iterations,
+ CodeCacheUtils.assertEQorGTE(btype, bean.getUsageThresholdCount(), oldValue + iterations,
"Unexpected threshold usage count");
- System.out.printf("INFO: Scenario finished successfully for %s%n",
- bean.getName());
+ System.out.printf("INFO: Scenario finished successfully for %s%n", bean.getName());
}
}
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -27,7 +27,6 @@
/*
* @test UsageThresholdIncreasedTest
- * @ignore 8129937
* @library /testlibrary /../../test/lib
* @modules java.base/sun.misc
* java.management
@@ -54,14 +53,12 @@
public static void main(String[] args) {
for (BlobType btype : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
- new UsageThresholdIncreasedTest(btype).runTest();
- }
+ new UsageThresholdIncreasedTest(btype).runTest();
}
}
private void checkUsageThresholdCount(MemoryPoolMXBean bean, long count){
- Asserts.assertEQ(bean.getUsageThresholdCount(), count,
+ CodeCacheUtils.assertEQorGTE(btype, bean.getUsageThresholdCount(), count,
String.format("Usage threshold was hit: %d times for %s "
+ "Threshold value: %d with current usage: %d",
bean.getUsageThresholdCount(), bean.getName(),
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java Fri Jun 26 19:11:15 2015 -0700
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java Wed Jul 01 09:07:10 2015 +0200
@@ -50,9 +50,7 @@
public static void main(String[] args) {
for (BlobType btype : BlobType.getAvailable()) {
- if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
- new UsageThresholdNotExceededTest(btype).runTest();
- }
+ new UsageThresholdNotExceededTest(btype).runTest();
}
}
@@ -65,13 +63,11 @@
- CodeCacheUtils.getHeaderSize(btype), btype.id);
// a gc cycle triggers usage threshold recalculation
CodeCacheUtils.WB.fullGC();
- Asserts.assertEQ(bean.getUsageThresholdCount(), initialThresholdCount,
- String.format("Usage threshold was hit: %d times for %s. "
+ CodeCacheUtils.assertEQorGTE(btype, bean.getUsageThresholdCount(), initialThresholdCount,
+ String.format("Usage threshold was hit: %d times for %s. "
+ "Threshold value: %d with current usage: %d",
bean.getUsageThresholdCount(), bean.getName(),
bean.getUsageThreshold(), bean.getUsage().getUsed()));
-
- System.out.println("INFO: Case finished successfully for "
- + bean.getName());
+ System.out.println("INFO: Case finished successfully for " + bean.getName());
}
}