1 /* 2 * Copyright (c) 2021, 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 * @test 26 * @bug 8275868 27 * @library / /test/lib 28 * @summary Testing that ciReplay inlining does not fail with unresolved signature classes. 29 * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.compMode != "Xcomp" & vm.debug == true & vm.compiler2.enabled 30 * @modules java.base/jdk.internal.misc 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:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 34 * compiler.ciReplay.TestInliningProtectionDomain 35 */ 36 37 package compiler.ciReplay; 38 39 import jdk.test.lib.Asserts; 40 41 import java.util.List; 42 43 public class TestInliningProtectionDomain extends InliningBase { 44 45 public static void main(String[] args) { 46 new TestInliningProtectionDomain(ProtectionDomainTestCompiledBefore.class, true); 47 new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPublic.class, false); 48 // TODO Re-enable this once 8284443 fixed handling of unloaded return types 49 // new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPrivate.class, false); 50 new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPrivateString.class, false); 51 } 52 53 public TestInliningProtectionDomain(Class<?> testClass, boolean compileBar) { 54 super(testClass); 55 if (compileBar) { 56 commandLineNormal.add("-XX:CompileCommand=compileonly," + testClass.getName() + "::bar"); 57 } 58 runTest(); 59 } 60 61 @Override 62 public void testAction() { 63 positiveTest(commandLineReplay); 64 String entryString = getTestClass() + " " + "test"; 65 boolean inlineFails = testClass == ProtectionDomainTestNoOtherCompilationPrivate.class; 66 int inlineeCount = inlineFails ? 1 : 5; 67 68 List<InlineEntry> inlineesNormal = parseLogFile(LOG_FILE_NORMAL, entryString, "compile_id='" + getCompileIdFromFile(getReplayFileName()) + "'", inlineeCount); 69 List<InlineEntry> inlineesReplay = parseLogFile(LOG_FILE_REPLAY, entryString, "test ()V", inlineeCount); 70 verifyLists(inlineesNormal, inlineesReplay, inlineeCount); 71 72 if (inlineFails) { 73 Asserts.assertTrue(inlineesNormal.get(0).compare("compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", "bar", inlineesNormal.get(0).isUnloadedSignatureClasses())); 74 Asserts.assertTrue(inlineesReplay.get(0).compare("compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", "bar", inlineesReplay.get(0).isDisallowedByReplay())); 75 } else { 76 Asserts.assertTrue(inlineesNormal.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesNormal.get(4).isNormalInline())); 77 Asserts.assertTrue(inlineesReplay.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesReplay.get(4).isForcedByReplay() || inlineesReplay.get(4).isForcedIncrementalInlineByReplay())); 78 } 79 } 80 } 81 82 class ProtectionDomainTestCompiledBefore { 83 public static void main(String[] args) { 84 for (int i = 0; i < 10000; i++) { 85 bar(); // Ensure that bar() was compiled 86 } 87 for (int i = 0; i < 10000; i++) { 88 test(); 89 } 90 } 91 92 public static void test() { 93 bar(); 94 } 95 96 // Integer should be resolved for the protection domain of this class because the separate compilation of bar() in 97 // the normal run will resolve all classes in the signature. Inlining succeeds. 98 private static Integer bar() { 99 InliningFoo.foo(); 100 return null; 101 } 102 } 103 104 class ProtectionDomainTestNoOtherCompilationPublic { 105 public static void main(String[] args) { 106 for (int i = 0; i < 10000; i++) { 107 test(); 108 } 109 } 110 111 public static void test() { 112 bar(); // Not compiled before separately 113 } 114 115 // Integer should be resolved for the protection domain of this class because getDeclaredMethods is called in normal run 116 // when validating main() method. In this process, all public methods of this class are visited and its signature classes 117 // are resolved. Inlining of bar() succeeds. 118 public static Integer bar() { 119 InliningFoo.foo(); 120 return null; 121 } 122 } 123 124 class ProtectionDomainTestNoOtherCompilationPrivate { 125 public static void main(String[] args) { 126 for (int i = 0; i < 10000; i++) { 127 test(); 128 } 129 } 130 131 public static void test() { 132 bar(); // Not compiled before separately 133 } 134 135 // Integer should be unresolved for the protection domain of this class even though getDeclaredMethods is called in normal 136 // run when validating main() method. In this process, only public methods of this class are visited and its signature 137 // classes are resolved. Since this method is private, the signature classes are not resolved for this protection domain. 138 // Inlining of bar() should fail in normal run with "unresolved signature classes". Therefore, replay compilation should 139 // also not inline bar(). 140 private static Integer bar() { 141 InliningFoo.foo(); 142 return null; 143 } 144 } 145 146 class ProtectionDomainTestNoOtherCompilationPrivateString { 147 public static void main(String[] args) { 148 for (int i = 0; i < 10000; i++) { 149 test(); 150 } 151 } 152 153 public static void test() { 154 bar(); // Not compiled before separately 155 } 156 157 // Integer should be resovled for the protection domain of this class because getDeclaredMethods is called in normal run 158 // when validating main() method. In this process, public methods of this class are visited and its signature classes 159 // are resolved. bar() is private and not visited in this process (i.e. no resolution of String). But since main() 160 // has String[] as parameter, the String class will be resolved for this protection domain. Inlining of bar() succeeds. 161 private static String bar() { 162 InliningFoo.foo(); 163 return null; 164 } 165 } 166 167 class InliningFoo { 168 public static void foo() { 169 foo2(); 170 } 171 172 private static void foo2() { 173 InliningBar.bar(); 174 } 175 } 176 177 178 class InliningBar { 179 public static void bar() { 180 bar2(); 181 } 182 183 private static void bar2() {} 184 }