1 /* 2 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @summary Tests that recursive locking doesn't cause excessive native memory usage 27 * @library /test/lib 28 * @build jdk.test.whitebox.WhiteBox 29 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 30 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 31 * -Xmx100M -XX:AsyncDeflationInterval=0 -XX:GuaranteedAsyncDeflationInterval=0 32 * -Xlog:monitorinflation=trace 33 * TestRecursiveMonitorChurn 34 */ 35 36 import jdk.test.whitebox.WhiteBox; 37 import jtreg.SkippedException; 38 39 public class TestRecursiveMonitorChurn { 40 static class Monitor { 41 public static volatile int i, j; 42 synchronized void doSomething() { 43 i++; 44 doSomethingElse(); 45 } 46 synchronized void doSomethingElse() { 47 j++; 48 } 49 } 50 51 static final WhiteBox WB = WhiteBox.getWhiteBox(); 52 static final int LM_MONITOR = 0; 53 static final int COUNT = 100000; 54 55 public static volatile Monitor monitor; 56 public static void main(String[] args) { 57 if (WB.getIntVMFlag("LockingMode") == LM_MONITOR) { 58 throw new SkippedException("LM_MONITOR always inflates. Invalid test."); 59 } 60 System.out.println("Starting test..."); 61 final long pre_monitor_count = WB.getInUseMonitorCount(); 62 System.out.println(" Precount = " + pre_monitor_count); 63 for (int i = 0; i < COUNT; i++) { 64 monitor = new Monitor(); 65 monitor.doSomething(); 66 } 67 System.out.println("i + j = " + (Monitor.i + Monitor.j)); 68 final long post_monitor_count = WB.getInUseMonitorCount(); 69 System.out.println("Postcount = " + post_monitor_count); 70 71 if (pre_monitor_count != post_monitor_count) { 72 final long monitor_count_change = post_monitor_count - pre_monitor_count; 73 System.out.println("Unexpected change in monitor count: " + monitor_count_change); 74 75 // Intermittent deflation and inflation may occur due to running the test 76 // with stress flags (like DeoptimizeALot) or with added instrumentation 77 // which runs in the same VM. 78 // An arbitrary fuzzy max difference of 10 (= 0.01% of COUNT) is chosen to 79 // allow for these occurrences to be skipped while still catching regressions. 80 final long fuzzy_max_difference = 10; 81 if (Math.abs(monitor_count_change) < fuzzy_max_difference) { 82 final String type = monitor_count_change < 0 ? "deflation" : "inflation"; 83 throw new SkippedException("Intermittent " + type + " detected. Invalid test."); 84 } 85 86 if (monitor_count_change < 0) { 87 throw new RuntimeException("Unexpected Deflation"); 88 } 89 throw new RuntimeException("Unexpected Inflation"); 90 } 91 } 92 }