Skip to content

Commit 51d7169

Browse files
tabjyrwestrel
authored andcommitted
8320237: C2: late inlining of method handle invoke causes duplicate lines in PrintInlining output
Reviewed-by: roland, kvn, thartmann
1 parent fd89b33 commit 51d7169

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed

src/hotspot/share/opto/callGenerator.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ void CallGenerator::do_late_inline_helper() {
684684
C->print_inlining_update_delayed(this);
685685
return;
686686
}
687+
if (C->print_inlining() && (is_mh_late_inline() || is_virtual_late_inline())) {
688+
C->print_inlining_update_delayed(this);
689+
}
687690

688691
// Setup default node notes to be picked up by the inlining
689692
Node_Notes* old_nn = C->node_notes_at(call->_idx);
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Copyright (c) 2023, Red Hat 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 8320237
27+
* @summary late inlining output shouldn't produce both failure and success messages
28+
* @library /test/lib
29+
* @requires vm.compiler2.enabled
30+
* @run driver compiler.inlining.TestDuplicatedLateInliningOutput
31+
*/
32+
33+
package compiler.inlining;
34+
35+
import java.lang.invoke.MethodHandle;
36+
import java.lang.invoke.MethodHandles;
37+
import java.lang.invoke.MethodType;
38+
import java.util.List;
39+
import java.util.stream.IntStream;
40+
41+
import jdk.test.lib.process.OutputAnalyzer;
42+
import jdk.test.lib.process.ProcessTools;
43+
44+
public class TestDuplicatedLateInliningOutput {
45+
public static void main(String[] args) throws Exception {
46+
test(
47+
NonConstantReceiverLauncher.class,
48+
"@ (\\d+)\\s+java\\.lang\\.invoke\\.LambdaForm\\$DMH\\/0x[0-9a-f]+::invokeStatic \\(\\d+ bytes\\)\\s+force inline by annotation",
49+
"@ (\\d+)\\s+java\\.lang\\.invoke\\.MethodHandle::invokeBasic\\(\\)V \\(\\d+ bytes\\)\\s+failed to inline: receiver not constant");
50+
51+
test(
52+
VirtualCallLauncher.class,
53+
"@ (\\d+)\\s+compiler\\.inlining\\.TestDuplicatedLateInliningOutput\\$VirtualCallLauncher\\$B::lateInlined2 \\(\\d+ bytes\\)\\s+inline \\(hot\\)",
54+
"@ (\\d+)\\s+compiler\\.inlining\\.TestDuplicatedLateInliningOutput\\$VirtualCallLauncher\\$A::lateInlined2 \\(\\d+ bytes\\)\\s+failed to inline: virtual call"
55+
);
56+
}
57+
58+
private static void test(Class<?> launcher, String pattern1, String pattern2) throws Exception {
59+
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
60+
"-XX:+UnlockDiagnosticVMOptions",
61+
"-XX:+PrintInlining",
62+
"-XX:CICompilerCount=1",
63+
"-XX:-TieredCompilation",
64+
"-XX:-BackgroundCompilation",
65+
launcher.getName());
66+
67+
OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
68+
69+
analyzer.shouldHaveExitValue(0);
70+
71+
analyzer.outputTo(System.out);
72+
analyzer.errorTo(System.err);
73+
74+
List<String> lines = analyzer.asLines();
75+
int index = IntStream.range(0, lines.size())
76+
.filter(i -> lines.get(i).trim().matches(pattern1))
77+
.findFirst()
78+
.orElseThrow(() -> new Exception("No inlining found"));
79+
80+
if (lines.get(index - 1).trim().matches(pattern2)) {
81+
throw new Exception("Both failure and success message found");
82+
}
83+
}
84+
85+
static class NonConstantReceiverLauncher {
86+
static final MethodHandle mh1;
87+
static MethodHandle mh2;
88+
89+
static {
90+
try {
91+
MethodHandles.Lookup lookup = MethodHandles.lookup();
92+
mh1 = lookup.findStatic(NonConstantReceiverLauncher.class, "lateInlined", MethodType.methodType(void.class));
93+
mh2 = mh1;
94+
} catch (NoSuchMethodException | IllegalAccessException e) {
95+
e.printStackTrace();
96+
throw new RuntimeException("Method handle lookup failed");
97+
}
98+
}
99+
100+
public static void main(String[] args) throws Throwable {
101+
for (int i = 0; i < 20_000; i++) {
102+
test(true);
103+
inlined(false);
104+
}
105+
}
106+
107+
private static void lateInlined() {
108+
// noop
109+
}
110+
111+
private static void test(boolean flag) throws Throwable {
112+
MethodHandle mh = null;
113+
if (flag) {
114+
mh = inlined(flag);
115+
}
116+
mh.invokeExact();
117+
}
118+
119+
private static MethodHandle inlined(boolean flag) {
120+
if (flag) {
121+
return mh1;
122+
}
123+
return mh2;
124+
}
125+
}
126+
127+
static class VirtualCallLauncher {
128+
static final A obj1 = new B();
129+
static final A obj2 = new C();
130+
static final A obj3 = new D();
131+
132+
public static void main(String[] args) throws Throwable {
133+
for (int i = 0; i < 20_000; i++) {
134+
test2(true);
135+
inlined2(false);
136+
inlined3(obj1);
137+
inlined3(obj2);
138+
inlined3(obj3);
139+
}
140+
}
141+
142+
private static void test2(boolean flag) {
143+
A a = null;
144+
if (flag) {
145+
a = inlined2(flag);
146+
}
147+
inlined3(a);
148+
}
149+
150+
private static A inlined2(boolean flag) {
151+
if (flag) {
152+
return obj1;
153+
}
154+
return obj2;
155+
}
156+
157+
private static void inlined3(A a) {
158+
a.lateInlined2();
159+
}
160+
161+
private static abstract class A {
162+
abstract void lateInlined2();
163+
}
164+
165+
private static class B extends A {
166+
@Override
167+
void lateInlined2() {
168+
// noop
169+
}
170+
}
171+
172+
private static class C extends A {
173+
@Override
174+
void lateInlined2() {
175+
// noop
176+
}
177+
}
178+
179+
private static class D extends A {
180+
@Override
181+
void lateInlined2() {
182+
// noop
183+
}
184+
}
185+
}
186+
}

0 commit comments

Comments
 (0)