src/share/vm/opto/type.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/type.cpp

src/share/vm/opto/type.cpp

Print this page
rev 5464 : 8024070: C2 needs some form of type speculation
Summary: record unused type profile information with type system, propagate and use it.
Reviewed-by:
rev 5465 : imported patch speculative-cleanup

*** 356,366 **** TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::mark_offset_in_bytes()); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::klass_offset_in_bytes()); ! TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot); TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM ); --- 356,366 ---- TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::mark_offset_in_bytes()); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), false, 0, oopDesc::klass_offset_in_bytes()); ! TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot, NULL); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot); TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
*** 575,585 **** return false; } //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT ! bool Type::interface_vs_oop(const Type *t) const { bool result = false; const TypePtr* this_ptr = this->make_ptr(); // In case it is narrow_oop const TypePtr* t_ptr = t->make_ptr(); if( this_ptr == NULL || t_ptr == NULL ) --- 575,585 ---- return false; } //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT ! bool Type::interface_vs_oop_helper(const Type *t) const { bool result = false; const TypePtr* this_ptr = this->make_ptr(); // In case it is narrow_oop const TypePtr* t_ptr = t->make_ptr(); if( this_ptr == NULL || t_ptr == NULL )
*** 593,602 **** --- 593,625 ---- result = this_interface ^ t_interface; } return result; } + + bool Type::interface_vs_oop(const Type *t) const { + if (interface_vs_oop_helper(t)) { + return true; + } + // Now check the speculative parts as well + const TypeOopPtr* this_spec = isa_oopptr() != NULL ? isa_oopptr()->speculative() : NULL; + const TypeOopPtr* t_spec = t->isa_oopptr() != NULL ? t->isa_oopptr()->speculative() : NULL; + if (this_spec != NULL && t_spec != NULL) { + if (this_spec->interface_vs_oop_helper(t_spec)) { + return true; + } + return false; + } + if (this_spec != NULL && this_spec->interface_vs_oop_helper(t)) { + return true; + } + if (t_spec != NULL && interface_vs_oop_helper(t_spec)) { + return true; + } + return false; + } + #endif //------------------------------meet------------------------------------------- // Compute the MEET of two types. NOT virtual. It enforces that meet is // commutative and the lattice is symmetric.
*** 2405,2422 **** //============================================================================= // Convenience common pre-built type. const TypeOopPtr *TypeOopPtr::BOTTOM; //------------------------------TypeOopPtr------------------------------------- ! TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id ) : TypePtr(t, ptr, offset), _const_oop(o), _klass(k), _klass_is_exact(xk), _is_ptr_to_narrowoop(false), _is_ptr_to_narrowklass(false), _is_ptr_to_boxed_value(false), ! _instance_id(instance_id) { if (Compile::current()->eliminate_boxing() && (t == InstPtr) && (offset > 0) && xk && (k != 0) && k->is_instance_klass()) { _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset); } #ifdef _LP64 --- 2428,2446 ---- //============================================================================= // Convenience common pre-built type. const TypeOopPtr *TypeOopPtr::BOTTOM; //------------------------------TypeOopPtr------------------------------------- ! TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative) : TypePtr(t, ptr, offset), _const_oop(o), _klass(k), _klass_is_exact(xk), _is_ptr_to_narrowoop(false), _is_ptr_to_narrowklass(false), _is_ptr_to_boxed_value(false), ! _instance_id(instance_id), ! _speculative(speculative) { if (Compile::current()->eliminate_boxing() && (t == InstPtr) && (offset > 0) && xk && (k != 0) && k->is_instance_klass()) { _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset); } #ifdef _LP64
*** 2479,2502 **** #endif } //------------------------------make------------------------------------------- const TypeOopPtr *TypeOopPtr::make(PTR ptr, ! int offset, int instance_id) { assert(ptr != Constant, "no constant generic pointers"); ciKlass* k = Compile::current()->env()->Object_klass(); bool xk = false; ciObject* o = NULL; ! return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const { assert(_base == OopPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(ptr, _offset, _instance_id); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const { // There are no instances of a general oop. --- 2503,2526 ---- #endif } //------------------------------make------------------------------------------- const TypeOopPtr *TypeOopPtr::make(PTR ptr, ! int offset, int instance_id, const TypeOopPtr* speculative) { assert(ptr != Constant, "no constant generic pointers"); ciKlass* k = Compile::current()->env()->Object_klass(); bool xk = false; ciObject* o = NULL; ! return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const { assert(_base == OopPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(ptr, _offset, _instance_id, _speculative); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const { // There are no instances of a general oop.
*** 2522,2535 **** return TypeKlassPtr::OBJECT; else return TypeKlassPtr::make(xk? Constant: NotNull, k, 0); } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeOopPtr::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is OopPtr switch (t->base()) { // switch on original type --- 2546,2580 ---- return TypeKlassPtr::OBJECT; else return TypeKlassPtr::make(xk? Constant: NotNull, k, 0); } + const Type *TypeOopPtr::xmeet(const Type *t) const { + const Type* res = xmeet_helper(t); + if (res->isa_oopptr() == NULL) { + return res; + } + + if (res->isa_oopptr() != NULL) { + // type->speculative() == NULL means that speculation is no better + // than type, i.e. type->speculative() == type. So there are 2 + // ways to represent the fact that we have no useful speculative + // data and we should use a single one to be able to test for + // equality between types. Check whether type->speculative() == + // type and set speculative to NULL if it is the case. + const TypeOopPtr* res_oopptr = res->is_oopptr(); + if (res_oopptr->remove_speculative() == res_oopptr->speculative()) { + return res_oopptr->remove_speculative(); + } + } + + return res; + } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeOopPtr::xmeet_helper(const Type *t) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is OopPtr switch (t->base()) { // switch on original type
*** 2567,2577 **** if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); // else fall through: case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! return make(ptr, offset, instance_id); } case BotPTR: case NotNull: return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); --- 2612,2623 ---- if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); // else fall through: case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! const TypeOopPtr* speculative = _speculative; ! return make(ptr, offset, instance_id, speculative); } case BotPTR: case NotNull: return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t);
*** 2579,2589 **** } case OopPtr: { // Meeting to other OopPtrs const TypeOopPtr *tp = t->is_oopptr(); int instance_id = meet_instance_id(tp->instance_id()); ! return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id ); } case InstPtr: // For these, flip the call around to cut down case AryPtr: return t->xmeet(this); // Call in reverse direction --- 2625,2636 ---- } case OopPtr: { // Meeting to other OopPtrs const TypeOopPtr *tp = t->is_oopptr(); int instance_id = meet_instance_id(tp->instance_id()); ! const TypeOopPtr* speculative = meet_speculative(tp); ! return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative); } case InstPtr: // For these, flip the call around to cut down case AryPtr: return t->xmeet(this); // Call in reverse direction
*** 2596,2606 **** //------------------------------xdual------------------------------------------ // Dual of a pure heap pointer. No relevant klass or oop information. const Type *TypeOopPtr::xdual() const { assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here"); assert(const_oop() == NULL, "no constants here"); ! return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id() ); } //--------------------------make_from_klass_common----------------------------- // Computes the element-type given a klass. const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_change, bool try_for_exact) { --- 2643,2653 ---- //------------------------------xdual------------------------------------------ // Dual of a pure heap pointer. No relevant klass or oop information. const Type *TypeOopPtr::xdual() const { assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here"); assert(const_oop() == NULL, "no constants here"); ! return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative()); } //--------------------------make_from_klass_common----------------------------- // Computes the element-type given a klass. const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_change, bool try_for_exact) {
*** 2687,2697 **** if (require_constant) { if (!o->can_be_constant()) return NULL; } else if (!o->should_be_constant()) { return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); } ! const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, is_autobox_cache); return arr; } else if (klass->is_type_array_klass()) { // Element is an typeArray const Type* etype = (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type()); --- 2734,2744 ---- if (require_constant) { if (!o->can_be_constant()) return NULL; } else if (!o->should_be_constant()) { return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); } ! const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, is_autobox_cache); return arr; } else if (klass->is_type_array_klass()) { // Element is an typeArray const Type* etype = (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
*** 2787,2797 **** //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeOopPtr::eq( const Type *t ) const { const TypeOopPtr *a = (const TypeOopPtr*)t; if (_klass_is_exact != a->_klass_is_exact || ! _instance_id != a->_instance_id) return false; ciObject* one = const_oop(); ciObject* two = a->const_oop(); if (one == NULL || two == NULL) { return (one == two) && TypePtr::eq(t); } else { --- 2834,2845 ---- //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeOopPtr::eq( const Type *t ) const { const TypeOopPtr *a = (const TypeOopPtr*)t; if (_klass_is_exact != a->_klass_is_exact || ! _instance_id != a->_instance_id || ! !eq_speculative(a)) return false; ciObject* one = const_oop(); ciObject* two = a->const_oop(); if (one == NULL || two == NULL) { return (one == two) && TypePtr::eq(t); } else {
*** 2804,2813 **** --- 2852,2862 ---- int TypeOopPtr::hash(void) const { return (const_oop() ? const_oop()->hash() : 0) + _klass_is_exact + _instance_id + + hash_speculative() + TypePtr::hash(); } //------------------------------dump2------------------------------------------ #ifndef PRODUCT
*** 2823,2832 **** --- 2872,2892 ---- } if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id); + + dump_speculative(st); + } + + // dump the speculative part of the type + void TypeOopPtr::dump_speculative(outputStream *st) const { + if (_speculative != NULL) { + st->print(" (speculative="); + _speculative->dump_on(st); + st->print(")"); + } } #endif //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
*** 2836,2847 **** // TopPTR, Null, AnyNull, Constant are all singletons return (_offset == 0) && !below_centerline(_ptr); } //------------------------------add_offset------------------------------------- ! const TypePtr *TypeOopPtr::add_offset( intptr_t offset ) const { ! return make( _ptr, xadd_offset(offset), _instance_id); } //------------------------------meet_instance_id-------------------------------- int TypeOopPtr::meet_instance_id( int instance_id ) const { // Either is 'TOP' instance? Return the other instance! --- 2896,2912 ---- // TopPTR, Null, AnyNull, Constant are all singletons return (_offset == 0) && !below_centerline(_ptr); } //------------------------------add_offset------------------------------------- ! const TypePtr *TypeOopPtr::add_offset(intptr_t offset) const { ! return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset)); ! } ! ! // Return same type without a speculative part ! const TypeOopPtr* TypeOopPtr::remove_speculative() const { ! return make(_ptr, _offset, _instance_id, NULL); } //------------------------------meet_instance_id-------------------------------- int TypeOopPtr::meet_instance_id( int instance_id ) const { // Either is 'TOP' instance? Return the other instance!
*** 2857,2878 **** if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP return _instance_id; // Map everything else into self } //============================================================================= // Convenience common pre-built types. const TypeInstPtr *TypeInstPtr::NOTNULL; const TypeInstPtr *TypeInstPtr::BOTTOM; const TypeInstPtr *TypeInstPtr::MIRROR; const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- ! TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id) ! : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id), _name(k->name()) { assert(k != NULL && (k->is_loaded() || o == NULL), "cannot have constants with non-loaded klass"); }; --- 2922,3010 ---- if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP return _instance_id; // Map everything else into self } + // meet of the speculative parts of 2 types + const TypeOopPtr* TypeOopPtr::meet_speculative(const TypeOopPtr* other) const { + bool this_has_spec = (_speculative != NULL); + bool other_has_spec = (other->speculative() != NULL); + + if (!this_has_spec && !other_has_spec) { + return NULL; + } + + // If we are at a point where control flow meets and one branch has + // a speculative type and the other has not, we meet the speculative + // type of one branch with the actual type of the other. If the + // actual type is exact and the speculative is as well, then the + // result is a speculative type which is exact and we can continue + // speculation further. + const TypeOopPtr* this_spec = _speculative; + const TypeOopPtr* other_spec = other->speculative(); + + if (!this_has_spec) { + this_spec = this; + } + + if (!other_has_spec) { + other_spec = other; + } + + return this_spec->meet(other_spec)->is_oopptr(); + } + + // dual of the speculative part of the type + const TypeOopPtr* TypeOopPtr::dual_speculative() const { + if (_speculative == NULL) { + return NULL; + } + return _speculative->dual()->is_oopptr(); + } + + // add offset to the speculative part of the type + const TypeOopPtr* TypeOopPtr::add_offset_speculative(intptr_t offset) const { + if (_speculative == NULL) { + return NULL; + } + return _speculative->add_offset(offset)->is_oopptr(); + } + + // Are the speculative parts of 2 types equal? + bool TypeOopPtr::eq_speculative(const TypeOopPtr* other) const { + if (_speculative == NULL || other->speculative() == NULL) { + return _speculative == other->speculative(); + } + + if (_speculative->base() != other->speculative()->base()) { + return false; + } + + return _speculative->eq(other->speculative()); + } + + // Hash of the speculative part of the type + int TypeOopPtr::hash_speculative() const { + if (_speculative == NULL) { + return 0; + } + + return _speculative->hash(); + } + //============================================================================= // Convenience common pre-built types. const TypeInstPtr *TypeInstPtr::NOTNULL; const TypeInstPtr *TypeInstPtr::BOTTOM; const TypeInstPtr *TypeInstPtr::MIRROR; const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- ! TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative) ! : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative), _name(k->name()) { assert(k != NULL && (k->is_loaded() || o == NULL), "cannot have constants with non-loaded klass"); };
*** 2880,2890 **** const TypeInstPtr *TypeInstPtr::make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, ! int instance_id) { assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance"); // Either const_oop() is NULL or else ptr is Constant assert( (!o && ptr != Constant) || (o && ptr == Constant), "constant pointers must have a value supplied" ); // Ptr is never Null --- 3012,3023 ---- const TypeInstPtr *TypeInstPtr::make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, ! int instance_id, ! const TypeOopPtr* speculative) { assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance"); // Either const_oop() is NULL or else ptr is Constant assert( (!o && ptr != Constant) || (o && ptr == Constant), "constant pointers must have a value supplied" ); // Ptr is never Null
*** 2901,2911 **** if (xk && ik->is_interface()) xk = false; // no exact interface } // Now hash this baby TypeInstPtr *result = ! (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id))->hashcons(); return result; } /** --- 3034,3044 ---- if (xk && ik->is_interface()) xk = false; // no exact interface } // Now hash this baby TypeInstPtr *result = ! (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative))->hashcons(); return result; } /**
*** 2934,2944 **** //------------------------------cast_to_ptr_type------------------------------- const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const { if( ptr == _ptr ) return this; // Reconstruct _sig info here since not a problem with later lazy // construction, _sig will show up on demand. ! return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const { --- 3067,3077 ---- //------------------------------cast_to_ptr_type------------------------------- const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const { if( ptr == _ptr ) return this; // Reconstruct _sig info here since not a problem with later lazy // construction, _sig will show up on demand. ! return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const {
*** 2946,2971 **** if (!UseExactTypes) return this; if (!_klass->is_loaded()) return this; ciInstanceKlass* ik = _klass->as_instance_klass(); if( (ik->is_final() || _const_oop) ) return this; // cannot clear xk if( ik->is_interface() ) return this; // cannot set xk ! return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; ! return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id); } //------------------------------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 { int off = meet_offset(tinst->offset()); PTR ptr = meet_ptr(tinst->ptr()); int instance_id = meet_instance_id(tinst->instance_id()); const TypeInstPtr *loaded = is_loaded() ? this : tinst; const TypeInstPtr *unloaded = is_loaded() ? tinst : this; if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) { // --- 3079,3105 ---- if (!UseExactTypes) return this; if (!_klass->is_loaded()) return this; ciInstanceKlass* ik = _klass->as_instance_klass(); if( (ik->is_final() || _const_oop) ) return this; // cannot clear xk if( ik->is_interface() ) return this; // cannot set xk ! return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; ! return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative); } //------------------------------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 { int off = meet_offset(tinst->offset()); PTR ptr = meet_ptr(tinst->ptr()); int instance_id = meet_instance_id(tinst->instance_id()); + const TypeOopPtr* speculative = meet_speculative(tinst); const TypeInstPtr *loaded = is_loaded() ? this : tinst; const TypeInstPtr *unloaded = is_loaded() ? tinst : this; if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) { //
*** 2982,2992 **** // BOTTOM | ........................Object-BOTTOM ..................| // assert(loaded->ptr() != TypePtr::Null, "insanity check"); // if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded; } ! else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make( ptr, unloaded->klass(), false, NULL, off, instance_id ); } else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) { if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } else { return TypeInstPtr::NOTNULL; } } --- 3116,3126 ---- // BOTTOM | ........................Object-BOTTOM ..................| // assert(loaded->ptr() != TypePtr::Null, "insanity check"); // if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded; } ! else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative); } else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) { if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } else { return TypeInstPtr::NOTNULL; } }
*** 3004,3014 **** } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeInstPtr::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is Pointer switch (t->base()) { // switch on original type --- 3138,3148 ---- } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeInstPtr::xmeet_helper(const Type *t) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is Pointer switch (t->base()) { // switch on original type
*** 3038,3077 **** case AryPtr: { // All arrays inherit from Object class const TypeAryPtr *tp = t->is_aryptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); switch (ptr) { case TopPTR: case AnyNull: // Fall 'down' to dual of object klass ! if (klass()->equals(ciEnv::current()->Object_klass())) { ! return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id); } else { // cannot subclass, so the meet has to fall badly below the centerline ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id); } case Constant: case NotNull: case BotPTR: // Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better if( above_centerline(_ptr) ) { // if( _ptr == TopPTR || _ptr == AnyNull ) // If 'this' (InstPtr) is above the centerline and it is Object class // then we can subclass in the Java class hierarchy. ! if (klass()->equals(ciEnv::current()->Object_klass())) { // that is, tp's array type is a subtype of my klass return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL), ! tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id); } } // The other case cannot happen, since I cannot be a subtype of an array. // The meet falls down to Object class below centerline. if( ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; ! return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id ); default: typerr(t); } } case OopPtr: { // Meeting to OopPtrs --- 3172,3218 ---- case AryPtr: { // All arrays inherit from Object class const TypeAryPtr *tp = t->is_aryptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); + const TypeOopPtr* speculative = meet_speculative(tp); switch (ptr) { case TopPTR: case AnyNull: // Fall 'down' to dual of object klass ! // 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()) && !klass_is_exact()) { ! return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative); } else { // cannot subclass, so the meet has to fall badly below the centerline ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative); } case Constant: case NotNull: case BotPTR: // Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better if( above_centerline(_ptr) ) { // if( _ptr == TopPTR || _ptr == AnyNull ) // If 'this' (InstPtr) is above the centerline and it is Object class // then we can subclass in the Java class hierarchy. ! // 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()) && !klass_is_exact()) { // that is, tp's array type is a subtype of my klass return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL), ! tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative); } } // The other case cannot happen, since I cannot be a subtype of an array. // The meet falls down to Object class below centerline. if( ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; ! return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative); default: typerr(t); } } case OopPtr: { // Meeting to OopPtrs
*** 3081,3097 **** PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); ! return TypeOopPtr::make(ptr, offset, instance_id); } default: typerr(t); } } --- 3222,3240 ---- PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); + const TypeOopPtr* speculative = meet_speculative(tp); return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); ! const TypeOopPtr* speculative = meet_speculative(tp); ! return TypeOopPtr::make(ptr, offset, instance_id, speculative); } default: typerr(t); } }
*** 3100,3120 **** const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset ); // else fall through to AnyNull case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! return make( ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id); } case NotNull: case BotPTR: ! return TypePtr::make( AnyPtr, ptr, offset ); default: typerr(t); } } /* --- 3243,3264 ---- const TypePtr *tp = t->is_ptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case Null: ! if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); // else fall through to AnyNull case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! const TypeOopPtr* speculative = _speculative; ! return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative); } case NotNull: case BotPTR: ! return TypePtr::make(AnyPtr, ptr, offset); default: typerr(t); } } /*
*** 3137,3153 **** // Found an InstPtr sub-type vs self-InstPtr type const TypeInstPtr *tinst = t->is_instptr(); int off = meet_offset( tinst->offset() ); PTR ptr = meet_ptr( tinst->ptr() ); int instance_id = meet_instance_id(tinst->instance_id()); // 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 // both-not-loaded or both-loaded classes if (ptr != Constant && klass()->equals(tinst->klass()) && klass_is_exact() == tinst->klass_is_exact()) { ! return make( ptr, klass(), klass_is_exact(), NULL, off, instance_id ); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tinst_klass = tinst->klass(); ciKlass* this_klass = this->klass(); --- 3281,3298 ---- // Found an InstPtr sub-type vs self-InstPtr type const TypeInstPtr *tinst = t->is_instptr(); int off = meet_offset( tinst->offset() ); PTR ptr = meet_ptr( tinst->ptr() ); int instance_id = meet_instance_id(tinst->instance_id()); + const TypeOopPtr* speculative = meet_speculative(tinst); // 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 // both-not-loaded or both-loaded classes if (ptr != Constant && klass()->equals(tinst->klass()) && klass_is_exact() == tinst->klass_is_exact()) { ! return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tinst_klass = tinst->klass(); ciKlass* this_klass = this->klass();
*** 3165,3175 **** #endif return unloaded_meet; } // Handle mixing oops and interfaces first. ! if( this_klass->is_interface() && !tinst_klass->is_interface() ) { ciKlass *tmp = tinst_klass; // Swap interface around tinst_klass = this_klass; this_klass = tmp; bool tmp2 = tinst_xk; tinst_xk = this_xk; --- 3310,3321 ---- #endif return unloaded_meet; } // Handle mixing oops and interfaces first. ! if( this_klass->is_interface() && !(tinst_klass->is_interface() || ! tinst_klass == ciEnv::current()->Object_klass())) { ciKlass *tmp = tinst_klass; // Swap interface around tinst_klass = this_klass; this_klass = tmp; bool tmp2 = tinst_xk; tinst_xk = this_xk;
*** 3206,3216 **** ciObject* o = NULL; // the Constant value, if any if (ptr == Constant) { // Find out which constant. o = (this_klass == klass()) ? const_oop() : tinst->const_oop(); } ! return make( ptr, k, xk, o, off, instance_id ); } // Either oop vs oop or interface vs interface or interface vs Object // !!! Here's how the symmetry requirement breaks down into invariants: --- 3352,3362 ---- ciObject* o = NULL; // the Constant value, if any if (ptr == Constant) { // Find out which constant. o = (this_klass == klass()) ? const_oop() : tinst->const_oop(); } ! return make(ptr, k, xk, o, off, instance_id, speculative); } // Either oop vs oop or interface vs interface or interface vs Object // !!! Here's how the symmetry requirement breaks down into invariants:
*** 3283,3304 **** else if (above_centerline(tinst ->_ptr)) o = this_oop; else ptr = NotNull; } ! return make( ptr, this_klass, this_xk, o, off, instance_id ); } // Else classes are not equal // Since klasses are different, we require a LCA in the Java // class hierarchy - which means we have to fall to at least NotNull. if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tinst_klass); ! return make( ptr, k, false, NULL, off, instance_id ); } // End of case InstPtr } // End of switch return this; // Return the double constant } --- 3429,3450 ---- else if (above_centerline(tinst ->_ptr)) o = this_oop; else ptr = NotNull; } ! return make(ptr, this_klass, this_xk, o, off, instance_id, speculative); } // Else classes are not equal // Since klasses are different, we require a LCA in the Java // class hierarchy - which means we have to fall to at least NotNull. if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tinst_klass); ! return make(ptr, k, false, NULL, off, instance_id, speculative); } // End of case InstPtr } // End of switch return this; // Return the double constant }
*** 3318,3328 **** //------------------------------xdual------------------------------------------ // Dual: do NOT dual on klasses. This means I do NOT understand the Java // inheritance mechanism. const Type *TypeInstPtr::xdual() const { ! return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id() ); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeInstPtr::eq( const Type *t ) const { --- 3464,3474 ---- //------------------------------xdual------------------------------------------ // Dual: do NOT dual on klasses. This means I do NOT understand the Java // inheritance mechanism. const Type *TypeInstPtr::xdual() const { ! return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative()); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeInstPtr::eq( const Type *t ) const {
*** 3374,3389 **** st->print(" *"); if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id); } #endif //------------------------------add_offset------------------------------------- ! const TypePtr *TypeInstPtr::add_offset( intptr_t offset ) const { ! return make( _ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id ); } //============================================================================= // Convenience common pre-built types. const TypeAryPtr *TypeAryPtr::RANGE; --- 3520,3541 ---- st->print(" *"); if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id); + + dump_speculative(st); } #endif //------------------------------add_offset------------------------------------- ! const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const { ! return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id, add_offset_speculative(offset)); ! } ! ! const TypeOopPtr *TypeInstPtr::remove_speculative() const { ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL); } //============================================================================= // Convenience common pre-built types. const TypeAryPtr *TypeAryPtr::RANGE;
*** 3396,3444 **** const TypeAryPtr *TypeAryPtr::LONGS; const TypeAryPtr *TypeAryPtr::FLOATS; const TypeAryPtr *TypeAryPtr::DOUBLES; //------------------------------make------------------------------------------- ! const TypeAryPtr *TypeAryPtr::make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) { assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); if (!xk) xk = ary->ary_must_be_exact(); assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); ! return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false))->hashcons(); } //------------------------------make------------------------------------------- ! const TypeAryPtr *TypeAryPtr::make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, bool is_autobox_cache) { assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" ); if (!xk) xk = (o != NULL) || ary->ary_must_be_exact(); assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); ! return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const { if( ptr == _ptr ) return this; ! return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const { if( klass_is_exact == _klass_is_exact ) return this; if (!UseExactTypes) return this; if (_ary->ary_must_be_exact()) return this; // cannot clear xk ! return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; ! return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id); } //-----------------------------narrow_size_type------------------------------- // Local cache for arrayOopDesc::max_array_length(etype), // which is kind of slow (and cached elsewhere by other users). --- 3548,3596 ---- const TypeAryPtr *TypeAryPtr::LONGS; const TypeAryPtr *TypeAryPtr::FLOATS; const TypeAryPtr *TypeAryPtr::DOUBLES; //------------------------------make------------------------------------------- ! const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative) { assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); if (!xk) xk = ary->ary_must_be_exact(); assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); ! return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative))->hashcons(); } //------------------------------make------------------------------------------- ! const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, bool is_autobox_cache) { assert(!(k == NULL && ary->_elem->isa_int()), "integral arrays must be pre-equipped with a class"); assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" ); if (!xk) xk = (o != NULL) || ary->ary_must_be_exact(); assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); if (!UseExactTypes) xk = (ptr == Constant); ! return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative))->hashcons(); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const { if( ptr == _ptr ) return this; ! return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const { if( klass_is_exact == _klass_is_exact ) return this; if (!UseExactTypes) return this; if (_ary->ary_must_be_exact()) return this; // cannot clear xk ! return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative); } //-----------------------------cast_to_instance_id---------------------------- const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const { if( instance_id == _instance_id ) return this; ! return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative); } //-----------------------------narrow_size_type------------------------------- // Local cache for arrayOopDesc::max_array_length(etype), // which is kind of slow (and cached elsewhere by other users).
*** 3497,3507 **** const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { assert(new_size != NULL, ""); new_size = narrow_size_type(new_size); if (new_size == size()) return this; const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); ! return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); } //------------------------------cast_to_stable--------------------------------- const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const { --- 3649,3659 ---- const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { assert(new_size != NULL, ""); new_size = narrow_size_type(new_size); if (new_size == size()) return this; const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); ! return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative); } //------------------------------cast_to_stable--------------------------------- const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const {
*** 3546,3556 **** return (intptr_t)_ary + TypeOopPtr::hash(); } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeAryPtr::xmeet( const Type *t ) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is Pointer switch (t->base()) { // switch on original type --- 3698,3708 ---- return (intptr_t)_ary + TypeOopPtr::hash(); } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. ! const Type *TypeAryPtr::xmeet_helper(const Type *t) const { // Perform a fast test for common case; meeting the same types together. if( this == t ) return this; // Meeting same type-rep? // Current "this->_base" is Pointer switch (t->base()) { // switch on original type
*** 3580,3596 **** PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); return make(ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id); } case BotPTR: case NotNull: { int instance_id = meet_instance_id(tp->instance_id()); ! return TypeOopPtr::make(ptr, offset, instance_id); } default: ShouldNotReachHere(); } } --- 3732,3750 ---- PTR ptr = meet_ptr(tp->ptr()); switch (tp->ptr()) { case TopPTR: case AnyNull: { int instance_id = meet_instance_id(InstanceTop); + const TypeOopPtr* speculative = meet_speculative(tp); return make(ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id, speculative); } case BotPTR: case NotNull: { int instance_id = meet_instance_id(tp->instance_id()); ! const TypeOopPtr* speculative = meet_speculative(tp); ! return TypeOopPtr::make(ptr, offset, instance_id, speculative); } default: ShouldNotReachHere(); } }
*** 3608,3619 **** case Null: if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); // else fall through to AnyNull case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! return make( ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id); } default: ShouldNotReachHere(); } } --- 3762,3774 ---- case Null: if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); // else fall through to AnyNull case AnyNull: { int instance_id = meet_instance_id(InstanceTop); ! const TypeOopPtr* speculative = _speculative; ! return make(ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id, speculative); } default: ShouldNotReachHere(); } }
*** 3625,3634 **** --- 3780,3790 ---- const TypeAryPtr *tap = t->is_aryptr(); int off = meet_offset(tap->offset()); const TypeAry *tary = _ary->meet(tap->_ary)->is_ary(); PTR ptr = meet_ptr(tap->ptr()); int instance_id = meet_instance_id(tap->instance_id()); + const TypeOopPtr* speculative = meet_speculative(tap); ciKlass* lazy_klass = NULL; if (tary->_elem->isa_int()) { // Integral array element types have irrelevant lattice relations. // It is the klass that determines array layout, not the element type. if (_klass == NULL)
*** 3652,3671 **** // 'tap' is exact and super or unrelated: (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); ! return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot ); } bool xk = false; switch (tap->ptr()) { case AnyNull: case TopPTR: // Compute new klass on demand, do not use tap->_klass xk = (tap->_klass_is_exact | this->_klass_is_exact); ! return make( ptr, const_oop(), tary, lazy_klass, xk, off, instance_id ); case Constant: { ciObject* o = const_oop(); if( _ptr == Constant ) { if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) { xk = (klass() == tap->klass()); --- 3808,3831 ---- // 'tap' is exact and super or unrelated: (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); ! return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot); } bool xk = false; switch (tap->ptr()) { case AnyNull: case TopPTR: // Compute new klass on demand, do not use tap->_klass + if (below_centerline(this->_ptr)) { + xk = this->_klass_is_exact; + } else { xk = (tap->_klass_is_exact | this->_klass_is_exact); ! } ! return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative); case Constant: { ciObject* o = const_oop(); if( _ptr == Constant ) { if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) { xk = (klass() == tap->klass());
*** 3673,3752 **** o = NULL; instance_id = InstanceBot; } else { xk = true; } ! } else if( above_centerline(_ptr) ) { o = tap->const_oop(); xk = true; } else { // Only precise for identical arrays xk = this->_klass_is_exact && (klass() == tap->klass()); } ! return TypeAryPtr::make( ptr, o, tary, lazy_klass, xk, off, instance_id ); } case NotNull: case BotPTR: // Compute new klass on demand, do not use tap->_klass if (above_centerline(this->_ptr)) xk = tap->_klass_is_exact; - else if (above_centerline(tap->_ptr)) - xk = this->_klass_is_exact; else xk = (tap->_klass_is_exact & this->_klass_is_exact) && (klass() == tap->klass()); // Only precise for identical arrays ! return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, instance_id ); default: ShouldNotReachHere(); } } // All arrays inherit from Object class case InstPtr: { const TypeInstPtr *tp = t->is_instptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); switch (ptr) { case TopPTR: case AnyNull: // Fall 'down' to dual of object klass ! if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) { ! return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id ); } else { // cannot subclass, so the meet has to fall badly below the centerline ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id); } case Constant: case NotNull: case BotPTR: // Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better if (above_centerline(tp->ptr())) { // If 'tp' is above the centerline and it is Object class // then we can subclass in the Java class hierarchy. ! if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) { // that is, my array type is a subtype of 'tp' klass ! return make( ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id ); } } // The other case cannot happen, since t cannot be a subtype of an array. // The meet falls down to Object class below centerline. if( ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id); default: typerr(t); } } } return this; // Lint noise } //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual const Type *TypeAryPtr::xdual() const { ! return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache() ); } //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT bool TypeAryPtr::interface_vs_oop(const Type *t) const { --- 3833,3917 ---- o = NULL; instance_id = InstanceBot; } else { xk = true; } ! } else if(above_centerline(_ptr)) { o = tap->const_oop(); xk = true; } else { // Only precise for identical arrays xk = this->_klass_is_exact && (klass() == tap->klass()); } ! return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative); } case NotNull: case BotPTR: // Compute new klass on demand, do not use tap->_klass if (above_centerline(this->_ptr)) xk = tap->_klass_is_exact; else xk = (tap->_klass_is_exact & this->_klass_is_exact) && (klass() == tap->klass()); // Only precise for identical arrays ! return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative); default: ShouldNotReachHere(); } } // All arrays inherit from Object class case InstPtr: { const TypeInstPtr *tp = t->is_instptr(); int offset = meet_offset(tp->offset()); PTR ptr = meet_ptr(tp->ptr()); int instance_id = meet_instance_id(tp->instance_id()); + const TypeOopPtr* speculative = meet_speculative(tp); switch (ptr) { case TopPTR: case AnyNull: // Fall 'down' to dual of object klass ! // 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()) && !tp->klass_is_exact()) { ! return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative); } else { // cannot subclass, so the meet has to fall badly below the centerline ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative); } case Constant: case NotNull: case BotPTR: // Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better if (above_centerline(tp->ptr())) { // If 'tp' is above the centerline and it is Object class // then we can subclass in the Java class hierarchy. ! // 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()) && !tp->klass_is_exact()) { // that is, my array type is a subtype of 'tp' klass ! return make(ptr, (ptr == Constant ? const_oop() : NULL), ! _ary, _klass, _klass_is_exact, offset, instance_id, speculative); } } // The other case cannot happen, since t cannot be a subtype of an array. // The meet falls down to Object class below centerline. if( ptr == Constant ) ptr = NotNull; instance_id = InstanceBot; ! return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative); default: typerr(t); } } } return this; // Lint noise } //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual const Type *TypeAryPtr::xdual() const { ! return new TypeAryPtr(dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache(), dual_speculative()); } //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT bool TypeAryPtr::interface_vs_oop(const Type *t) const {
*** 3794,3816 **** st->print(" *"); if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id); } #endif bool TypeAryPtr::empty(void) const { if (_ary->empty()) return true; return TypeOopPtr::empty(); } //------------------------------add_offset------------------------------------- ! const TypePtr *TypeAryPtr::add_offset( intptr_t offset ) const { ! return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id ); } //============================================================================= //------------------------------hash------------------------------------------- // Type-specific hashing function. --- 3959,3986 ---- st->print(" *"); if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id); + + dump_speculative(st); } #endif bool TypeAryPtr::empty(void) const { if (_ary->empty()) return true; return TypeOopPtr::empty(); } //------------------------------add_offset------------------------------------- ! const TypePtr *TypeAryPtr::add_offset(intptr_t offset) const { ! return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset)); } + const TypeOopPtr *TypeAryPtr::remove_speculative() const { + return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, _offset, _instance_id, NULL); + } //============================================================================= //------------------------------hash------------------------------------------- // Type-specific hashing function.
src/share/vm/opto/type.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File