< 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 >