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