Skip to content

Commit c8ad7b7

Browse files
committedDec 14, 2023
8321974: Crash in ciKlass::is_subtype_of because TypeAryPtr::_klass is not initialized
Reviewed-by: roland, kvn
1 parent cf94854 commit c8ad7b7

File tree

3 files changed

+67
-35
lines changed

3 files changed

+67
-35
lines changed
 

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

+12-34
Original file line numberDiff line numberDiff line change
@@ -4664,7 +4664,7 @@ template <class T1, class T2> bool TypePtr::is_meet_subtype_of_helper_for_array
46644664
}
46654665

46664666
if (other_elem == nullptr && this_elem == nullptr) {
4667-
return this_one->_klass->is_subtype_of(other->_klass);
4667+
return this_one->klass()->is_subtype_of(other->klass());
46684668
}
46694669

46704670
return false;
@@ -5993,7 +5993,7 @@ template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_instan
59935993
return true;
59945994
}
59955995

5996-
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces->contains(other->_interfaces);
5996+
return this_one->klass()->is_subtype_of(other->klass()) && this_one->_interfaces->contains(other->_interfaces);
59975997
}
59985998

59995999
bool TypeInstKlassPtr::is_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const {
@@ -6008,7 +6008,7 @@ template <class T1, class T2> bool TypePtr::is_same_java_type_as_helper_for_inst
60086008
if (!this_one->is_instance_type(other)) {
60096009
return false;
60106010
}
6011-
return this_one->_klass->equals(other->_klass) && this_one->_interfaces->eq(other->_interfaces);
6011+
return this_one->klass()->equals(other->klass()) && this_one->_interfaces->eq(other->_interfaces);
60126012
}
60136013

60146014
bool TypeInstKlassPtr::is_same_java_type_as_helper(const TypeKlassPtr* other) const {
@@ -6022,7 +6022,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_ins
60226022
}
60236023

60246024
if (this_one->is_array_type(other)) {
6025-
return !this_exact && this_one->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces->contains(this_one->_interfaces);
6025+
return !this_exact && this_one->klass()->equals(ciEnv::current()->Object_klass()) && other->_interfaces->contains(this_one->_interfaces);
60266026
}
60276027

60286028
assert(this_one->is_instance_type(other), "unsupported");
@@ -6031,12 +6031,12 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_ins
60316031
return this_one->is_java_subtype_of(other);
60326032
}
60336033

6034-
if (!this_one->_klass->is_subtype_of(other->_klass) && !other->_klass->is_subtype_of(this_one->_klass)) {
6034+
if (!this_one->klass()->is_subtype_of(other->klass()) && !other->klass()->is_subtype_of(this_one->klass())) {
60356035
return false;
60366036
}
60376037

60386038
if (this_exact) {
6039-
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces->contains(other->_interfaces);
6039+
return this_one->klass()->is_subtype_of(other->klass()) && this_one->_interfaces->contains(other->_interfaces);
60406040
}
60416041

60426042
return true;
@@ -6116,7 +6116,7 @@ uint TypeAryKlassPtr::hash(void) const {
61166116

61176117
//----------------------compute_klass------------------------------------------
61186118
// Compute the defining klass for this class
6119-
ciKlass* TypeAryPtr::compute_klass(DEBUG_ONLY(bool verify)) const {
6119+
ciKlass* TypeAryPtr::compute_klass() const {
61206120
// Compute _klass based on element type.
61216121
ciKlass* k_ary = nullptr;
61226122
const TypeInstPtr *tinst;
@@ -6137,28 +6137,7 @@ ciKlass* TypeAryPtr::compute_klass(DEBUG_ONLY(bool verify)) const {
61376137
// and object; Top occurs when doing join on Bottom.
61386138
// Leave k_ary at null.
61396139
} else {
6140-
// Cannot compute array klass directly from basic type,
6141-
// since subtypes of TypeInt all have basic type T_INT.
6142-
#ifdef ASSERT
6143-
if (verify && el->isa_int()) {
6144-
// Check simple cases when verifying klass.
6145-
BasicType bt = T_ILLEGAL;
6146-
if (el == TypeInt::BYTE) {
6147-
bt = T_BYTE;
6148-
} else if (el == TypeInt::SHORT) {
6149-
bt = T_SHORT;
6150-
} else if (el == TypeInt::CHAR) {
6151-
bt = T_CHAR;
6152-
} else if (el == TypeInt::INT) {
6153-
bt = T_INT;
6154-
} else {
6155-
return _klass; // just return specified klass
6156-
}
6157-
return ciTypeArrayKlass::make(bt);
6158-
}
6159-
#endif
6160-
assert(!el->isa_int(),
6161-
"integral arrays must be pre-equipped with a class");
6140+
assert(!el->isa_int(), "integral arrays must be pre-equipped with a class");
61626141
// Compute array klass directly from basic type
61636142
k_ary = ciTypeArrayKlass::make(el->basic_type());
61646143
}
@@ -6434,7 +6413,7 @@ template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_array(
64346413
return this_one->is_reference_type(this_elem)->is_java_subtype_of_helper(this_one->is_reference_type(other_elem), this_exact, other_exact);
64356414
}
64366415
if (this_elem == nullptr && other_elem == nullptr) {
6437-
return this_one->_klass->is_subtype_of(other->_klass);
6416+
return this_one->klass()->is_subtype_of(other->klass());
64386417
}
64396418
return false;
64406419
}
@@ -6466,8 +6445,7 @@ template <class T1, class T2> bool TypePtr::is_same_java_type_as_helper_for_arra
64666445
return this_one->is_reference_type(this_elem)->is_same_java_type_as(this_one->is_reference_type(other_elem));
64676446
}
64686447
if (other_elem == nullptr && this_elem == nullptr) {
6469-
assert(this_one->_klass != nullptr && other->_klass != nullptr, "");
6470-
return this_one->_klass->equals(other->_klass);
6448+
return this_one->klass()->equals(other->klass());
64716449
}
64726450
return false;
64736451
}
@@ -6487,7 +6465,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_arr
64876465
return true;
64886466
}
64896467
if (this_one->is_instance_type(other)) {
6490-
return other->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces->intersection_with(this_one->_interfaces)->eq(other->_interfaces);
6468+
return other->klass()->equals(ciEnv::current()->Object_klass()) && other->_interfaces->intersection_with(this_one->_interfaces)->eq(other->_interfaces);
64916469
}
64926470
assert(this_one->is_array_type(other), "");
64936471

@@ -6506,7 +6484,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_arr
65066484
return this_one->is_reference_type(this_elem)->maybe_java_subtype_of_helper(this_one->is_reference_type(other_elem), this_exact, other_exact);
65076485
}
65086486
if (other_elem == nullptr && this_elem == nullptr) {
6509-
return this_one->_klass->is_subtype_of(other->_klass);
6487+
return this_one->klass()->is_subtype_of(other->klass());
65106488
}
65116489
return false;
65126490
}

‎src/hotspot/share/opto/type.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ class TypeAryPtr : public TypeOopPtr {
14131413
const TypeAry *_ary; // Array we point into
14141414
const bool _is_autobox_cache;
14151415

1416-
ciKlass* compute_klass(DEBUG_ONLY(bool verify = false)) const;
1416+
ciKlass* compute_klass() const;
14171417

14181418
// A pointer to delay allocation to Type::Initialize_shared()
14191419

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
/*
27+
* @test
28+
* @bug 8321974
29+
* @summary Test that the TypeAryPtr::_klass field is properly initialized on use.
30+
* @comment This test only reproduces the issue with release builds of the JVM because
31+
* verification code in debug builds leads to eager initialization of the field.
32+
* @run main/othervm -Xbatch -XX:CompileCommand=compileonly,TestUninitializedKlassField::test*
33+
* -XX:-TieredCompilation TestUninitializedKlassField
34+
*/
35+
36+
public class TestUninitializedKlassField {
37+
static void test(long array2[]) {
38+
long array1[] = new long[1];
39+
// Loop is needed to create a backedge phi that is processed only during IGVN.
40+
for (int i = 0; i < 1; i++) {
41+
// CmpPNode::sub will check if classes of array1 and array2 are unrelated
42+
// and the subtype checks will crash if the _klass field is not initialized.
43+
if (array2 != array1) {
44+
array1 = new long[2];
45+
}
46+
}
47+
}
48+
49+
public static void main(String[] args) {
50+
for (int i = 0; i < 50_000; ++i) {
51+
test(null);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)
Failed to load comments.