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 }
--- EOF ---