changeset 8623:8835879bc34a

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
author thartmann
date Wed, 01 Jul 2015 09:07:10 +0200
parents 02ef8543e20f
children f7b19ca15ef8
files test/compiler/codecache/jmx/CodeCacheUtils.java test/compiler/codecache/jmx/GetUsageTest.java test/compiler/codecache/jmx/PeakUsageTest.java test/compiler/codecache/jmx/PoolsIndependenceTest.java test/compiler/codecache/jmx/ThresholdNotificationsTest.java test/compiler/codecache/jmx/UsageThresholdExceededTest.java test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java
diffstat 8 files changed, 64 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/test/compiler/codecache/jmx/CodeCacheUtils.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/GetUsageTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/PeakUsageTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/PoolsIndependenceTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/ThresholdNotificationsTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/UsageThresholdExceededTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java	Fri Jun 26 19:11:15 2015 -0700
+++ b/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());
     }
 }