< prev index next >

src/hotspot/share/opto/type.cpp

Print this page

        

*** 592,604 **** TypeInstPtr::NOTNULL = TypeInstPtr::make(TypePtr::NotNull, current->env()->Object_klass()); TypeInstPtr::BOTTOM = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass()); TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), ! false, 0, Offset(oopDesc::mark_offset_in_bytes())); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), ! false, 0, Offset(oopDesc::klass_offset_in_bytes())); TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, Offset::bottom, TypeOopPtr::InstanceBot); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, Offset::bottom); TypeValueType::BOTTOM = TypeValueType::make(NULL); --- 592,604 ---- TypeInstPtr::NOTNULL = TypeInstPtr::make(TypePtr::NotNull, current->env()->Object_klass()); TypeInstPtr::BOTTOM = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass()); TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), ! false, 0, Offset(oopDesc::mark_offset_in_bytes()), false); TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), ! false, 0, Offset(oopDesc::klass_offset_in_bytes()), false); TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, Offset::bottom, TypeOopPtr::InstanceBot); TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, Offset::bottom); TypeValueType::BOTTOM = TypeValueType::make(NULL);
*** 653,664 **** TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS; TypeAryPtr::_array_body_type[T_LONG] = TypeAryPtr::LONGS; TypeAryPtr::_array_body_type[T_FLOAT] = TypeAryPtr::FLOATS; TypeAryPtr::_array_body_type[T_DOUBLE] = TypeAryPtr::DOUBLES; ! TypeKlassPtr::OBJECT = TypeKlassPtr::make(TypePtr::NotNull, current->env()->Object_klass(), Offset(0) ); ! TypeKlassPtr::OBJECT_OR_NULL = TypeKlassPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), Offset(0) ); const Type **fi2c = TypeTuple::fields(2); fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method* fi2c[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // argument pointer TypeTuple::START_I2C = TypeTuple::make(TypeFunc::Parms+2, fi2c); --- 653,664 ---- TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS; TypeAryPtr::_array_body_type[T_LONG] = TypeAryPtr::LONGS; TypeAryPtr::_array_body_type[T_FLOAT] = TypeAryPtr::FLOATS; TypeAryPtr::_array_body_type[T_DOUBLE] = TypeAryPtr::DOUBLES; ! TypeKlassPtr::OBJECT = TypeKlassPtr::make(TypePtr::NotNull, current->env()->Object_klass(), Offset(0), false); ! TypeKlassPtr::OBJECT_OR_NULL = TypeKlassPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), Offset(0), false ); const Type **fi2c = TypeTuple::fields(2); fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method* fi2c[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // argument pointer TypeTuple::START_I2C = TypeTuple::make(TypeFunc::Parms+2, fi2c);
*** 3346,3356 **** ciKlass* k = klass(); bool xk = klass_is_exact(); if (k == NULL) return TypeKlassPtr::OBJECT; else ! return TypeKlassPtr::make(xk? Constant: NotNull, k, Offset(0)); } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. const Type *TypeOopPtr::xmeet_helper(const Type *t) const { --- 3346,3356 ---- ciKlass* k = klass(); bool xk = klass_is_exact(); if (k == NULL) return TypeKlassPtr::OBJECT; else ! return TypeKlassPtr::make(xk? Constant: NotNull, k, Offset(0), isa_instptr() && is_instptr()->flat_array()); } //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. const Type *TypeOopPtr::xmeet_helper(const Type *t) const {
*** 3460,3470 **** deps->assert_leaf_type(ik); klass_is_exact = true; } } } ! return TypeInstPtr::make(TypePtr::BotPTR, klass, klass_is_exact, NULL, Offset(0)); } else if (klass->is_obj_array_klass()) { // Element is an object or value array. Recursively call ourself. const TypeOopPtr* etype = TypeOopPtr::make_from_klass_common(klass->as_array_klass()->element_klass(), false, try_for_exact); bool null_free = klass->is_loaded() && klass->as_array_klass()->storage_properties().is_null_free(); if (null_free) { --- 3460,3470 ---- deps->assert_leaf_type(ik); klass_is_exact = true; } } } ! return TypeInstPtr::make(TypePtr::BotPTR, klass, klass_is_exact, NULL, Offset(0), klass->flatten_array()); } else if (klass->is_obj_array_klass()) { // Element is an object or value array. Recursively call ourself. const TypeOopPtr* etype = TypeOopPtr::make_from_klass_common(klass->as_array_klass()->element_klass(), false, try_for_exact); bool null_free = klass->is_loaded() && klass->as_array_klass()->storage_properties().is_null_free(); if (null_free) {
*** 3512,3522 **** if (klass->is_instance_klass() || klass->is_valuetype()) { // Element is an instance or value type if (make_constant) { return TypeInstPtr::make(o); } else { ! return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, Offset(0)); } } else if (klass->is_obj_array_klass()) { // Element is an object array. Recursively call ourself. const TypeOopPtr* etype = TypeOopPtr::make_from_klass_raw(klass->as_array_klass()->element_klass()); bool null_free = klass->is_loaded() && klass->as_array_klass()->storage_properties().is_null_free(); --- 3512,3522 ---- if (klass->is_instance_klass() || klass->is_valuetype()) { // Element is an instance or value type if (make_constant) { return TypeInstPtr::make(o); } else { ! return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, Offset(0), klass->flatten_array()); } } else if (klass->is_obj_array_klass()) { // Element is an object array. Recursively call ourself. const TypeOopPtr* etype = TypeOopPtr::make_from_klass_raw(klass->as_array_klass()->element_klass()); bool null_free = klass->is_loaded() && klass->as_array_klass()->storage_properties().is_null_free();
*** 3769,3792 **** const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset off, ! int instance_id, const TypePtr* speculative, int inline_depth) : TypeOopPtr(InstPtr, ptr, k, xk, o, off, Offset::bottom, instance_id, speculative, inline_depth), ! _name(k->name()) { assert(k != NULL && (k->is_loaded() || o == NULL), "cannot have constants with non-loaded klass"); }; //------------------------------make------------------------------------------- const TypeInstPtr *TypeInstPtr::make(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth) { assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance"); // Either const_oop() is NULL or else ptr is Constant --- 3769,3796 ---- const TypeInstPtr *TypeInstPtr::MARK; const TypeInstPtr *TypeInstPtr::KLASS; //------------------------------TypeInstPtr------------------------------------- TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset off, ! bool flat_array, int instance_id, const TypePtr* speculative, ! int inline_depth) : TypeOopPtr(InstPtr, ptr, k, xk, o, off, Offset::bottom, instance_id, speculative, inline_depth), ! _name(k->name()), _flat_array(flat_array) { assert(k != NULL && (k->is_loaded() || o == NULL), "cannot have constants with non-loaded klass"); + assert(!klass()->is_valuetype() || !klass()->flatten_array() || flat_array, "incorrect flatten array bit"); + assert(!flat_array || can_be_value_type(), "incorrect flatten array bit"); }; //------------------------------make------------------------------------------- const TypeInstPtr *TypeInstPtr::make(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, + bool flat_array, int instance_id, const TypePtr* speculative, int inline_depth) { assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance"); // Either const_oop() is NULL or else ptr is Constant
*** 3806,3816 **** 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, inline_depth))->hashcons(); return result; } /** --- 3810,3820 ---- if (xk && ik->is_interface()) xk = false; // no exact interface } // Now hash this baby TypeInstPtr *result = ! (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, flat_array, instance_id, speculative, inline_depth))->hashcons(); return result; } /**
*** 3839,3849 **** //------------------------------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, _inline_depth); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const { --- 3843,3853 ---- //------------------------------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, _flat_array, _instance_id, _speculative, _inline_depth); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const {
*** 3851,3872 **** 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, _inline_depth); } //-----------------------------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, _inline_depth); } const TypeOopPtr *TypeInstPtr::cast_to_nonconst() const { if (const_oop() == NULL) return this; ! return make(NotNull, klass(), _klass_is_exact, NULL, _offset, _instance_id, _speculative, _inline_depth); } //------------------------------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 --- 3855,3876 ---- 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, _flat_array, _instance_id, _speculative, _inline_depth); } //-----------------------------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, _flat_array, instance_id, _speculative, _inline_depth); } const TypeOopPtr *TypeInstPtr::cast_to_nonconst() const { if (const_oop() == NULL) return this; ! return make(NotNull, klass(), _klass_is_exact, NULL, _offset, _flat_array, _instance_id, _speculative, _inline_depth); } //------------------------------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
*** 3894,3904 **** // 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, depth); } 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; } } --- 3898,3908 ---- // 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, false, instance_id, speculative, depth); } 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; } }
*** 3964,3974 **** return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, tp->field_offset(), instance_id, speculative, depth); } 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, depth); } 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 --- 3968,3978 ---- return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, tp->field_offset(), instance_id, speculative, depth); } 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, false, instance_id, speculative, depth); } 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
*** 3987,3997 **** // 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, depth); default: typerr(t); } } case OopPtr: { // Meeting to OopPtrs --- 3991,4001 ---- // 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, false, instance_id, speculative, depth); default: typerr(t); } } case OopPtr: { // Meeting to OopPtrs
*** 4004,4014 **** case AnyNull: { int instance_id = meet_instance_id(InstanceTop); const TypePtr* speculative = xmeet_speculative(tp); int depth = meet_inline_depth(tp->inline_depth()); return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); const TypePtr* speculative = xmeet_speculative(tp); --- 4008,4018 ---- case AnyNull: { int instance_id = meet_instance_id(InstanceTop); const TypePtr* speculative = xmeet_speculative(tp); int depth = meet_inline_depth(tp->inline_depth()); return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, flat_array(), instance_id, speculative, depth); } case NotNull: case BotPTR: { int instance_id = meet_instance_id(tp->instance_id()); const TypePtr* speculative = xmeet_speculative(tp);
*** 4032,4042 **** if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); // else fall through to AnyNull case TopPTR: case AnyNull: { return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth); } case NotNull: case BotPTR: return TypePtr::make(AnyPtr, ptr, offset, speculative,depth); default: typerr(t); --- 4036,4046 ---- if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth); // else fall through to AnyNull case TopPTR: case AnyNull: { return make(ptr, klass(), klass_is_exact(), ! (ptr == Constant ? const_oop() : NULL), offset, flat_array(), instance_id, speculative, depth); } case NotNull: case BotPTR: return TypePtr::make(AnyPtr, ptr, offset, speculative,depth); default: typerr(t);
*** 4070,4088 **** // 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, depth); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tinst_klass = tinst->klass(); ciKlass* this_klass = this->klass(); bool tinst_xk = tinst->klass_is_exact(); bool this_xk = this->klass_is_exact(); if (!tinst_klass->is_loaded() || !this_klass->is_loaded() ) { // One of these classes has not been loaded const TypeInstPtr *unloaded_meet = xmeet_unloaded(tinst); #ifndef PRODUCT if( PrintOpto && Verbose ) { --- 4074,4095 ---- // 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() && ! flat_array() == tinst->flat_array()) { ! return make(ptr, klass(), klass_is_exact(), NULL, off, flat_array(), instance_id, speculative, depth); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tinst_klass = tinst->klass(); ciKlass* this_klass = this->klass(); bool tinst_xk = tinst->klass_is_exact(); bool this_xk = this->klass_is_exact(); + bool tinst_flat_array = tinst->flat_array(); + bool this_flat_array = this->flat_array(); if (!tinst_klass->is_loaded() || !this_klass->is_loaded() ) { // One of these classes has not been loaded const TypeInstPtr *unloaded_meet = xmeet_unloaded(tinst); #ifndef PRODUCT if( PrintOpto && Verbose ) {
*** 4101,4110 **** --- 4108,4120 ---- tinst_klass = this_klass; this_klass = tmp; bool tmp2 = tinst_xk; tinst_xk = this_xk; this_xk = tmp2; + tmp2 = tinst_flat_array; + tinst_flat_array = this_flat_array; + this_flat_array = tmp2; } if (tinst_klass->is_interface() && !(this_klass->is_interface() || // Treat java/lang/Object as an honorary interface, // because we need a bottom for the interface hierarchy.
*** 4112,4145 **** // Oop meets interface! // See if the oop subtypes (implements) interface. ciKlass *k; bool xk; if( this_klass->is_subtype_of( tinst_klass ) ) { // Oop indeed subtypes. Now keep oop or interface depending // on whether we are both above the centerline or either is // below the centerline. If we are on the centerline // (e.g., Constant vs. AnyNull interface), use the constant. k = below_centerline(ptr) ? tinst_klass : this_klass; // If we are keeping this_klass, keep its exactness too. xk = below_centerline(ptr) ? tinst_xk : this_xk; } else { // Does not implement, fall to Object // Oop does not implement interface, so mixing falls to Object // just like the verifier does (if both are above the // centerline fall to interface) k = above_centerline(ptr) ? tinst_klass : ciEnv::current()->Object_klass(); xk = above_centerline(ptr) ? tinst_xk : false; // Watch out for Constant vs. AnyNull interface. if (ptr == Constant) ptr = NotNull; // forget it was a constant instance_id = InstanceBot; } 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, depth); } // Either oop vs oop or interface vs interface or interface vs Object // !!! Here's how the symmetry requirement breaks down into invariants: --- 4122,4158 ---- // Oop meets interface! // See if the oop subtypes (implements) interface. ciKlass *k; bool xk; + bool flat_array; if( this_klass->is_subtype_of( tinst_klass ) ) { // Oop indeed subtypes. Now keep oop or interface depending // on whether we are both above the centerline or either is // below the centerline. If we are on the centerline // (e.g., Constant vs. AnyNull interface), use the constant. k = below_centerline(ptr) ? tinst_klass : this_klass; // If we are keeping this_klass, keep its exactness too. xk = below_centerline(ptr) ? tinst_xk : this_xk; + flat_array = below_centerline(ptr) ? tinst_flat_array : this_flat_array; } else { // Does not implement, fall to Object // Oop does not implement interface, so mixing falls to Object // just like the verifier does (if both are above the // centerline fall to interface) k = above_centerline(ptr) ? tinst_klass : ciEnv::current()->Object_klass(); xk = above_centerline(ptr) ? tinst_xk : false; + flat_array = above_centerline(ptr) ? tinst_flat_array : false; // Watch out for Constant vs. AnyNull interface. if (ptr == Constant) ptr = NotNull; // forget it was a constant instance_id = InstanceBot; } 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, flat_array, instance_id, speculative, depth); } // Either oop vs oop or interface vs interface or interface vs Object // !!! Here's how the symmetry requirement breaks down into invariants:
*** 4167,4199 **** --- 4180,4220 ---- // centerline and or-ed above it. (N.B. Constants are always exact.) // Check for subtyping: ciKlass *subtype = NULL; bool subtype_exact = false; + bool flat_array = false; if( tinst_klass->equals(this_klass) ) { subtype = this_klass; subtype_exact = below_centerline(ptr) ? (this_xk && tinst_xk) : (this_xk || tinst_xk); + flat_array = below_centerline(ptr) ? (this_flat_array && tinst_flat_array) : (this_flat_array || tinst_flat_array); } else if( !tinst_xk && this_klass->is_subtype_of( tinst_klass ) ) { subtype = this_klass; // Pick subtyping class subtype_exact = this_xk; + flat_array = this_flat_array; } else if( !this_xk && tinst_klass->is_subtype_of( this_klass ) ) { subtype = tinst_klass; // Pick subtyping class subtype_exact = tinst_xk; + flat_array = tinst_flat_array; } if( subtype ) { if( above_centerline(ptr) ) { // both are up? this_klass = tinst_klass = subtype; this_xk = tinst_xk = subtype_exact; + this_flat_array = tinst_flat_array = flat_array; } else if( above_centerline(this ->_ptr) && !above_centerline(tinst->_ptr) ) { this_klass = tinst_klass; // tinst is down; keep down man this_xk = tinst_xk; + this_flat_array = tinst_flat_array; } else if( above_centerline(tinst->_ptr) && !above_centerline(this ->_ptr) ) { tinst_klass = this_klass; // this is down; keep down man tinst_xk = this_xk; + tinst_flat_array = this_flat_array; } else { this_xk = subtype_exact; // either they are equal, or we'll do an LCA + this_flat_array = flat_array; } } // Check for classes now being equal if (tinst_klass->equals(this_klass)) {
*** 4212,4222 **** else if (above_centerline(tinst ->_ptr)) o = this_oop; else ptr = NotNull; } ! return make(ptr, this_klass, this_xk, o, off, instance_id, speculative, depth); } // 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 ) --- 4233,4243 ---- else if (above_centerline(tinst ->_ptr)) o = this_oop; else ptr = NotNull; } ! return make(ptr, this_klass, this_xk, o, off, this_flat_array, instance_id, speculative, depth); } // 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 )
*** 4224,4234 **** 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, depth); } // End of case InstPtr case ValueType: { const TypeValueType* tv = t->is_valuetype(); if (above_centerline(ptr())) { --- 4245,4255 ---- 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, false, instance_id, speculative, depth); } // End of case InstPtr case ValueType: { const TypeValueType* tv = t->is_valuetype(); if (above_centerline(ptr())) {
*** 4269,4294 **** //------------------------------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(), dual_inline_depth()); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeInstPtr::eq( const Type *t ) const { const TypeInstPtr *p = t->is_instptr(); return klass()->equals(p->klass()) && TypeOopPtr::eq(p); // Check sub-type stuff } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInstPtr::hash(void) const { ! int hash = java_add((jint)klass()->hash(), (jint)TypeOopPtr::hash()); return hash; } //------------------------------dump2------------------------------------------ // Dump oop Type --- 4290,4316 ---- //------------------------------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(), flat_array(), dual_instance_id(), dual_speculative(), dual_inline_depth()); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeInstPtr::eq( const Type *t ) const { const TypeInstPtr *p = t->is_instptr(); return klass()->equals(p->klass()) && + flat_array() == p->flat_array() && TypeOopPtr::eq(p); // Check sub-type stuff } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInstPtr::hash(void) const { ! int hash = java_add(java_add((jint)klass()->hash(), (jint)TypeOopPtr::hash()), (jint)flat_array()); return hash; } //------------------------------dump2------------------------------------------ // Dump oop Type
*** 4319,4328 **** --- 4341,4355 ---- } _offset.dump2(st); st->print(" *"); + + if (flat_array() && !klass()->is_valuetype()) { + st->print(" (flatten array)"); + } + if (_instance_id == InstanceTop) st->print(",iid=top"); else if (_instance_id != InstanceBot) st->print(",iid=%d",_instance_id);
*** 4331,4365 **** } #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), _inline_depth); } const Type *TypeInstPtr::remove_speculative() const { if (_speculative == NULL) { return this; } assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL, _inline_depth); } const TypePtr *TypeInstPtr::with_inline_depth(int depth) const { if (!UseInlineDepthForSpeculativeTypes) { return this; } ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth); } const TypePtr *TypeInstPtr::with_instance_id(int instance_id) const { assert(is_known_instance(), "should be known"); ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, instance_id, _speculative, _inline_depth); } //============================================================================= // Convenience common pre-built types. const TypeAryPtr *TypeAryPtr::RANGE; const TypeAryPtr *TypeAryPtr::OOPS; const TypeAryPtr *TypeAryPtr::NARROWOOPS; --- 4358,4397 ---- } #endif //------------------------------add_offset------------------------------------- const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const { ! return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), flat_array(), _instance_id, add_offset_speculative(offset), _inline_depth); } const Type *TypeInstPtr::remove_speculative() const { if (_speculative == NULL) { return this; } assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, flat_array(), _instance_id, NULL, _inline_depth); } const TypePtr *TypeInstPtr::with_inline_depth(int depth) const { if (!UseInlineDepthForSpeculativeTypes) { return this; } ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, flat_array(), _instance_id, _speculative, depth); } const TypePtr *TypeInstPtr::with_instance_id(int instance_id) const { assert(is_known_instance(), "should be known"); ! return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, flat_array(), instance_id, _speculative, _inline_depth); } + const TypeInstPtr *TypeInstPtr::cast_to_flat_array() const { + return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, true, _instance_id, _speculative, _inline_depth); + } + + //============================================================================= // Convenience common pre-built types. const TypeAryPtr *TypeAryPtr::RANGE; const TypeAryPtr *TypeAryPtr::OOPS; const TypeAryPtr *TypeAryPtr::NARROWOOPS;
*** 4763,4773 **** return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, _field_offset, instance_id, speculative, depth); } 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, depth); } 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 --- 4795,4805 ---- return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, _field_offset, instance_id, speculative, depth); } 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, false, instance_id, speculative, depth); } 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
*** 4786,4796 **** // 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, depth); default: typerr(t); } } case ValueType: { --- 4818,4828 ---- // 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, false, instance_id, speculative, depth); default: typerr(t); } } case ValueType: {
*** 5324,5355 **** // Not-null object klass or below const TypeKlassPtr *TypeKlassPtr::OBJECT; const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL; //------------------------------TypeKlassPtr----------------------------------- ! TypeKlassPtr::TypeKlassPtr( PTR ptr, ciKlass* klass, Offset offset ) ! : TypePtr(KlassPtr, ptr, offset), _klass(klass), _klass_is_exact(ptr == Constant) { } //------------------------------make------------------------------------------- // ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant ! const TypeKlassPtr* TypeKlassPtr::make(PTR ptr, ciKlass* k, Offset offset) { assert(k == NULL || k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop"); ! return (TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset))->hashcons(); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeKlassPtr::eq( const Type *t ) const { const TypeKlassPtr *p = t->is_klassptr(); ! return klass() == p->klass() && TypePtr::eq(p); } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeKlassPtr::hash(void) const { ! return java_add(klass() != NULL ? klass()->hash() : (jint)0, (jint)TypePtr::hash()); } //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants --- 5356,5389 ---- // Not-null object klass or below const TypeKlassPtr *TypeKlassPtr::OBJECT; const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL; //------------------------------TypeKlassPtr----------------------------------- ! TypeKlassPtr::TypeKlassPtr(PTR ptr, ciKlass* klass, Offset offset, bool flat_array) ! : TypePtr(KlassPtr, ptr, offset), _klass(klass), _klass_is_exact(ptr == Constant), _flat_array(flat_array) { ! assert(!klass->is_valuetype() || !klass->flatten_array() || flat_array, "incorrect flatten array bit"); ! assert(!flat_array || can_be_value_type(), "incorrect flatten array bit"); } //------------------------------make------------------------------------------- // ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant ! const TypeKlassPtr* TypeKlassPtr::make(PTR ptr, ciKlass* k, Offset offset, bool value) { assert(k == NULL || k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop"); ! return (TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset, value))->hashcons(); } //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeKlassPtr::eq( const Type *t ) const { const TypeKlassPtr *p = t->is_klassptr(); ! return klass() == p->klass() && TypePtr::eq(p) && flat_array() == p->flat_array(); } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeKlassPtr::hash(void) const { ! return java_add(java_add(klass() != NULL ? klass()->hash() : (jint)0, (jint)TypePtr::hash()), (jint)flat_array()); } //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants
*** 5479,5504 **** //------------------------------add_offset------------------------------------- // Access internals of klass object const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const { ! return make( _ptr, klass(), xadd_offset(offset) ); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const { assert(_base == KlassPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(ptr, _klass, _offset); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeKlassPtr::cast_to_exactness(bool klass_is_exact) const { if( klass_is_exact == _klass_is_exact ) return this; if (!UseExactTypes) return this; ! return make(klass_is_exact ? Constant : NotNull, _klass, _offset); } //-----------------------------as_instance_type-------------------------------- // Corresponding type for an instance of the given class. --- 5513,5538 ---- //------------------------------add_offset------------------------------------- // Access internals of klass object const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const { ! return make(_ptr, klass(), xadd_offset(offset), flat_array()); } //------------------------------cast_to_ptr_type------------------------------- const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const { assert(_base == KlassPtr, "subclass must override cast_to_ptr_type"); if( ptr == _ptr ) return this; ! return make(ptr, _klass, _offset, _flat_array); } //-----------------------------cast_to_exactness------------------------------- const Type *TypeKlassPtr::cast_to_exactness(bool klass_is_exact) const { if( klass_is_exact == _klass_is_exact ) return this; if (!UseExactTypes) return this; ! return make(klass_is_exact ? Constant : NotNull, _klass, _offset, _flat_array); } //-----------------------------as_instance_type-------------------------------- // Corresponding type for an instance of the given class.
*** 5509,5518 **** --- 5543,5555 ---- bool xk = klass_is_exact(); //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0); const TypeOopPtr* toop = TypeOopPtr::make_from_klass_raw(k); guarantee(toop != NULL, "need type for given klass"); toop = toop->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr(); + if (flat_array() && !klass()->is_valuetype()) { + toop = toop->is_instptr()->cast_to_flat_array(); + } return toop->cast_to_exactness(xk)->is_oopptr(); } //------------------------------xmeet------------------------------------------
*** 5551,5561 **** case TopPTR: return this; case Null: if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); case AnyNull: ! return make( ptr, klass(), offset ); case BotPTR: case NotNull: return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); default: typerr(t); } --- 5588,5598 ---- case TopPTR: return this; case Null: if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); case AnyNull: ! return make(ptr, klass(), offset, flat_array()); case BotPTR: case NotNull: return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth()); default: typerr(t); }
*** 5592,5617 **** if (klass() == NULL || tkls->klass() == NULL) { ciKlass* k = NULL; if (ptr == Constant) { k = (klass() == NULL) ? tkls->klass() : klass(); } ! return make(ptr, k, off); } // 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 // not-loaded classes ! if( ptr != Constant && tkls->klass()->equals(klass()) ) { ! return make( ptr, klass(), off ); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tkls_klass = tkls->klass(); ciKlass* this_klass = this->klass(); assert( tkls_klass->is_loaded(), "This class should have been loaded."); assert( this_klass->is_loaded(), "This class should have been loaded."); // If 'this' type is above the centerline and is a superclass of the // other, we can treat 'this' as having the same type as the other. if ((above_centerline(this->ptr())) && tkls_klass->is_subtype_of(this_klass)) { --- 5629,5657 ---- if (klass() == NULL || tkls->klass() == NULL) { ciKlass* k = NULL; if (ptr == Constant) { k = (klass() == NULL) ? tkls->klass() : klass(); } ! return make(ptr, k, off, false); } // 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 // not-loaded classes ! if (ptr != Constant && tkls->klass()->equals(klass()) && flat_array() == tkls->flat_array()) { ! return make(ptr, klass(), off, flat_array()); } // Classes require inspection in the Java klass hierarchy. Must be loaded. ciKlass* tkls_klass = tkls->klass(); ciKlass* this_klass = this->klass(); assert( tkls_klass->is_loaded(), "This class should have been loaded."); assert( this_klass->is_loaded(), "This class should have been loaded."); + bool tkls_flat_array = tkls->flat_array(); + bool this_flat_array = this->flat_array(); + bool flat_array = below_centerline(ptr) ? (this_flat_array && tkls_flat_array) : (this_flat_array || tkls_flat_array); // If 'this' type is above the centerline and is a superclass of the // other, we can treat 'this' as having the same type as the other. if ((above_centerline(this->ptr())) && tkls_klass->is_subtype_of(this_klass)) {
*** 5635,5664 **** else if (above_centerline(this->ptr())); else if (above_centerline(tkls->ptr())); else ptr = NotNull; } ! return make( ptr, this_klass, off ); } // Else classes are not equal // Since klasses are different, we require the 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; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tkls_klass); ! return make( ptr, k, off ); } // End of case KlassPtr } // End of switch return this; // Return the double constant } //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual const Type *TypeKlassPtr::xdual() const { ! return new TypeKlassPtr( dual_ptr(), klass(), dual_offset() ); } //------------------------------get_con---------------------------------------- intptr_t TypeKlassPtr::get_con() const { assert( _ptr == Null || _ptr == Constant, "" ); --- 5675,5704 ---- else if (above_centerline(this->ptr())); else if (above_centerline(tkls->ptr())); else ptr = NotNull; } ! return make(ptr, this_klass, off, flat_array); } // Else classes are not equal // Since klasses are different, we require the 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; // Now we find the LCA of Java classes ciKlass* k = this_klass->least_common_ancestor(tkls_klass); ! return make(ptr, k, off, k->is_valuetype() && k->flatten_array()); } // End of case KlassPtr } // End of switch return this; // Return the double constant } //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual const Type *TypeKlassPtr::xdual() const { ! return new TypeKlassPtr(dual_ptr(), klass(), dual_offset(), flat_array()); } //------------------------------get_con---------------------------------------- intptr_t TypeKlassPtr::get_con() const { assert( _ptr == Null || _ptr == Constant, "" );
< prev index next >