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