--- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/PeakUsageTest.java 2014-12-04 21:15:00.140585446 +0300 @@ -0,0 +1,87 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test PeakUsageTest + * @library /testlibrary /testlibrary/whitebox + * @build PeakUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache PeakUsageTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache PeakUsageTest + * @summary testing of getPeakUsage() and resetPeakUsage for + * segmented code cache + */ +public class PeakUsageTest { + + private final BlobType btype; + + public PeakUsageTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new PeakUsageTest(btype).runTest(); + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + bean.resetPeakUsage(); + long addr = CodeCacheUtils.allocateDefaultSize(btype); + long newPeakUsage = bean.getPeakUsage().getUsed(); + try { + Asserts.assertEQ(newPeakUsage, bean.getUsage().getUsed(), + "Peak usage does not match usage after allocation for " + + bean.getName()); + } finally { + CodeCacheUtils.WB.freeCodeBlob(addr); + } + Asserts.assertEQ(newPeakUsage, bean.getPeakUsage().getUsed(), + "Code cache peak usage has changed after usage decreased for " + + bean.getName()); + bean.resetPeakUsage(); + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after reset for " + + bean.getName()); + long addr2 = CodeCacheUtils.allocateDefaultSize(btype); + try { + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after fresh " + + "allocation for " + bean.getName()); + } finally { + CodeCacheUtils.WB.freeCodeBlob(addr2); + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java 2014-12-04 21:15:00.220585443 +0300 @@ -0,0 +1,107 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.ArrayList; +import java.util.List; +import sun.hotspot.code.BlobType; + +/* + * @test InitialAndMaxUsageTest + * @library /testlibrary /testlibrary/whitebox + * @build InitialAndMaxUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * InitialAndMaxUsageTest + * @summary testing of initial and max usage + */ +public class InitialAndMaxUsageTest { + + private static final double CACHE_USAGE_COEF = 0.95d; + private final BlobType btype; + private final boolean lowerBoundIsZero; + private final long maxSize; + + public InitialAndMaxUsageTest(BlobType btype) { + this.btype = btype; + this.maxSize = btype.getSize(); + /* Only profiled code cache initial size should be 0, because of + -XX:CompileCommand=compileonly,null::* non-methods might be not empty, + as well as non-profiled methods, because it's used as fallback in + case non-methods is full */ + lowerBoundIsZero = btype == BlobType.MethodProfiled; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new InitialAndMaxUsageTest(btype).runTest(); + } + } + + private void fillWithSize(long size, List blobs) { + long blob; + while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) + != 0L) { + blobs.add(blob); + } + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialUsage = btype.getMemoryPool().getUsage().getUsed(); + System.out.printf("INFO: trying to test %s of max size %d and initial" + + " usage %d%n", bean.getName(), maxSize, initialUsage); + Asserts.assertLT(initialUsage + headerSize + 1L, maxSize, + "Initial usage is close to total size for " + bean.getName()); + if (lowerBoundIsZero) { + Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage"); + } + ArrayList blobs = new ArrayList<>(); + long minAllocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + /* now filling code cache with large-sized allocation first, since + lots of small allocations takes too much time, so, just a small + optimization */ + try { + for (int coef = 1000000; coef > 0; coef /= 10) { + fillWithSize(coef * minAllocationUnit, blobs); + } + Asserts.assertGT((double) bean.getUsage().getUsed(), + CACHE_USAGE_COEF * maxSize, String.format("Unable to fill " + + "more than %f of %s. Reported usage is %d ", + CACHE_USAGE_COEF, bean.getName(), + bean.getUsage().getUsed())); + } finally { + for (long entry : blobs) { + CodeCacheUtils.WB.freeCodeBlob(entry); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } + +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/GetUsageTest.java 2014-12-04 21:15:00.232585443 +0300 @@ -0,0 +1,103 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import sun.hotspot.code.BlobType; + +/* + * @test GetUsageTest + * @library /testlibrary /testlibrary/whitebox + * @build GetUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:CompileCommand=compileonly,null::* + * -XX:-UseCodeCacheFlushing -XX:-MethodFlushing -XX:+SegmentedCodeCache + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI GetUsageTest + * @summary testing of getUsage() for segmented code cache + */ +public class GetUsageTest { + + private final BlobType btype; + private final int allocateSize; + + public GetUsageTest(BlobType btype, int allocSize) { + this.btype = btype; + this.allocateSize = allocSize; + } + + 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(); + } + } + } + } + + protected final Map getBeanUsages() { + Map beanUsages = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + beanUsages.put(bt.getMemoryPool(), + bt.getMemoryPool().getUsage().getUsed()); + } + return beanUsages; + } + + protected void runTest() { + MemoryPoolMXBean[] predictableBeans = BlobType.getAvailable().stream() + .filter(CodeCacheUtils::isCodeHeapPredictable) + .map(BlobType::getMemoryPool) + .toArray(MemoryPoolMXBean[]::new); + CodeCacheUtils.WB.deoptimizeAll(); + Map initial = getBeanUsages(); + CodeCacheUtils.WB.allocateCodeBlob(allocateSize, btype.id); + Map current = getBeanUsages(); + long blockCount = Math.floorDiv(allocateSize + + CodeCacheUtils.getHeaderSize(btype) + + CodeCacheUtils.SEGMENT_SIZE - 1, CodeCacheUtils.SEGMENT_SIZE); + long usageUpperEstimate = Math.max(blockCount, + CodeCacheUtils.MIN_BLOCK_LENGTH) * CodeCacheUtils.SEGMENT_SIZE; + 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)); + } else { + Asserts.assertEQ(diff, 0L, + String.format("Pool %s usage changed unexpectedly while" + + " trying to increase: %s using allocation " + + "size %d", entry.getName(), + btype.getMemoryPool().getName(), allocateSize)); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + btype.getMemoryPool().getName()); + } +} --- old/test/testlibrary/com/oracle/java/testlibrary/Utils.java 2014-12-04 21:15:00.768585423 +0300 +++ new/test/testlibrary/com/oracle/java/testlibrary/Utils.java 2014-12-04 21:15:00.444585435 +0300 @@ -37,6 +37,7 @@ import java.util.Collections; import java.util.List; import java.util.Random; +import java.util.function.BooleanSupplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import sun.misc.Unsafe; @@ -88,6 +89,13 @@ TIMEOUT_FACTOR = Double.parseDouble(toFactor); } + /** + * Returns the value of 'test.iterations.count' system property + * converted to {@code int}. + */ + public static final int ITERATIONS_COUNT = + Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + private Utils() { // Private constructor to prevent class instantiation } @@ -367,4 +375,31 @@ } return RANDOM_GENERATOR; } + + /** + * Wait for condition to be true + * + * @param condition, a condition to wait for, using default sleep time 100 + */ + public static final void waitForCondition(BooleanSupplier condition) { + waitForCondition(condition, 100); + } + + /** + * Wait until timeout for condition to be true + * + * @param condition, a condition to wait for + * @param sleepTime a time to sleep value in milliseconds + */ + public static final void waitForCondition(BooleanSupplier condition, + long sleepTime) { + while (!condition.getAsBoolean()) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + } } --- old/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java 2014-12-04 21:15:00.884585418 +0300 +++ new/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java 2014-12-04 21:15:00.392585437 +0300 @@ -32,11 +32,11 @@ public enum BlobType { // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) - MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), + MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'", "NonProfiledCodeHeapSize"), // Execution level 2 and 3 (profiled) nmethods - MethodProfiled(1, "CodeHeap 'profiled nmethods'"), + MethodProfiled(1, "CodeHeap 'profiled nmethods'", "ProfiledCodeHeapSize"), // Non-nmethods like Buffers, Adapters and Runtime Stubs - NonNMethod(2, "CodeHeap 'non-nmethods'") { + NonNMethod(2, "CodeHeap 'non-nmethods'", "NonNMethodCodeHeapSize") { @Override public boolean allowTypeWhenOverflow(BlobType type) { return super.allowTypeWhenOverflow(type) @@ -44,14 +44,16 @@ } }, // All types (No code cache segmentation) - All(3, "CodeCache"); + All(3, "CodeCache", "ReservedCodeCacheSize"); public final int id; - private final String beanName; + public final String sizeOptionName; + public final String beanName; - private BlobType(int id, String beanName) { + private BlobType(int id, String beanName, String sizeOptionName) { this.id = id; this.beanName = beanName; + this.sizeOptionName = sizeOptionName; } public MemoryPoolMXBean getMemoryPool() { @@ -87,4 +89,8 @@ } return result; } + + public long getSize() { + return WhiteBox.getWhiteBox().getUintxVMFlag(sizeOptionName); + } } --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java 2014-12-04 21:15:00.428585435 +0300 @@ -0,0 +1,55 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.util.EnumSet; +import sun.hotspot.code.BlobType; + +/** + * @test CodeHeapBeanPresenceTest + * @library /testlibrary /testlibrary/whitebox + * @build CodeHeapBeanPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache CodeHeapBeanPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache CodeHeapBeanPresenceTest + * @summary verify CodeHeap bean presence + */ +public class CodeHeapBeanPresenceTest { + + public static void main(String args[]) { + EnumSet shouldBeAvailable = BlobType.getAvailable(); + EnumSet shouldNotBeAvailable + = EnumSet.complementOf(shouldBeAvailable); + for (BlobType btype : shouldBeAvailable) { + Asserts.assertNotNull(btype.getMemoryPool(), + "Can't find memory pool for " + btype.name()); + } + for (BlobType btype : shouldNotBeAvailable) { + Asserts.assertNull(btype.getMemoryPool(), + "Memory pool unexpected for " + btype.name()); + } + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/PoolsIndependenceTest.java 2014-12-04 21:15:00.720585424 +0300 @@ -0,0 +1,131 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test PoolsIndependenceTest + * @library /testlibrary /testlibrary/whitebox + * @build PoolsIndependenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache PoolsIndependenceTest + * @summary testing of getUsageThreashold() + */ +public class PoolsIndependenceTest implements NotificationListener { + + private final Map counters; + private final BlobType btype; + private volatile long lastEventTimestamp; + + public PoolsIndependenceTest(BlobType btype) { + counters = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + counters.put(bt.getMemoryPool().getName(), new AtomicInteger(0)); + } + this.btype = btype; + lastEventTimestamp = 0; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new PoolsIndependenceTest(bt).runTest(); + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + bean.setUsageThreshold(bean.getUsage().getUsed() + 1); + long beginTimestamp = System.currentTimeMillis(); + CodeCacheUtils.allocateDefaultSize(btype); + CodeCacheUtils.WB.fullGC(); + /* waiting for expected event to be recieved plus double the time took + to recieve expected event(for possible unexpected) and + plus 1 second in case expected event recieved (almost)immediately */ + Utils.waitForCondition(() -> { + long currentTimestamp = System.currentTimeMillis(); + int eventsCount + = counters.get(btype.getMemoryPool().getName()).get(); + if (eventsCount > 0) { + if (eventsCount > 1) { + return true; + } + long timeLastEventTook + = beginTimestamp - lastEventTimestamp; + long timeoutValue + = 1000L + beginTimestamp + 3L * timeLastEventTook; + return currentTimestamp > timeoutValue; + } + return false; + }); + for (BlobType bt : BlobType.getAvailable()) { + 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())); + } + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario with %s finished%n", bean.getName()); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + // receiving events from available CodeCache-related beans only + if (counters.get(poolName) != null) { + counters.get(poolName).incrementAndGet(); + lastEventTimestamp = System.currentTimeMillis(); + } + } + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/ThresholdNotificationsTest.java 2014-12-04 21:15:00.916585417 +0300 @@ -0,0 +1,97 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import java.util.concurrent.atomic.AtomicInteger; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test ThresholdNotificationsTest + * @library /testlibrary /testlibrary/whitebox + * @build ThresholdNotificationsTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * ThresholdNotificationsTest + * @summary testing of getUsageThreashold() + */ +public class ThresholdNotificationsTest implements NotificationListener { + + private volatile long counter; + private final BlobType btype; + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new ThresholdNotificationsTest(bt).runTest(); + } + } + + public ThresholdNotificationsTest(BlobType btype) { + this.btype = btype; + counter = 0L; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + if (poolName.equals(btype.getMemoryPool().getName())) { + counter++; + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + for (int i = 0; i < Utils.ITERATIONS_COUNT; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Utils.waitForCondition(() -> counter == Utils.ITERATIONS_COUNT); + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/BeanTypeTest.java 2014-12-04 21:15:00.932585416 +0300 @@ -0,0 +1,47 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryType; +import sun.hotspot.code.BlobType; + +/** + * @test BeanTypeTest + * @library /testlibrary /testlibrary/whitebox + * @build BeanTypeTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache BeanTypeTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache BeanTypeTest + * @summary verify types of code cache memory pool bean + */ +public class BeanTypeTest { + + public static void main(String args[]) { + for (BlobType bt : BlobType.getAvailable()) { + Asserts.assertEQ(MemoryType.NON_HEAP, bt.getMemoryPool().getType()); + } + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java 2014-12-04 21:15:00.808585421 +0300 @@ -0,0 +1,78 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryManagerMXBean; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import sun.hotspot.code.BlobType; + +/** + * @test MemoryPoolsPresenceTest + * @library /testlibrary /testlibrary/whitebox + * @build MemoryPoolsPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache MemoryPoolsPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache MemoryPoolsPresenceTest + * @summary verify that MemoryManagerMXBean exists for every code cache segment + */ +public class MemoryPoolsPresenceTest { + + private static final String CC_MANAGER = "CodeCacheManager"; + private final Map counters = new HashMap<>(); + + public static void main(String args[]) { + new MemoryPoolsPresenceTest().runTest(); + } + + protected void runTest() { + List beans + = ManagementFactory.getMemoryManagerMXBeans(); + Optional any = beans + .stream() + .filter(bean -> CC_MANAGER.equals(bean.getName())) + .findAny(); + Asserts.assertTrue(any.isPresent(), "Bean not found: " + CC_MANAGER); + MemoryManagerMXBean ccManager = any.get(); + Asserts.assertNotNull(ccManager, "Found null for " + CC_MANAGER); + String names[] = ccManager.getMemoryPoolNames(); + for (String name : names) { + counters.put(name, counters.containsKey(name) + ? counters.get(name) + 1 : 1); + } + for (BlobType btype : BlobType.getAvailable()) { + Asserts.assertEQ(counters.get(btype.getMemoryPool().getName()), 1, + "Found unexpected amount of beans for pool " + + btype.getMemoryPool().getName()); + } + Asserts.assertEQ(BlobType.getAvailable().size(), + counters.keySet().size(), "Unexpected amount of bean names"); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/CodeCacheUtils.java 2014-12-04 21:15:00.940585416 +0300 @@ -0,0 +1,105 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Utils; +import java.lang.management.MemoryPoolMXBean; +import javax.management.Notification; +import sun.hotspot.WhiteBox; +import sun.hotspot.code.BlobType; +import sun.hotspot.code.CodeBlob; + +public final class CodeCacheUtils { + + /** + * Returns the value to be used for code heap allocation + */ + public static final int ALLOCATION_SIZE + = Integer.getInteger("codecache.allocation.size", 100); + public static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static final long SEGMENT_SIZE + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheSegmentSize"); + public static final long MIN_BLOCK_LENGTH + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheMinBlockLength"); + public static final long MIN_ALLOCATION = SEGMENT_SIZE * MIN_BLOCK_LENGTH; + + private CodeCacheUtils() { + // To prevent from instantiation + } + + public static final void hitUsageThreshold(MemoryPoolMXBean bean, + BlobType btype) { + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + 1); + long usageThresholdCount = bean.getUsageThresholdCount(); + long addr = WB.allocateCodeBlob(1, btype.id); + WB.fullGC(); + Utils.waitForCondition(() + -> bean.getUsageThresholdCount() == usageThresholdCount + 1); + WB.freeCodeBlob(addr); + } + + public static long allocateDefaultSize(BlobType btype) { + return WB.allocateCodeBlob(ALLOCATION_SIZE, btype.id); + } + + public static final long getHeaderSize(BlobType btype) { + long addr = WB.allocateCodeBlob(0, btype.id); + int size = CodeBlob.getCodeBlob(addr).size; + WB.freeCodeBlob(addr); + return size; + } + + public static String getPoolNameFromNotification( + Notification notification) { + return ((javax.management.openmbean.CompositeDataSupport) + notification.getUserData()).get("poolName").toString(); + } + + public static boolean isAvailableCodeHeapPoolName(String name) { + return BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .map(MemoryPoolMXBean::getName) + .filter(name::equals) + .findAny().isPresent(); + } + + /** + * 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'. + * + * @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; + } + + public static void disableCollectionUsageThresholds(){ + BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .filter(MemoryPoolMXBean::isCollectionUsageThresholdSupported) + .forEach(b -> b.setCollectionUsageThreshold(0L)); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/ManagerNamesTest.java 2014-12-04 21:15:01.056585412 +0300 @@ -0,0 +1,64 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/** + * @test ManagerNamesTest + * @library /testlibrary /testlibrary/whitebox + * @build ManagerNamesTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache ManagerNamesTest + * * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache ManagerNamesTest + * @summary verify getMemoryManageNames calls in case on segmented code cache + */ +public class ManagerNamesTest { + + private final MemoryPoolMXBean bean; + private final static String POOL_NAME = "CodeCacheManager"; + + public static void main(String args[]) { + for (BlobType btype : BlobType.getAvailable()) { + new ManagerNamesTest(btype).runTest(); + } + } + + public ManagerNamesTest(BlobType btype) { + bean = btype.getMemoryPool(); + } + + protected void runTest() { + String[] names = bean.getMemoryManagerNames(); + Asserts.assertEQ(names.length, 1, + "Unexpected length of MemoryManagerNames"); + Asserts.assertEQ(POOL_NAME, names[0], + "Unexpected value of MemoryManagerName"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/UsageThresholdExceededTest.java 2014-12-04 21:15:01.636585390 +0300 @@ -0,0 +1,71 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdExceededTest + * @library /testlibrary /testlibrary/whitebox + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit + */ +public class UsageThresholdExceededTest { + + protected final int iterations; + private final BlobType btype; + + public UsageThresholdExceededTest(BlobType btype, int iterations) { + this.btype = btype; + this.iterations = iterations; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdExceededTest(btype, Utils.ITERATIONS_COUNT) + .runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long oldValue = bean.getUsageThresholdCount(); + for (int i = 0; i < iterations; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Asserts.assertEQ(bean.getUsageThresholdCount(), oldValue + iterations, + "Unexpected threshold usage count"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java 2014-12-04 21:15:01.660585389 +0300 @@ -0,0 +1,75 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdNotExceededTest + * @library /testlibrary /testlibrary/whitebox + * @build UsageThresholdNotExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * UsageThresholdNotExceededTest + * @summary verifying that usage threshold not exceeded while allocating less + * than usage threshold + */ +public class UsageThresholdNotExceededTest { + + private final BlobType btype; + + public UsageThresholdNotExceededTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdNotExceededTest(btype).runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialThresholdCount = bean.getUsageThresholdCount(); + long initialUsage = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialUsage + 1 + + CodeCacheUtils.SEGMENT_SIZE * CodeCacheUtils.MIN_BLOCK_LENGTH); + CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.SEGMENT_SIZE * CodeCacheUtils.MIN_BLOCK_LENGTH + - CodeCacheUtils.getHeaderSize(btype), btype.id); + CodeCacheUtils.WB.fullGC(); + Asserts.assertEQ(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()); + } +} --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java 2014-12-04 21:15:01.696585387 +0300 @@ -0,0 +1,36 @@ +/* + * 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 UsageThresholdExceededSeveralTimesTest + * @library /testlibrary /testlibrary/whitebox + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * -Dcom.oracle.java.testlibrary.iterations=10 UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit several times + */ --- /dev/null 2014-12-02 13:47:03.829845816 +0300 +++ new/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java 2014-12-04 21:15:01.752585385 +0300 @@ -0,0 +1,87 @@ +/* + * 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. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdIncreasedTest + * @library /testlibrary /testlibrary/whitebox + * @build UsageThresholdIncreasedTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* UsageThresholdIncreasedTest + * @summary verifying that threshold hasn't been hit after allocationg smaller + * than threshold value and that threshold value can be changed + */ +public class UsageThresholdIncreasedTest { + + private static final int ALLOCATION_STEP = 5; + private static final long THRESHOLD_STEP = ALLOCATION_STEP + * CodeCacheUtils.MIN_ALLOCATION; + private final BlobType btype; + + public UsageThresholdIncreasedTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new UsageThresholdIncreasedTest(btype).runTest(); + } + } + + private void checkUsageThresholdCount(MemoryPoolMXBean bean, long count){ + Asserts.assertEQ(bean.getUsageThresholdCount(), count, + 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())); + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + long allocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialCount = bean.getUsageThresholdCount(); + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + // Usage threshold check is triggered by GC cycle, so, call it + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + long filledSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(filledSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + System.out.println("INFO: Case finished successfully for " + bean.getName()); + } +}