Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit 129c377

Browse files
committedDec 3, 2020
8257594: C2 compiled checkcast of non-null object triggers endless deoptimization/recompilation cycle
Reviewed-by: roland, vlivanov
1 parent e4497c9 commit 129c377

File tree

4 files changed

+133
-2
lines changed

4 files changed

+133
-2
lines changed
 

‎src/hotspot/share/opto/graphKit.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -3311,7 +3311,13 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
33113311
case Compile::SSC_always_false:
33123312
// It needs a null check because a null will *pass* the cast check.
33133313
// A non-null value will always produce an exception.
3314-
return null_assert(obj);
3314+
if (!objtp->maybe_null()) {
3315+
builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(objtp->klass())));
3316+
return top();
3317+
} else if (!too_many_traps_or_recompiles(Deoptimization::Reason_null_assert)) {
3318+
return null_assert(obj);
3319+
}
3320+
break; // Fall through to full check
33153321
}
33163322
}
33173323
}

‎src/hotspot/share/opto/parse2.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ void Parse::array_store(BasicType bt) {
8383
if (stopped()) return; // guaranteed null or range check
8484
if (bt == T_OBJECT) {
8585
array_store_check();
86+
if (stopped()) {
87+
return;
88+
}
8689
}
8790
Node* val; // Oop to store
8891
if (big_val) {

‎src/hotspot/share/opto/parseHelper.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ void Parse::do_checkcast() {
8989
return;
9090
}
9191

92-
Node *res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)) );
92+
Node* res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)));
93+
if (stopped()) {
94+
return;
95+
}
9396

9497
// Pop from stack AFTER gen_checkcast because it can uncommon trap and
9598
// the debug info has to be correct.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) 2020, 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 8257594
27+
* @summary Test that failing checkcast does not trigger repeated recompilation until cutoff is hit.
28+
* @requires vm.compiler2.enabled
29+
* @modules java.base/jdk.internal.misc
30+
* @library /test/lib
31+
* @build sun.hotspot.WhiteBox
32+
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
33+
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
34+
* -Xbatch -XX:CompileCommand=dontinline,compiler.uncommontrap.TestNullAssertAtCheckCast::test*
35+
* -XX:CompileCommand=inline,compiler.uncommontrap.TestNullAssertAtCheckCast::cast
36+
* -XX:CompileCommand=inline,compiler.uncommontrap.TestNullAssertAtCheckCast::store
37+
* compiler.uncommontrap.TestNullAssertAtCheckCast
38+
*/
39+
40+
package compiler.uncommontrap;
41+
42+
import sun.hotspot.WhiteBox;
43+
44+
import java.lang.reflect.Method;
45+
46+
public class TestNullAssertAtCheckCast {
47+
private static final WhiteBox WB = WhiteBox.getWhiteBox();
48+
private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
49+
50+
static Long cast(Object val) {
51+
return (Long)val;
52+
}
53+
54+
static void test1() {
55+
try {
56+
// Always fails
57+
cast(new Integer(42));
58+
} catch (ClassCastException cce) {
59+
// Ignored
60+
}
61+
}
62+
63+
static void test2(Integer val) {
64+
try {
65+
// Always fails
66+
cast(val);
67+
} catch (ClassCastException cce) {
68+
// Ignored
69+
}
70+
}
71+
72+
static void store(Object[] array, Object val) {
73+
array[0] = val;
74+
}
75+
76+
static void test3() {
77+
try {
78+
// Always fails
79+
store(new Long[1], new Integer(42));
80+
} catch (ArrayStoreException cce) {
81+
// Ignored
82+
}
83+
}
84+
85+
static void test4(Integer val) {
86+
try {
87+
// Always fails
88+
store(new Long[1], val);
89+
} catch (ArrayStoreException cce) {
90+
// Ignored
91+
}
92+
}
93+
94+
public static void main(String[] args) throws Exception {
95+
for (int i = 0; i < 1_000_000; ++i) {
96+
test1();
97+
test2((i % 2 == 0) ? null : 42);
98+
test3();
99+
test4((i % 2 == 0) ? null : 42);
100+
}
101+
Method method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test1");
102+
if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
103+
throw new RuntimeException("TestNullAssertAtCheckCast::test1 not compilable");
104+
}
105+
method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test2", Integer.class);
106+
if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
107+
throw new RuntimeException("TestNullAssertAtCheckCast::test2 not compilable");
108+
}
109+
method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test3");
110+
if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
111+
throw new RuntimeException("TestNullAssertAtCheckCast::test3 not compilable");
112+
}
113+
method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test4", Integer.class);
114+
if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
115+
throw new RuntimeException("TestNullAssertAtCheckCast::test4 not compilable");
116+
}
117+
}
118+
}
119+

0 commit comments

Comments
 (0)
This repository has been archived.