Skip to content

Commit a1d566c

Browse files
marc-chevalierTobiHartmann
authored andcommitted
8348853: Fold layout helper check for objects implementing non-array interfaces
Reviewed-by: thartmann, roland
1 parent f7fa05f commit a1d566c

File tree

5 files changed

+27
-11
lines changed

5 files changed

+27
-11
lines changed

src/hotspot/share/ci/ciMetadata.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class ciMetadata: public ciBaseObject {
103103

104104
Metadata* constant_encoding() { return _metadata; }
105105

106-
bool equals(ciMetadata* obj) const { return (this == obj); }
106+
bool equals(const ciMetadata* obj) const { return (this == obj); }
107107

108108
uint hash() { return ident() * 31; } // ???
109109

src/hotspot/share/opto/library_call.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4305,12 +4305,7 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region,
43054305
if (obj != nullptr && is_array_ctrl != nullptr && is_array_ctrl != top()) {
43064306
// Keep track of the fact that 'obj' is an array to prevent
43074307
// array specific accesses from floating above the guard.
4308-
Node* cast = _gvn.transform(new CastPPNode(is_array_ctrl, *obj, TypeAryPtr::BOTTOM));
4309-
// Check for top because in rare cases, the type system can determine that
4310-
// the object can't be an array but the layout helper check is not folded.
4311-
if (!cast->is_top()) {
4312-
*obj = cast;
4313-
}
4308+
*obj = _gvn.transform(new CastPPNode(is_array_ctrl, *obj, TypeAryPtr::BOTTOM));
43144309
}
43154310
return ctrl;
43164311
}

src/hotspot/share/opto/memnode.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,10 +2218,8 @@ const Type* LoadNode::Value(PhaseGVN* phase) const {
22182218
// This will help short-circuit some reflective code.
22192219
if (tkls->offset() == in_bytes(Klass::layout_helper_offset()) &&
22202220
tkls->isa_instklassptr() && // not directly typed as an array
2221-
!tkls->is_instklassptr()->instance_klass()->is_java_lang_Object() // not the supertype of all T[] and specifically not Serializable & Cloneable
2222-
) {
2223-
// Note: When interfaces are reliable, we can narrow the interface
2224-
// test to (klass != Serializable && klass != Cloneable).
2221+
!tkls->is_instklassptr()->might_be_an_array() // not the supertype of all T[] (java.lang.Object) or has an interface that is not Serializable or Cloneable
2222+
) {
22252223
assert(Opcode() == Op_LoadI, "must load an int from _layout_helper");
22262224
jint min_size = Klass::instance_layout_helper(oopDesc::header_size(), false);
22272225
// The key property of this type is that it folds up tests

src/hotspot/share/opto/type.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,6 +3685,12 @@ bool TypeInterfaces::singleton(void) const {
36853685
return Type::singleton();
36863686
}
36873687

3688+
bool TypeInterfaces::has_non_array_interface() const {
3689+
assert(TypeAryPtr::_array_interfaces != nullptr, "How come Type::Initialize_shared wasn't called yet?");
3690+
3691+
return !TypeAryPtr::_array_interfaces->contains(this);
3692+
}
3693+
36883694
//------------------------------TypeOopPtr-------------------------------------
36893695
TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int offset,
36903696
int instance_id, const TypePtr* speculative, int inline_depth)
@@ -6197,6 +6203,19 @@ template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_instan
61976203
return this_one->klass()->is_subtype_of(other->klass()) && this_one->_interfaces->contains(other->_interfaces);
61986204
}
61996205

6206+
bool TypeInstKlassPtr::might_be_an_array() const {
6207+
if (!instance_klass()->is_java_lang_Object()) {
6208+
// TypeInstKlassPtr can be an array only if it is java.lang.Object: the only supertype of array types.
6209+
return false;
6210+
}
6211+
if (interfaces()->has_non_array_interface()) {
6212+
// Arrays only implement Cloneable and Serializable. If we see any other interface, [this] cannot be an array.
6213+
return false;
6214+
}
6215+
// Cannot prove it's not an array.
6216+
return true;
6217+
}
6218+
62006219
bool TypeInstKlassPtr::is_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const {
62016220
return TypePtr::is_java_subtype_of_helper_for_instance(this, other, this_exact, other_exact);
62026221
}

src/hotspot/share/opto/type.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ class TypeInterfaces : public Type {
943943
const Type* xmeet(const Type* t) const;
944944

945945
bool singleton(void) const;
946+
bool has_non_array_interface() const;
946947
};
947948

948949
//------------------------------TypePtr----------------------------------------
@@ -1420,6 +1421,7 @@ class TypeInstPtr : public TypeOopPtr {
14201421
class TypeAryPtr : public TypeOopPtr {
14211422
friend class Type;
14221423
friend class TypePtr;
1424+
friend class TypeInterfaces;
14231425

14241426
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
14251427
int offset, int instance_id, bool is_autobox_cache,
@@ -1692,6 +1694,8 @@ class TypeInstKlassPtr : public TypeKlassPtr {
16921694
return klass()->as_instance_klass();
16931695
}
16941696

1697+
bool might_be_an_array() const;
1698+
16951699
bool is_same_java_type_as_helper(const TypeKlassPtr* other) const;
16961700
bool is_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const;
16971701
bool maybe_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const;

0 commit comments

Comments
 (0)