8309203: C2: remove copy-by-value of GrowableArray for InterfaceSet

Reviewed-by: thartmann, kvn
This commit is contained in:
Roland Westrelin 2023-11-14 09:07:56 +00:00
parent b120a05b22
commit 21cda19d05
2 changed files with 242 additions and 220 deletions

View File

@ -62,6 +62,7 @@ const Type::TypeInfo Type::_type_info[Type::lastype] = {
{ Bad, T_NARROWKLASS,"narrowklass:", false, Op_RegN, relocInfo::none }, // NarrowKlass
{ Bad, T_ILLEGAL, "tuple:", false, Node::NotAMachineReg, relocInfo::none }, // Tuple
{ Bad, T_ARRAY, "array:", false, Node::NotAMachineReg, relocInfo::none }, // Array
{ Bad, T_ARRAY, "interfaces:", false, Node::NotAMachineReg, relocInfo::none }, // Interfaces
#if defined(PPC64)
{ Bad, T_ILLEGAL, "vectormask:", false, Op_RegVectMask, relocInfo::none }, // VectorMask.
@ -121,8 +122,8 @@ const Type* Type:: _zero_type[T_CONFLICT+1];
// Map basic types to array-body alias types.
const TypeAryPtr* TypeAryPtr::_array_body_type[T_CONFLICT+1];
const TypePtr::InterfaceSet* TypeAryPtr::_array_interfaces = nullptr;
const TypePtr::InterfaceSet* TypeAryKlassPtr::_array_interfaces = nullptr;
const TypeInterfaces* TypeAryPtr::_array_interfaces = nullptr;
const TypeInterfaces* TypeAryKlassPtr::_array_interfaces = nullptr;
//=============================================================================
// Convenience common pre-built types.
@ -572,7 +573,7 @@ void Type::Initialize_shared(Compile* current) {
GrowableArray<ciInstanceKlass*> array_interfaces;
array_interfaces.push(current->env()->Cloneable_klass());
array_interfaces.push(current->env()->Serializable_klass());
TypeAryPtr::_array_interfaces = new TypePtr::InterfaceSet(&array_interfaces);
TypeAryPtr::_array_interfaces = TypeInterfaces::make(&array_interfaces);
TypeAryKlassPtr::_array_interfaces = TypeAryPtr::_array_interfaces;
TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), nullptr /* current->env()->Object_klass() */, false, arrayOopDesc::length_offset_in_bytes());
@ -3253,14 +3254,14 @@ void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
// Convenience common pre-built type.
const TypeOopPtr *TypeOopPtr::BOTTOM;
TypePtr::InterfaceSet::InterfaceSet()
: _list(Compile::current()->type_arena(), 0, 0, nullptr),
TypeInterfaces::TypeInterfaces()
: Type(Interfaces), _list(Compile::current()->type_arena(), 0, 0, nullptr),
_hash(0), _exact_klass(nullptr) {
DEBUG_ONLY(_initialized = true);
}
TypePtr::InterfaceSet::InterfaceSet(GrowableArray<ciInstanceKlass*>* interfaces)
: _list(Compile::current()->type_arena(), interfaces->length(), 0, nullptr),
TypeInterfaces::TypeInterfaces(GrowableArray<ciInstanceKlass*>* interfaces)
: Type(Interfaces), _list(Compile::current()->type_arena(), interfaces->length(), 0, nullptr),
_hash(0), _exact_klass(nullptr) {
for (int i = 0; i < interfaces->length(); i++) {
add(interfaces->at(i));
@ -3268,13 +3269,18 @@ TypePtr::InterfaceSet::InterfaceSet(GrowableArray<ciInstanceKlass*>* interfaces)
initialize();
}
void TypePtr::InterfaceSet::initialize() {
const TypeInterfaces* TypeInterfaces::make(GrowableArray<ciInstanceKlass*>* interfaces) {
TypeInterfaces* result = (interfaces == nullptr) ? new TypeInterfaces() : new TypeInterfaces(interfaces);
return (const TypeInterfaces*)result->hashcons();
}
void TypeInterfaces::initialize() {
compute_hash();
compute_exact_klass();
DEBUG_ONLY(_initialized = true;)
}
int TypePtr::InterfaceSet::compare(ciKlass* const& k1, ciKlass* const& k2) {
int TypeInterfaces::compare(ciInstanceKlass* const& k1, ciInstanceKlass* const& k2) {
if ((intptr_t)k1 < (intptr_t)k2) {
return -1;
} else if ((intptr_t)k1 > (intptr_t)k2) {
@ -3283,24 +3289,20 @@ int TypePtr::InterfaceSet::compare(ciKlass* const& k1, ciKlass* const& k2) {
return 0;
}
void TypePtr::InterfaceSet::add(ciKlass* interface) {
void TypeInterfaces::add(ciInstanceKlass* interface) {
assert(interface->is_interface(), "for interfaces only");
_list.insert_sorted<compare>(interface);
verify();
}
void TypePtr::InterfaceSet::raw_add(ciKlass* interface) {
assert(interface->is_interface(), "for interfaces only");
_list.push(interface);
}
bool TypePtr::InterfaceSet::eq(const InterfaceSet& other) const {
if (_list.length() != other._list.length()) {
bool TypeInterfaces::eq(const Type* t) const {
const TypeInterfaces* other = (const TypeInterfaces*)t;
if (_list.length() != other->_list.length()) {
return false;
}
for (int i = 0; i < _list.length(); i++) {
ciKlass* k1 = _list.at(i);
ciKlass* k2 = other._list.at(i);
ciKlass* k2 = other->_list.at(i);
if (!k1->equals(k2)) {
return false;
}
@ -3308,15 +3310,15 @@ bool TypePtr::InterfaceSet::eq(const InterfaceSet& other) const {
return true;
}
bool TypePtr::InterfaceSet::eq(ciInstanceKlass* k) const {
bool TypeInterfaces::eq(ciInstanceKlass* k) const {
assert(k->is_loaded(), "should be loaded");
GrowableArray<ciInstanceKlass *>* interfaces = k->as_instance_klass()->transitive_interfaces();
GrowableArray<ciInstanceKlass *>* interfaces = k->transitive_interfaces();
if (_list.length() != interfaces->length()) {
return false;
}
for (int i = 0; i < interfaces->length(); i++) {
bool found = false;
_list.find_sorted<ciKlass*, compare>(interfaces->at(i), found);
_list.find_sorted<ciInstanceKlass*, compare>(interfaces->at(i), found);
if (!found) {
return false;
}
@ -3325,12 +3327,16 @@ bool TypePtr::InterfaceSet::eq(ciInstanceKlass* k) const {
}
uint TypePtr::InterfaceSet::hash() const {
uint TypeInterfaces::hash() const {
assert(_initialized, "must be");
return _hash;
}
void TypePtr::InterfaceSet::compute_hash() {
const Type* TypeInterfaces::xdual() const {
return this;
}
void TypeInterfaces::compute_hash() {
uint hash = 0;
for (int i = 0; i < _list.length(); i++) {
ciKlass* k = _list.at(i);
@ -3339,17 +3345,17 @@ void TypePtr::InterfaceSet::compute_hash() {
_hash = hash;
}
static int compare_interfaces(ciKlass** k1, ciKlass** k2) {
static int compare_interfaces(ciInstanceKlass** k1, ciInstanceKlass** k2) {
return (int)((*k1)->ident() - (*k2)->ident());
}
void TypePtr::InterfaceSet::dump(outputStream* st) const {
void TypeInterfaces::dump(outputStream* st) const {
if (_list.length() == 0) {
return;
}
ResourceMark rm;
st->print(" (");
GrowableArray<ciKlass*> interfaces;
GrowableArray<ciInstanceKlass*> interfaces;
interfaces.appendAll(&_list);
// Sort the interfaces so they are listed in the same order from one run to the other of the same compilation
interfaces.sort(compare_interfaces);
@ -3364,110 +3370,110 @@ void TypePtr::InterfaceSet::dump(outputStream* st) const {
}
#ifdef ASSERT
void TypePtr::InterfaceSet::verify() const {
void TypeInterfaces::verify() const {
for (int i = 1; i < _list.length(); i++) {
ciKlass* k1 = _list.at(i-1);
ciKlass* k2 = _list.at(i);
ciInstanceKlass* k1 = _list.at(i-1);
ciInstanceKlass* k2 = _list.at(i);
assert(compare(k2, k1) > 0, "should be ordered");
assert(k1 != k2, "no duplicate");
}
}
#endif
TypePtr::InterfaceSet TypeOopPtr::InterfaceSet::union_with(const InterfaceSet& other) const {
InterfaceSet result;
const TypeInterfaces* TypeInterfaces::union_with(const TypeInterfaces* other) const {
GrowableArray<ciInstanceKlass*> result_list;
int i = 0;
int j = 0;
while (i < _list.length() || j < other._list.length()) {
while (i < _list.length() || j < other->_list.length()) {
while (i < _list.length() &&
(j >= other._list.length() ||
compare(_list.at(i), other._list.at(j)) < 0)) {
result.raw_add(_list.at(i));
(j >= other->_list.length() ||
compare(_list.at(i), other->_list.at(j)) < 0)) {
result_list.push(_list.at(i));
i++;
}
while (j < other._list.length() &&
while (j < other->_list.length() &&
(i >= _list.length() ||
compare(other._list.at(j), _list.at(i)) < 0)) {
result.raw_add(other._list.at(j));
compare(other->_list.at(j), _list.at(i)) < 0)) {
result_list.push(other->_list.at(j));
j++;
}
if (i < _list.length() &&
j < other._list.length() &&
_list.at(i) == other._list.at(j)) {
result.raw_add(_list.at(i));
j < other->_list.length() &&
_list.at(i) == other->_list.at(j)) {
result_list.push(_list.at(i));
i++;
j++;
}
}
result.initialize();
const TypeInterfaces* result = TypeInterfaces::make(&result_list);
#ifdef ASSERT
result.verify();
result->verify();
for (int i = 0; i < _list.length(); i++) {
assert(result._list.contains(_list.at(i)), "missing");
assert(result->_list.contains(_list.at(i)), "missing");
}
for (int i = 0; i < other._list.length(); i++) {
assert(result._list.contains(other._list.at(i)), "missing");
for (int i = 0; i < other->_list.length(); i++) {
assert(result->_list.contains(other->_list.at(i)), "missing");
}
for (int i = 0; i < result._list.length(); i++) {
assert(_list.contains(result._list.at(i)) || other._list.contains(result._list.at(i)), "missing");
for (int i = 0; i < result->_list.length(); i++) {
assert(_list.contains(result->_list.at(i)) || other->_list.contains(result->_list.at(i)), "missing");
}
#endif
return result;
}
TypePtr::InterfaceSet TypeOopPtr::InterfaceSet::intersection_with(const InterfaceSet& other) const {
InterfaceSet result;
const TypeInterfaces* TypeInterfaces::intersection_with(const TypeInterfaces* other) const {
GrowableArray<ciInstanceKlass*> result_list;
int i = 0;
int j = 0;
while (i < _list.length() || j < other._list.length()) {
while (i < _list.length() || j < other->_list.length()) {
while (i < _list.length() &&
(j >= other._list.length() ||
compare(_list.at(i), other._list.at(j)) < 0)) {
(j >= other->_list.length() ||
compare(_list.at(i), other->_list.at(j)) < 0)) {
i++;
}
while (j < other._list.length() &&
while (j < other->_list.length() &&
(i >= _list.length() ||
compare(other._list.at(j), _list.at(i)) < 0)) {
compare(other->_list.at(j), _list.at(i)) < 0)) {
j++;
}
if (i < _list.length() &&
j < other._list.length() &&
_list.at(i) == other._list.at(j)) {
result.raw_add(_list.at(i));
j < other->_list.length() &&
_list.at(i) == other->_list.at(j)) {
result_list.push(_list.at(i));
i++;
j++;
}
}
result.initialize();
const TypeInterfaces* result = TypeInterfaces::make(&result_list);
#ifdef ASSERT
result.verify();
result->verify();
for (int i = 0; i < _list.length(); i++) {
assert(!other._list.contains(_list.at(i)) || result._list.contains(_list.at(i)), "missing");
assert(!other->_list.contains(_list.at(i)) || result->_list.contains(_list.at(i)), "missing");
}
for (int i = 0; i < other._list.length(); i++) {
assert(!_list.contains(other._list.at(i)) || result._list.contains(other._list.at(i)), "missing");
for (int i = 0; i < other->_list.length(); i++) {
assert(!_list.contains(other->_list.at(i)) || result->_list.contains(other->_list.at(i)), "missing");
}
for (int i = 0; i < result._list.length(); i++) {
assert(_list.contains(result._list.at(i)) && other._list.contains(result._list.at(i)), "missing");
for (int i = 0; i < result->_list.length(); i++) {
assert(_list.contains(result->_list.at(i)) && other->_list.contains(result->_list.at(i)), "missing");
}
#endif
return result;
}
// Is there a single ciKlass* that can represent the interface set?
ciKlass* TypePtr::InterfaceSet::exact_klass() const {
ciInstanceKlass* TypeInterfaces::exact_klass() const {
assert(_initialized, "must be");
return _exact_klass;
}
void TypePtr::InterfaceSet::compute_exact_klass() {
void TypeInterfaces::compute_exact_klass() {
if (_list.length() == 0) {
_exact_klass = nullptr;
return;
}
ciKlass* res = nullptr;
ciInstanceKlass* res = nullptr;
for (int i = 0; i < _list.length(); i++) {
ciInstanceKlass* interface = _list.at(i)->as_instance_klass();
ciInstanceKlass* interface = _list.at(i);
if (eq(interface)) {
assert(res == nullptr, "");
res = interface;
@ -3477,7 +3483,7 @@ void TypePtr::InterfaceSet::compute_exact_klass() {
}
#ifdef ASSERT
void TypePtr::InterfaceSet::verify_is_loaded() const {
void TypeInterfaces::verify_is_loaded() const {
for (int i = 0; i < _list.length(); i++) {
ciKlass* interface = _list.at(i);
assert(interface->is_loaded(), "Interface not loaded");
@ -3485,8 +3491,19 @@ void TypePtr::InterfaceSet::verify_is_loaded() const {
}
#endif
// Can't be implemented because there's no way to know if the type is above or below the center line.
const Type* TypeInterfaces::xmeet(const Type* t) const {
ShouldNotReachHere();
return Type::xmeet(t);
}
bool TypeInterfaces::singleton(void) const {
ShouldNotReachHere();
return Type::singleton();
}
//------------------------------TypeOopPtr-------------------------------------
TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bool xk, ciObject* o, int offset,
TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int offset,
int instance_id, const TypePtr* speculative, int inline_depth)
: TypePtr(t, ptr, offset, speculative, inline_depth),
_const_oop(o), _klass(k),
@ -3498,7 +3515,7 @@ TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const InterfaceSet& interfa
_instance_id(instance_id) {
#ifdef ASSERT
if (klass() != nullptr && klass()->is_loaded()) {
interfaces.verify_is_loaded();
interfaces->verify_is_loaded();
}
#endif
if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
@ -3575,7 +3592,8 @@ const TypeOopPtr *TypeOopPtr::make(PTR ptr, int offset, int instance_id,
ciKlass* k = Compile::current()->env()->Object_klass();
bool xk = false;
ciObject* o = nullptr;
return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, InterfaceSet(), xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
const TypeInterfaces* interfaces = TypeInterfaces::make();
return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, interfaces, xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
}
@ -3720,7 +3738,7 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass* klass, bool klass_
klass_is_exact = true;
}
}
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
const TypeInterfaces* interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
return TypeInstPtr::make(TypePtr::BotPTR, klass, interfaces, klass_is_exact, nullptr, 0);
} else if (klass->is_obj_array_klass()) {
// Element is an object array. Recursively call ourself.
@ -3953,15 +3971,15 @@ int TypeOopPtr::dual_instance_id( ) const {
}
TypePtr::InterfaceSet TypeOopPtr::meet_interfaces(const TypeOopPtr* other) const {
const TypeInterfaces* TypeOopPtr::meet_interfaces(const TypeOopPtr* other) const {
if (above_centerline(_ptr) && above_centerline(other->_ptr)) {
return _interfaces.union_with(other->_interfaces);
return _interfaces->union_with(other->_interfaces);
} else if (above_centerline(_ptr) && !above_centerline(other->_ptr)) {
return other->_interfaces;
} else if (above_centerline(other->_ptr) && !above_centerline(_ptr)) {
return _interfaces;
}
return _interfaces.intersection_with(other->_interfaces);
return _interfaces->intersection_with(other->_interfaces);
}
/**
@ -3990,20 +4008,20 @@ const TypeInstPtr *TypeInstPtr::KLASS;
// Is there a single ciKlass* that can represent that type?
ciKlass* TypeInstPtr::exact_klass_helper() const {
if (_interfaces.empty()) {
if (_interfaces->empty()) {
return _klass;
}
if (_klass != ciEnv::current()->Object_klass()) {
if (_interfaces.eq(_klass->as_instance_klass())) {
if (_interfaces->eq(_klass->as_instance_klass())) {
return _klass;
}
return nullptr;
}
return _interfaces.exact_klass();
return _interfaces->exact_klass();
}
//------------------------------TypeInstPtr-------------------------------------
TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bool xk, ciObject* o, int off,
TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int off,
int instance_id, const TypePtr* speculative, int inline_depth)
: TypeOopPtr(InstPtr, ptr, k, interfaces, xk, o, off, instance_id, speculative, inline_depth) {
assert(k == nullptr || !k->is_loaded() || !k->is_interface(), "no interface here");
@ -4015,7 +4033,7 @@ TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bo
//------------------------------make-------------------------------------------
const TypeInstPtr *TypeInstPtr::make(PTR ptr,
ciKlass* k,
const InterfaceSet& interfaces,
const TypeInterfaces* interfaces,
bool xk,
ciObject* o,
int offset,
@ -4047,17 +4065,17 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr,
return result;
}
TypePtr::InterfaceSet TypePtr::interfaces(ciKlass*& k, bool klass, bool interface, bool array, InterfaceHandling interface_handling) {
const TypeInterfaces* TypePtr::interfaces(ciKlass*& k, bool klass, bool interface, bool array, InterfaceHandling interface_handling) {
if (k->is_instance_klass()) {
if (k->is_loaded()) {
if (k->is_interface() && interface_handling == ignore_interfaces) {
assert(interface, "no interface expected");
k = ciEnv::current()->Object_klass();
InterfaceSet interfaces;
const TypeInterfaces* interfaces = TypeInterfaces::make();
return interfaces;
}
GrowableArray<ciInstanceKlass *>* k_interfaces = k->as_instance_klass()->transitive_interfaces();
InterfaceSet interfaces(k_interfaces);
const TypeInterfaces* interfaces = TypeInterfaces::make(k_interfaces);
if (k->is_interface()) {
assert(interface, "no interface expected");
k = ciEnv::current()->Object_klass();
@ -4066,7 +4084,7 @@ TypePtr::InterfaceSet TypePtr::interfaces(ciKlass*& k, bool klass, bool interfac
}
return interfaces;
}
InterfaceSet interfaces;
const TypeInterfaces* interfaces = TypeInterfaces::make();
return interfaces;
}
assert(array, "no array expected");
@ -4077,7 +4095,7 @@ TypePtr::InterfaceSet TypePtr::interfaces(ciKlass*& k, bool klass, bool interfac
k = ciObjArrayKlass::make(ciEnv::current()->Object_klass(), k->as_array_klass()->dimension());
}
}
return *TypeAryPtr::_array_interfaces;
return TypeAryPtr::_array_interfaces;
}
/**
@ -4131,7 +4149,7 @@ const TypeInstPtr* TypeInstPtr::cast_to_instance_id(int instance_id) const {
//------------------------------xmeet_unloaded---------------------------------
// Compute the MEET of two InstPtrs when at least one is unloaded.
// Assume classes are different since called after check for same name/class-loader
const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst, const InterfaceSet& interfaces) const {
const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst, const TypeInterfaces* interfaces) const {
int off = meet_offset(tinst->offset());
PTR ptr = meet_ptr(tinst->ptr());
int instance_id = meet_instance_id(tinst->instance_id());
@ -4288,7 +4306,7 @@ const Type *TypeInstPtr::xmeet_helper(const Type *t) const {
int instance_id = meet_instance_id(tinst->instance_id());
const TypePtr* speculative = xmeet_speculative(tinst);
int depth = meet_inline_depth(tinst->inline_depth());
InterfaceSet interfaces = meet_interfaces(tinst);
const TypeInterfaces* interfaces = meet_interfaces(tinst);
ciKlass* tinst_klass = tinst->klass();
ciKlass* this_klass = klass();
@ -4348,16 +4366,16 @@ const Type *TypeInstPtr::xmeet_helper(const Type *t) const {
return this; // Return the double constant
}
template<class T> TypePtr::MeetResult TypePtr::meet_instptr(PTR& ptr, InterfaceSet& interfaces, const T* this_type, const T* other_type,
ciKlass*& res_klass, bool& res_xk) {
template<class T> TypePtr::MeetResult TypePtr::meet_instptr(PTR& ptr, const TypeInterfaces*& interfaces, const T* this_type, const T* other_type,
ciKlass*& res_klass, bool& res_xk) {
ciKlass* this_klass = this_type->klass();
ciKlass* other_klass = other_type->klass();
bool this_xk = this_type->klass_is_exact();
bool other_xk = other_type->klass_is_exact();
PTR this_ptr = this_type->ptr();
PTR other_ptr = other_type->ptr();
InterfaceSet this_interfaces = this_type->interfaces();
InterfaceSet other_interfaces = other_type->interfaces();
const TypeInterfaces* this_interfaces = this_type->interfaces();
const TypeInterfaces* other_interfaces = other_type->interfaces();
// Check for easy case; klasses are equal (and perhaps not loaded!)
// If we have constants, then we created oops so classes are loaded
// and we can handle the constants further down. This case handles
@ -4442,7 +4460,7 @@ template<class T> TypePtr::MeetResult TypePtr::meet_instptr(PTR& ptr, InterfaceS
ptr = NotNull;
}
interfaces = this_interfaces.intersection_with(other_interfaces);
interfaces = this_interfaces->intersection_with(other_interfaces);
// Now we find the LCA of Java classes
ciKlass* k = this_klass->least_common_ancestor(other_klass);
@ -4478,14 +4496,14 @@ bool TypeInstPtr::eq( const Type *t ) const {
const TypeInstPtr *p = t->is_instptr();
return
klass()->equals(p->klass()) &&
_interfaces.eq(p->_interfaces) &&
_interfaces->eq(p->_interfaces) &&
TypeOopPtr::eq(p); // Check sub-type stuff
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
uint TypeInstPtr::hash(void) const {
return klass()->hash() + TypeOopPtr::hash() + _interfaces.hash();
return klass()->hash() + TypeOopPtr::hash() + _interfaces->hash();
}
bool TypeInstPtr::is_java_subtype_of_helper(const TypeOopPtr* other, bool this_exact, bool other_exact) const {
@ -4508,7 +4526,7 @@ bool TypeInstPtr::maybe_java_subtype_of_helper(const TypeOopPtr* other, bool thi
void TypeInstPtr::dump2(Dict &d, uint depth, outputStream* st) const {
// Print the name of the klass.
klass()->print_name_on(st);
_interfaces.dump(st);
_interfaces->dump(st);
switch( _ptr ) {
case Constant:
@ -4592,7 +4610,7 @@ const TypeKlassPtr* TypeInstPtr::as_klass_type(bool try_for_exact) const {
bool xk = klass_is_exact();
ciInstanceKlass* ik = klass()->as_instance_klass();
if (try_for_exact && !xk && !ik->has_subklass() && !ik->is_final()) {
if (_interfaces.eq(ik)) {
if (_interfaces->eq(ik)) {
Compile* C = Compile::current();
Dependencies* deps = C->dependencies();
deps->assert_leaf_type(ik);
@ -4609,12 +4627,12 @@ template <class T1, class T2> bool TypePtr::is_meet_subtype_of_helper_for_instan
return false;
}
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces.empty()) {
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->empty()) {
return true;
}
return this_one->klass()->is_subtype_of(other->klass()) &&
(!this_xk || this_one->_interfaces.contains(other->_interfaces));
(!this_xk || this_one->_interfaces->contains(other->_interfaces));
}
@ -4624,12 +4642,12 @@ bool TypeInstPtr::is_meet_subtype_of_helper(const TypeOopPtr *other, bool this_x
template <class T1, class T2> bool TypePtr::is_meet_subtype_of_helper_for_array(const T1* this_one, const T2* other, bool this_xk, bool other_xk) {
static_assert(std::is_base_of<T2, T1>::value, "");
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces.empty()) {
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->empty()) {
return true;
}
if (this_one->is_instance_type(other)) {
return other->klass() == ciEnv::current()->Object_klass() && this_one->_interfaces.contains(other->_interfaces);
return other->klass() == ciEnv::current()->Object_klass() && this_one->_interfaces->contains(other->_interfaces);
}
int dummy;
@ -4972,9 +4990,9 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const {
int instance_id = meet_instance_id(tp->instance_id());
const TypePtr* speculative = xmeet_speculative(tp);
int depth = meet_inline_depth(tp->inline_depth());
InterfaceSet interfaces = meet_interfaces(tp);
InterfaceSet tp_interfaces = tp->_interfaces;
InterfaceSet this_interfaces = _interfaces;
const TypeInterfaces* interfaces = meet_interfaces(tp);
const TypeInterfaces* tp_interfaces = tp->_interfaces;
const TypeInterfaces* this_interfaces = _interfaces;
switch (ptr) {
case TopPTR:
@ -4982,13 +5000,13 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need to
// do the same here.
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces.contains(tp_interfaces) && !tp->klass_is_exact()) {
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces->contains(tp_interfaces) && !tp->klass_is_exact()) {
return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
instance_id = InstanceBot;
interfaces = this_interfaces.intersection_with(tp_interfaces);
interfaces = this_interfaces->intersection_with(tp_interfaces);
return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), interfaces, false, nullptr,offset, instance_id, speculative, depth);
}
case Constant:
@ -5001,7 +5019,7 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need
// to do the same here.
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces.contains(tp_interfaces) && !tp->klass_is_exact()) {
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces->contains(tp_interfaces) && !tp->klass_is_exact()) {
// that is, my array type is a subtype of 'tp' klass
return make(ptr, (ptr == Constant ? const_oop() : nullptr),
_ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
@ -5015,7 +5033,7 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const {
if (instance_id > 0) {
instance_id = InstanceBot;
}
interfaces = this_interfaces.intersection_with(tp_interfaces);
interfaces = this_interfaces->intersection_with(tp_interfaces);
return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), interfaces, false, nullptr, offset, instance_id, speculative, depth);
default: typerr(t);
}
@ -5129,7 +5147,7 @@ const Type *TypeAryPtr::xdual() const {
#ifndef PRODUCT
void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
_ary->dump2(d,depth,st);
_interfaces.dump(st);
_interfaces->dump(st);
switch( _ptr ) {
case Constant:
@ -5579,7 +5597,7 @@ const TypeKlassPtr* TypeKlassPtr::make(ciKlass *klass, InterfaceHandling interfa
const TypeKlassPtr* TypeKlassPtr::make(PTR ptr, ciKlass* klass, int offset, InterfaceHandling interface_handling) {
if (klass->is_instance_klass()) {
const InterfaceSet interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
const TypeInterfaces* interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
return TypeInstKlassPtr::make(ptr, klass, interfaces, offset);
}
return TypeAryKlassPtr::make(ptr, klass, offset, interface_handling);
@ -5587,7 +5605,7 @@ const TypeKlassPtr* TypeKlassPtr::make(PTR ptr, ciKlass* klass, int offset, Inte
//------------------------------TypeKlassPtr-----------------------------------
TypeKlassPtr::TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, const InterfaceSet& interfaces, int offset)
TypeKlassPtr::TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, const TypeInterfaces* interfaces, int offset)
: TypePtr(t, ptr, offset), _klass(klass), _interfaces(interfaces) {
assert(klass == nullptr || !klass->is_loaded() || (klass->is_instance_klass() && !klass->is_interface()) ||
klass->is_type_array_klass() || !klass->as_obj_array_klass()->base_element_klass()->is_interface(), "no interface here");
@ -5596,16 +5614,16 @@ TypeKlassPtr::TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, const InterfaceSet&
// Is there a single ciKlass* that can represent that type?
ciKlass* TypeKlassPtr::exact_klass_helper() const {
assert(_klass->is_instance_klass() && !_klass->is_interface(), "No interface");
if (_interfaces.empty()) {
if (_interfaces->empty()) {
return _klass;
}
if (_klass != ciEnv::current()->Object_klass()) {
if (_interfaces.eq(_klass->as_instance_klass())) {
if (_interfaces->eq(_klass->as_instance_klass())) {
return _klass;
}
return nullptr;
}
return _interfaces.exact_klass();
return _interfaces->exact_klass();
}
//------------------------------eq---------------------------------------------
@ -5613,14 +5631,14 @@ ciKlass* TypeKlassPtr::exact_klass_helper() const {
bool TypeKlassPtr::eq(const Type *t) const {
const TypeKlassPtr *p = t->is_klassptr();
return
_interfaces.eq(p->_interfaces) &&
_interfaces->eq(p->_interfaces) &&
TypePtr::eq(p);
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
uint TypeKlassPtr::hash(void) const {
return TypePtr::hash() + _interfaces.hash();
return TypePtr::hash() + _interfaces->hash();
}
//------------------------------singleton--------------------------------------
@ -5647,15 +5665,15 @@ const Type *TypeKlassPtr::filter_helper(const Type *kills, bool include_speculat
return ft;
}
TypePtr::InterfaceSet TypeKlassPtr::meet_interfaces(const TypeKlassPtr* other) const {
const TypeInterfaces* TypeKlassPtr::meet_interfaces(const TypeKlassPtr* other) const {
if (above_centerline(_ptr) && above_centerline(other->_ptr)) {
return _interfaces.union_with(other->_interfaces);
return _interfaces->union_with(other->_interfaces);
} else if (above_centerline(_ptr) && !above_centerline(other->_ptr)) {
return other->_interfaces;
} else if (above_centerline(other->_ptr) && !above_centerline(_ptr)) {
return _interfaces;
}
return _interfaces.intersection_with(other->_interfaces);
return _interfaces->intersection_with(other->_interfaces);
}
//------------------------------get_con----------------------------------------
@ -5695,7 +5713,7 @@ void TypeKlassPtr::dump2(Dict & d, uint depth, outputStream *st) const {
} else {
ShouldNotReachHere();
}
_interfaces.dump(st);
_interfaces->dump(st);
}
case BotPTR:
if (!WizardMode && !Verbose && _ptr != Constant) break;
@ -5736,7 +5754,7 @@ uint TypeInstKlassPtr::hash(void) const {
return klass()->hash() + TypeKlassPtr::hash();
}
const TypeInstKlassPtr *TypeInstKlassPtr::make(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, int offset) {
const TypeInstKlassPtr *TypeInstKlassPtr::make(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, int offset) {
TypeInstKlassPtr *r =
(TypeInstKlassPtr*)(new TypeInstKlassPtr(ptr, k, interfaces, offset))->hashcons();
@ -5788,7 +5806,7 @@ const TypeOopPtr* TypeInstKlassPtr::as_instance_type(bool klass_change) const {
assert((deps != nullptr) == (C->method() != nullptr && C->method()->code_size() > 0), "sanity");
// Element is an instance
bool klass_is_exact = false;
TypePtr::InterfaceSet interfaces = _interfaces;
const TypeInterfaces* interfaces = _interfaces;
if (k->is_loaded()) {
// Try to set klass_is_exact.
ciInstanceKlass* ik = k->as_instance_klass();
@ -5797,7 +5815,7 @@ const TypeOopPtr* TypeInstKlassPtr::as_instance_type(bool klass_change) const {
&& deps != nullptr && UseUniqueSubclasses) {
ciInstanceKlass* sub = ik->unique_concrete_subklass();
if (sub != nullptr) {
if (_interfaces.eq(sub)) {
if (_interfaces->eq(sub)) {
deps->assert_abstract_with_unique_concrete_subtype(ik, sub);
k = ik = sub;
xk = sub->is_final();
@ -5881,7 +5899,7 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const {
const TypeInstKlassPtr *tkls = t->is_instklassptr();
int off = meet_offset(tkls->offset());
PTR ptr = meet_ptr(tkls->ptr());
InterfaceSet interfaces = meet_interfaces(tkls);
const TypeInterfaces* interfaces = meet_interfaces(tkls);
ciKlass* res_klass = nullptr;
bool res_xk = false;
@ -5904,9 +5922,9 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const {
const TypeAryKlassPtr *tp = t->is_aryklassptr();
int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr());
InterfaceSet interfaces = meet_interfaces(tp);
InterfaceSet tp_interfaces = tp->_interfaces;
InterfaceSet this_interfaces = _interfaces;
const TypeInterfaces* interfaces = meet_interfaces(tp);
const TypeInterfaces* tp_interfaces = tp->_interfaces;
const TypeInterfaces* this_interfaces = _interfaces;
switch (ptr) {
case TopPTR:
@ -5914,12 +5932,12 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need to
// do the same here.
if (klass()->equals(ciEnv::current()->Object_klass()) && tp_interfaces.contains(this_interfaces) && !klass_is_exact()) {
if (klass()->equals(ciEnv::current()->Object_klass()) && tp_interfaces->contains(this_interfaces) && !klass_is_exact()) {
return TypeAryKlassPtr::make(ptr, tp->elem(), tp->klass(), offset);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
interfaces = _interfaces.intersection_with(tp->_interfaces);
interfaces = _interfaces->intersection_with(tp->_interfaces);
return make(ptr, ciEnv::current()->Object_klass(), interfaces, offset);
}
case Constant:
@ -5932,7 +5950,7 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need
// to do the same here.
if (klass()->equals(ciEnv::current()->Object_klass()) && tp_interfaces.contains(this_interfaces) && !klass_is_exact()) {
if (klass()->equals(ciEnv::current()->Object_klass()) && tp_interfaces->contains(this_interfaces) && !klass_is_exact()) {
// that is, tp's array type is a subtype of my klass
return TypeAryKlassPtr::make(ptr,
tp->elem(), tp->klass(), offset);
@ -5942,7 +5960,7 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const {
// The meet falls down to Object class below centerline.
if( ptr == Constant )
ptr = NotNull;
interfaces = this_interfaces.intersection_with(tp_interfaces);
interfaces = this_interfaces->intersection_with(tp_interfaces);
return make(ptr, ciEnv::current()->Object_klass(), interfaces, offset);
default: typerr(t);
}
@ -5971,11 +5989,11 @@ template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_instan
return false;
}
if (other->klass()->equals(ciEnv::current()->Object_klass()) && other->_interfaces.empty()) {
if (other->klass()->equals(ciEnv::current()->Object_klass()) && other->_interfaces->empty()) {
return true;
}
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces.contains(other->_interfaces);
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces->contains(other->_interfaces);
}
bool TypeInstKlassPtr::is_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const {
@ -5990,7 +6008,7 @@ template <class T1, class T2> bool TypePtr::is_same_java_type_as_helper_for_inst
if (!this_one->is_instance_type(other)) {
return false;
}
return this_one->_klass->equals(other->_klass) && this_one->_interfaces.eq(other->_interfaces);
return this_one->_klass->equals(other->_klass) && this_one->_interfaces->eq(other->_interfaces);
}
bool TypeInstKlassPtr::is_same_java_type_as_helper(const TypeKlassPtr* other) const {
@ -6004,7 +6022,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_ins
}
if (this_one->is_array_type(other)) {
return !this_exact && this_one->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces.contains(this_one->_interfaces);
return !this_exact && this_one->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces->contains(this_one->_interfaces);
}
assert(this_one->is_instance_type(other), "unsupported");
@ -6018,7 +6036,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_ins
}
if (this_exact) {
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces.contains(other->_interfaces);
return this_one->_klass->is_subtype_of(other->_klass) && this_one->_interfaces->contains(other->_interfaces);
}
return true;
@ -6036,7 +6054,7 @@ const TypeKlassPtr* TypeInstKlassPtr::try_improve() const {
Compile* C = Compile::current();
Dependencies* deps = C->dependencies();
assert((deps != nullptr) == (C->method() != nullptr && C->method()->code_size() > 0), "sanity");
TypePtr::InterfaceSet interfaces = _interfaces;
const TypeInterfaces* interfaces = _interfaces;
if (k->is_loaded()) {
ciInstanceKlass* ik = k->as_instance_klass();
bool klass_is_exact = ik->is_final();
@ -6044,7 +6062,7 @@ const TypeKlassPtr* TypeInstKlassPtr::try_improve() const {
deps != nullptr) {
ciInstanceKlass* sub = ik->unique_concrete_subklass();
if (sub != nullptr) {
if (_interfaces.eq(sub)) {
if (_interfaces->eq(sub)) {
deps->assert_abstract_with_unique_concrete_subtype(ik, sub);
k = ik = sub;
klass_is_exact = sub->is_final();
@ -6338,9 +6356,9 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const {
const TypeInstKlassPtr *tp = t->is_instklassptr();
int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr());
InterfaceSet interfaces = meet_interfaces(tp);
InterfaceSet tp_interfaces = tp->_interfaces;
InterfaceSet this_interfaces = _interfaces;
const TypeInterfaces* interfaces = meet_interfaces(tp);
const TypeInterfaces* tp_interfaces = tp->_interfaces;
const TypeInterfaces* this_interfaces = _interfaces;
switch (ptr) {
case TopPTR:
@ -6348,12 +6366,12 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need to
// do the same here.
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces.intersection_with(tp_interfaces).eq(tp_interfaces) && !tp->klass_is_exact()) {
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces->intersection_with(tp_interfaces)->eq(tp_interfaces) && !tp->klass_is_exact()) {
return TypeAryKlassPtr::make(ptr, _elem, _klass, offset);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
interfaces = this_interfaces.intersection_with(tp->_interfaces);
interfaces = this_interfaces->intersection_with(tp->_interfaces);
return TypeInstKlassPtr::make(ptr, ciEnv::current()->Object_klass(), interfaces, offset);
}
case Constant:
@ -6366,7 +6384,7 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const {
// For instances when a subclass meets a superclass we fall
// below the centerline when the superclass is exact. We need
// to do the same here.
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces.intersection_with(tp_interfaces).eq(tp_interfaces) && !tp->klass_is_exact()) {
if (tp->klass()->equals(ciEnv::current()->Object_klass()) && this_interfaces->intersection_with(tp_interfaces)->eq(tp_interfaces) && !tp->klass_is_exact()) {
// that is, my array type is a subtype of 'tp' klass
return make(ptr, _elem, _klass, offset);
}
@ -6375,7 +6393,7 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const {
// The meet falls down to Object class below centerline.
if (ptr == Constant)
ptr = NotNull;
interfaces = this_interfaces.intersection_with(tp_interfaces);
interfaces = this_interfaces->intersection_with(tp_interfaces);
return TypeInstKlassPtr::make(ptr, ciEnv::current()->Object_klass(), interfaces, offset);
default: typerr(t);
}
@ -6388,7 +6406,7 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const {
template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_array(const T1* this_one, const T2* other, bool this_exact, bool other_exact) {
static_assert(std::is_base_of<T2, T1>::value, "");
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces.empty() && other_exact) {
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->empty() && other_exact) {
return true;
}
@ -6400,7 +6418,7 @@ template <class T1, class T2> bool TypePtr::is_java_subtype_of_helper_for_array(
}
if (this_one->is_instance_type(other)) {
return other->klass() == ciEnv::current()->Object_klass() && other->_interfaces.intersection_with(this_one->_interfaces).eq(other->_interfaces) && other_exact;
return other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->intersection_with(this_one->_interfaces)->eq(other->_interfaces) && other_exact;
}
assert(this_one->is_array_type(other), "");
@ -6460,7 +6478,7 @@ bool TypeAryKlassPtr::is_same_java_type_as_helper(const TypeKlassPtr* other) con
template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_array(const T1* this_one, const T2* other, bool this_exact, bool other_exact) {
static_assert(std::is_base_of<T2, T1>::value, "");
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces.empty() && other_exact) {
if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->empty() && other_exact) {
return true;
}
int dummy;
@ -6469,7 +6487,7 @@ template <class T1, class T2> bool TypePtr::maybe_java_subtype_of_helper_for_arr
return true;
}
if (this_one->is_instance_type(other)) {
return other->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces.intersection_with(this_one->_interfaces).eq(other->_interfaces);
return other->_klass->equals(ciEnv::current()->Object_klass()) && other->_interfaces->intersection_with(this_one->_interfaces)->eq(other->_interfaces);
}
assert(this_one->is_array_type(other), "");
@ -6544,7 +6562,7 @@ void TypeAryKlassPtr::dump2( Dict & d, uint depth, outputStream *st ) const {
{
st->print("[");
_elem->dump2(d, depth, st);
_interfaces.dump(st);
_interfaces->dump(st);
st->print(": ");
}
case BotPTR:

View File

@ -94,6 +94,8 @@ public:
Tuple, // Method signature or object layout
Array, // Array types
Interfaces, // Set of implemented interfaces for oop types
VectorMask, // Vector predicate/mask type
VectorA, // (Scalable) Vector types for vector length agnostic
VectorS, // 32bit Vector types
@ -872,6 +874,48 @@ public:
static const TypeVectMask* make(const Type* elem, uint length);
};
// Set of implemented interfaces. Referenced from TypeOopPtr and TypeKlassPtr.
class TypeInterfaces : public Type {
private:
GrowableArray<ciInstanceKlass*> _list;
uint _hash;
ciInstanceKlass* _exact_klass;
DEBUG_ONLY(bool _initialized;)
void initialize();
void add(ciInstanceKlass* interface);
void verify() const NOT_DEBUG_RETURN;
void compute_hash();
void compute_exact_klass();
TypeInterfaces();
TypeInterfaces(GrowableArray<ciInstanceKlass*>* interfaces);
NONCOPYABLE(TypeInterfaces);
public:
static const TypeInterfaces* make(GrowableArray<ciInstanceKlass*>* interfaces = nullptr);
bool eq(const Type* other) const;
bool eq(ciInstanceKlass* k) const;
uint hash() const;
const Type *xdual() const;
void dump(outputStream* st) const;
const TypeInterfaces* union_with(const TypeInterfaces* other) const;
const TypeInterfaces* intersection_with(const TypeInterfaces* other) const;
bool contains(const TypeInterfaces* other) const {
return intersection_with(other)->eq(other);
}
bool empty() const { return _list.length() == 0; }
ciInstanceKlass* exact_klass() const;
void verify_is_loaded() const NOT_DEBUG_RETURN;
static int compare(ciInstanceKlass* const& k1, ciInstanceKlass* const& k2);
const Type* xmeet(const Type* t) const;
bool singleton(void) const;
};
//------------------------------TypePtr----------------------------------------
// Class of machine Pointer Types: raw data, instances or arrays.
// If the _base enum is AnyPtr, then this refers to all of the above.
@ -881,47 +925,7 @@ class TypePtr : public Type {
friend class TypeNarrowPtr;
friend class Type;
protected:
class InterfaceSet {
private:
GrowableArray<ciKlass*> _list;
uint _hash;
ciKlass* _exact_klass;
DEBUG_ONLY(bool _initialized;)
void initialize();
void raw_add(ciKlass* interface);
void add(ciKlass* interface);
void verify() const NOT_DEBUG_RETURN;
void compute_hash();
void compute_exact_klass();
public:
InterfaceSet();
InterfaceSet(GrowableArray<ciInstanceKlass*>* interfaces);
bool eq(const InterfaceSet& other) const;
bool eq(ciInstanceKlass* k) const;
uint hash() const;
void dump(outputStream* st) const;
InterfaceSet union_with(const InterfaceSet& other) const;
InterfaceSet intersection_with(const InterfaceSet& other) const;
bool contains(const InterfaceSet& other) const {
return intersection_with(other).eq(other);
}
bool empty() const { return _list.length() == 0; }
inline void* operator new(size_t x) throw() {
Compile* compile = Compile::current();
return compile->type_arena()->AmallocWords(x);
}
inline void operator delete(void* ptr) {
ShouldNotReachHere();
}
ciKlass* exact_klass() const;
void verify_is_loaded() const NOT_DEBUG_RETURN;
static int compare(ciKlass* const& k1, ciKlass* const& k2);
};
static InterfaceSet interfaces(ciKlass*& k, bool klass, bool interface, bool array, InterfaceHandling interface_handling);
static const TypeInterfaces* interfaces(ciKlass*& k, bool klass, bool interface, bool array, InterfaceHandling interface_handling);
public:
enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR };
@ -981,7 +985,7 @@ protected:
NOT_SUBTYPE,
LCA
};
template<class T> static TypePtr::MeetResult meet_instptr(PTR& ptr, InterfaceSet& interfaces, const T* this_type,
template<class T> static TypePtr::MeetResult meet_instptr(PTR& ptr, const TypeInterfaces*& interfaces, const T* this_type,
const T* other_type, ciKlass*& res_klass, bool& res_xk);
template<class T> static MeetResult meet_aryptr(PTR& ptr, const Type*& elem, const T* this_ary, const T* other_ary,
@ -1103,8 +1107,8 @@ class TypeOopPtr : public TypePtr {
friend class TypeInstPtr;
friend class TypeAryPtr;
protected:
TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bool xk, ciObject* o, int offset, int instance_id,
const TypePtr* speculative, int inline_depth);
TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int offset, int instance_id,
const TypePtr* speculative, int inline_depth);
public:
virtual bool eq( const Type *t ) const;
virtual uint hash() const; // Type specific hashing
@ -1120,7 +1124,7 @@ protected:
// If _klass is null, then so is _sig. This is an unloaded klass.
ciKlass* _klass; // Klass object
const InterfaceSet _interfaces;
const TypeInterfaces* _interfaces;
// Does the type exclude subclasses of the klass? (Inexact == polymorphic.)
bool _klass_is_exact;
@ -1138,7 +1142,7 @@ protected:
int dual_instance_id() const;
int meet_instance_id(int uid) const;
InterfaceSet meet_interfaces(const TypeOopPtr* other) const;
const TypeInterfaces* meet_interfaces(const TypeOopPtr* other) const;
// Do not allow interface-vs.-noninterface joins to collapse to top.
virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
@ -1252,7 +1256,7 @@ private:
ShouldNotReachHere(); return false;
}
virtual const InterfaceSet interfaces() const {
virtual const TypeInterfaces* interfaces() const {
return _interfaces;
};
@ -1273,7 +1277,7 @@ private:
// Class of Java object pointers, pointing either to non-array Java instances
// or to a Klass* (including array klasses).
class TypeInstPtr : public TypeOopPtr {
TypeInstPtr(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bool xk, ciObject* o, int offset, int instance_id,
TypeInstPtr(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int off, int instance_id,
const TypePtr* speculative, int inline_depth);
virtual bool eq( const Type *t ) const;
virtual uint hash() const; // Type specific hashing
@ -1295,41 +1299,41 @@ public:
// Make a pointer to a constant oop.
static const TypeInstPtr *make(ciObject* o) {
ciKlass* k = o->klass();
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
return make(TypePtr::Constant, k, interfaces, true, o, 0, InstanceBot);
}
// Make a pointer to a constant oop with offset.
static const TypeInstPtr *make(ciObject* o, int offset) {
ciKlass* k = o->klass();
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
return make(TypePtr::Constant, k, interfaces, true, o, offset, InstanceBot);
}
// Make a pointer to some value of type klass.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass, InterfaceHandling interface_handling = ignore_interfaces) {
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
const TypeInterfaces* interfaces = TypePtr::interfaces(klass, true, true, false, interface_handling);
return make(ptr, klass, interfaces, false, nullptr, 0, InstanceBot);
}
// Make a pointer to some non-polymorphic value of exactly type klass.
static const TypeInstPtr *make_exact(PTR ptr, ciKlass* klass) {
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(klass, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(klass, true, false, false, ignore_interfaces);
return make(ptr, klass, interfaces, true, nullptr, 0, InstanceBot);
}
// Make a pointer to some value of type klass with offset.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass, int offset) {
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(klass, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(klass, true, false, false, ignore_interfaces);
return make(ptr, klass, interfaces, false, nullptr, offset, InstanceBot);
}
static const TypeInstPtr *make(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, bool xk, ciObject* o, int offset,
static const TypeInstPtr *make(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, bool xk, ciObject* o, int offset,
int instance_id = InstanceBot,
const TypePtr* speculative = nullptr,
int inline_depth = InlineDepthBottom);
static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot) {
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
return make(ptr, k, interfaces, xk, o, offset, instance_id);
}
@ -1357,7 +1361,7 @@ public:
// the core of the computation of the meet of 2 types
virtual const Type *xmeet_helper(const Type *t) const;
virtual const TypeInstPtr *xmeet_unloaded(const TypeInstPtr *t, const InterfaceSet& interfaces) const;
virtual const TypeInstPtr *xmeet_unloaded(const TypeInstPtr *tinst, const TypeInterfaces* interfaces) const;
virtual const Type *xdual() const; // Compute dual right now.
const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
@ -1376,7 +1380,7 @@ private:
virtual bool is_meet_subtype_of_helper(const TypeOopPtr* other, bool this_xk, bool other_xk) const;
virtual bool is_meet_same_type_as(const TypePtr* other) const {
return _klass->equals(other->is_instptr()->_klass) && _interfaces.eq(other->is_instptr()->_interfaces);
return _klass->equals(other->is_instptr()->_klass) && _interfaces->eq(other->is_instptr()->_interfaces);
}
};
@ -1390,7 +1394,7 @@ class TypeAryPtr : public TypeOopPtr {
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
int offset, int instance_id, bool is_autobox_cache,
const TypePtr* speculative, int inline_depth)
: TypeOopPtr(AryPtr,ptr,k,*_array_interfaces,xk,o,offset, instance_id, speculative, inline_depth),
: TypeOopPtr(AryPtr,ptr,k,_array_interfaces,xk,o,offset, instance_id, speculative, inline_depth),
_ary(ary),
_is_autobox_cache(is_autobox_cache)
{
@ -1413,7 +1417,7 @@ class TypeAryPtr : public TypeOopPtr {
// A pointer to delay allocation to Type::Initialize_shared()
static const InterfaceSet* _array_interfaces;
static const TypeInterfaces* _array_interfaces;
ciKlass* exact_klass_helper() const;
// Only guaranteed non null for array of basic types
ciKlass* klass() const;
@ -1551,7 +1555,7 @@ class TypeKlassPtr : public TypePtr {
friend class TypeAryKlassPtr;
friend class TypePtr;
protected:
TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, const InterfaceSet& interfaces, int offset);
TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, const TypeInterfaces* interfaces, int offset);
virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
@ -1563,8 +1567,8 @@ public:
protected:
ciKlass* _klass;
const InterfaceSet _interfaces;
InterfaceSet meet_interfaces(const TypeKlassPtr* other) const;
const TypeInterfaces* _interfaces;
const TypeInterfaces* meet_interfaces(const TypeKlassPtr* other) const;
virtual bool must_be_exact() const { ShouldNotReachHere(); return false; }
virtual ciKlass* exact_klass_helper() const;
virtual ciKlass* klass() const { return _klass; }
@ -1623,7 +1627,7 @@ private:
ShouldNotReachHere(); return false;
}
virtual const InterfaceSet interfaces() const {
virtual const TypeInterfaces* interfaces() const {
return _interfaces;
};
@ -1643,7 +1647,7 @@ private:
// Instance klass pointer, mirrors TypeInstPtr
class TypeInstKlassPtr : public TypeKlassPtr {
TypeInstKlassPtr(PTR ptr, ciKlass* klass, const InterfaceSet& interfaces, int offset)
TypeInstKlassPtr(PTR ptr, ciKlass* klass, const TypeInterfaces* interfaces, int offset)
: TypeKlassPtr(InstKlassPtr, ptr, klass, interfaces, offset) {
assert(klass->is_instance_klass() && (!klass->is_loaded() || !klass->is_interface()), "");
}
@ -1662,13 +1666,13 @@ public:
bool maybe_java_subtype_of_helper(const TypeKlassPtr* other, bool this_exact, bool other_exact) const;
static const TypeInstKlassPtr *make(ciKlass* k, InterfaceHandling interface_handling) {
InterfaceSet interfaces = TypePtr::interfaces(k, true, true, false, interface_handling);
const TypeInterfaces* interfaces = TypePtr::interfaces(k, true, true, false, interface_handling);
return make(TypePtr::Constant, k, interfaces, 0);
}
static const TypeInstKlassPtr* make(PTR ptr, ciKlass* k, const InterfaceSet& interfaces, int offset);
static const TypeInstKlassPtr* make(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, int offset);
static const TypeInstKlassPtr* make(PTR ptr, ciKlass* k, int offset) {
const TypePtr::InterfaceSet interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
const TypeInterfaces* interfaces = TypePtr::interfaces(k, true, false, false, ignore_interfaces);
return make(ptr, k, interfaces, offset);
}
@ -1703,9 +1707,9 @@ class TypeAryKlassPtr : public TypeKlassPtr {
const Type *_elem;
static const InterfaceSet* _array_interfaces;
static const TypeInterfaces* _array_interfaces;
TypeAryKlassPtr(PTR ptr, const Type *elem, ciKlass* klass, int offset)
: TypeKlassPtr(AryKlassPtr, ptr, klass, *_array_interfaces, offset), _elem(elem) {
: TypeKlassPtr(AryKlassPtr, ptr, klass, _array_interfaces, offset), _elem(elem) {
assert(klass == nullptr || klass->is_type_array_klass() || !klass->as_obj_array_klass()->base_element_klass()->is_interface(), "");
}