diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index 74dc14868131c..9763911e58197 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -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 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* interfaces) - : _list(Compile::current()->type_arena(), interfaces->length(), 0, nullptr), +TypeInterfaces::TypeInterfaces(GrowableArray* 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* interfaces) initialize(); } -void TypePtr::InterfaceSet::initialize() { +const TypeInterfaces* TypeInterfaces::make(GrowableArray* 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(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* interfaces = k->as_instance_klass()->transitive_interfaces(); + GrowableArray* 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(interfaces->at(i), found); + _list.find_sorted(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 interfaces; + GrowableArray 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 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 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* 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 TypePtr::MeetResult TypePtr::meet_instptr(PTR& ptr, InterfaceSet& interfaces, const T* this_type, const T* other_type, - ciKlass*& res_klass, bool& res_xk) { +template 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 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 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 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::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 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 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 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 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 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::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 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 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::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 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: diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index c37c036639443..c65ff4af01244 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -94,6 +94,8 @@ class Type { 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 @@ class TypeVectMask : public TypeVect { static const TypeVectMask* make(const Type* elem, uint length); }; +// Set of implemented interfaces. Referenced from TypeOopPtr and TypeKlassPtr. +class TypeInterfaces : public Type { +private: + GrowableArray _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* interfaces); + + NONCOPYABLE(TypeInterfaces); +public: + static const TypeInterfaces* make(GrowableArray* 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 _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* 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 @@ class TypePtr : public Type { NOT_SUBTYPE, LCA }; - template static TypePtr::MeetResult meet_instptr(PTR& ptr, InterfaceSet& interfaces, const T* this_type, + template 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 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 @@ class TypeOopPtr : public TypePtr { // 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 @@ class TypeOopPtr : public TypePtr { 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 @@ class TypeOopPtr : public TypePtr { ShouldNotReachHere(); return false; } - virtual const InterfaceSet interfaces() const { + virtual const TypeInterfaces* interfaces() const { return _interfaces; }; @@ -1273,7 +1277,7 @@ class TypeOopPtr : public TypePtr { // 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 @@ class TypeInstPtr : public TypeOopPtr { // 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 @@ class TypeInstPtr : public TypeOopPtr { // 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 @@ class TypeInstPtr : public TypeOopPtr { 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 @@ class TypeKlassPtr : public TypePtr { 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 @@ class TypeKlassPtr : public TypePtr { ShouldNotReachHere(); return false; } - virtual const InterfaceSet interfaces() const { + virtual const TypeInterfaces* interfaces() const { return _interfaces; }; @@ -1643,7 +1647,7 @@ class TypeKlassPtr : public TypePtr { // 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 @@ class TypeInstKlassPtr : public TypeKlassPtr { 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(), ""); }