1 /* 2 * Copyright (c) 2024, Oracle and/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 /* 26 * @test TestLockStackCapacity 27 * @summary Tests the interaction between recursive lightweight locking and 28 * when the lock stack capacity is exceeded. 29 * @requires vm.flagless 30 * @library /testlibrary /test/lib 31 * @build jdk.test.whitebox.WhiteBox 32 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 33 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xint -XX:LockingMode=2 TestLockStackCapacity 34 */ 35 36 import jdk.test.lib.Asserts; 37 import jdk.test.whitebox.WhiteBox; 38 import jtreg.SkippedException; 39 40 public class TestLockStackCapacity { 41 static final WhiteBox WB = WhiteBox.getWhiteBox(); 42 static final int LockingMode = WB.getIntVMFlag("LockingMode").intValue(); 43 static final int LM_LIGHTWEIGHT = 2; 44 45 static class SynchronizedObject { 46 static final SynchronizedObject OUTER = new SynchronizedObject(); 47 static final SynchronizedObject INNER = new SynchronizedObject(); 48 static final int LockStackCapacity = WB.getLockStackCapacity(); 49 50 synchronized void runInner(int depth) { 51 assertNotInflated(); 52 if (depth == 1) { 53 return; 54 } else { 55 runInner(depth - 1); 56 } 57 assertNotInflated(); 58 } 59 60 synchronized void runOuter(int depth, SynchronizedObject inner) { 61 assertNotInflated(); 62 if (depth == 1) { 63 inner.runInner(LockStackCapacity); 64 } else { 65 runOuter(depth - 1, inner); 66 } 67 assertInflated(); 68 } 69 70 public static void runTest() { 71 // Test Requires a capacity of at least 2. 72 Asserts.assertGTE(LockStackCapacity, 2); 73 74 // Just checking 75 OUTER.assertNotInflated(); 76 INNER.assertNotInflated(); 77 78 synchronized(OUTER) { 79 OUTER.assertNotInflated(); 80 INNER.assertNotInflated(); 81 OUTER.runOuter(LockStackCapacity - 1, INNER); 82 83 OUTER.assertInflated(); 84 INNER.assertNotInflated(); 85 } 86 } 87 88 void assertNotInflated() { 89 Asserts.assertFalse(WB.isMonitorInflated(this)); 90 } 91 92 void assertInflated() { 93 Asserts.assertTrue(WB.isMonitorInflated(this)); 94 } 95 } 96 97 public static void main(String... args) throws Exception { 98 if (LockingMode != LM_LIGHTWEIGHT) { 99 throw new SkippedException("Test only valid for LM_LIGHTWEIGHT"); 100 } 101 102 if (!WB.supportsRecursiveLightweightLocking()) { 103 throw new SkippedException("Test only valid if LM_LIGHTWEIGHT supports recursion"); 104 } 105 106 SynchronizedObject.runTest(); 107 } 108 }