Skip to content

Commit 7350b3f

Browse files
committed
8312909: C1 should not inline through interface calls with non-subtype receiver
Backport-of: ab1c212ac1097ae6e1122ef1aba47ca51eca11f2
1 parent 515387d commit 7350b3f

File tree

3 files changed

+109
-4
lines changed

3 files changed

+109
-4
lines changed

src/hotspot/share/c1/c1_GraphBuilder.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,9 +2087,10 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
20872087
assert(singleton != declared_interface, "not a unique implementor");
20882088
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
20892089
if (cha_monomorphic_target != nullptr) {
2090-
if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
2091-
ciInstanceKlass* holder = cha_monomorphic_target->holder();
2092-
ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
2090+
ciInstanceKlass* holder = cha_monomorphic_target->holder();
2091+
ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
2092+
if (holder != compilation()->env()->Object_klass() &&
2093+
(!type_is_exact || receiver_klass->is_subtype_of(constraint))) {
20932094
actual_recv = declared_interface;
20942095

20952096
// insert a check it's really the expected class.
@@ -2102,7 +2103,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
21022103

21032104
dependency_recorder()->assert_unique_implementor(declared_interface, singleton);
21042105
} else {
2105-
cha_monomorphic_target = nullptr; // subtype check against Object is useless
2106+
cha_monomorphic_target = nullptr;
21062107
}
21072108
}
21082109
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2023, 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 8312909
27+
* @summary Test monomorphic interface call to with invalid receiver.
28+
* @modules java.base/jdk.internal.vm.annotation
29+
* @compile TestInvokeinterfaceWithBadReceiverHelper.jasm
30+
* @run main/bootclasspath/othervm -XX:CompileCommand=compileonly,TestInvokeinterfaceWithBadReceiverHelper::test
31+
* -Xcomp -XX:TieredStopAtLevel=1 TestInvokeinterfaceWithBadReceiver
32+
*/
33+
34+
import jdk.internal.vm.annotation.Stable;
35+
36+
interface MyInterface {
37+
public String get();
38+
}
39+
40+
// Single implementor
41+
class MyClass implements MyInterface {
42+
@Stable
43+
String field = "42";
44+
45+
public String get() {
46+
return field;
47+
}
48+
}
49+
50+
public class TestInvokeinterfaceWithBadReceiver {
51+
52+
public static void main(String[] args) {
53+
try {
54+
TestInvokeinterfaceWithBadReceiverHelper.test(new MyClass());
55+
throw new RuntimeException("No IncompatibleClassChangeError thrown!");
56+
} catch (IncompatibleClassChangeError e) {
57+
// Expected
58+
}
59+
}
60+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2023, 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+
super public class TestInvokeinterfaceWithBadReceiverHelper
26+
version 51:0
27+
{
28+
public Method "<init>":"()V"
29+
stack 1 locals 1
30+
{
31+
aload_0;
32+
invokespecial Method java/lang/Object."<init>":"()V";
33+
return;
34+
}
35+
36+
public static Method test:"(LMyInterface;)Ljava/lang/String;"
37+
stack 1 locals 2
38+
{
39+
ldc String "42";
40+
invokeinterface InterfaceMethod MyInterface.get:"()Ljava/lang/String;", 1;
41+
areturn;
42+
}
43+
44+
} // end Class TestInvokeinterfaceWithBadReceiverHelper

0 commit comments

Comments
 (0)