src/share/vm/opto/type.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/type.hpp
src/share/vm/opto/type.hpp
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
*** 157,166 ****
--- 157,171 ----
// lazily, on demand, and cached in _dual.
const Type *_dual; // Cached dual value
// Table for efficient dualing of base types
static const TYPES dual_type[lastype];
+ #ifdef ASSERT
+ // One type is interface, the other is oop
+ virtual bool interface_vs_oop_helper(const Type *t) const;
+ #endif
+
protected:
// Each class of type is also identified by its base.
const TYPES _base; // Enum of Types type
Type( TYPES t ) : _dual(NULL), _base(t) {} // Simple types
*** 374,383 ****
--- 379,391 ----
static const Type* make_from_constant(ciConstant constant,
bool require_constant = false,
bool is_autobox_cache = false);
+ // Speculative type. See TypeInstPtr
+ virtual ciKlass* speculative_type() const { return NULL; }
+
private:
// support arrays
static const BasicType _basic_type[];
static const Type* _zero_type[T_CONFLICT+1];
static const Type* _const_basic_type[T_CONFLICT+1];
*** 782,792 ****
//------------------------------TypeOopPtr-------------------------------------
// Some kind of oop (Java pointer), either klass or instance or array.
class TypeOopPtr : public TypePtr {
protected:
! TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id );
public:
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
enum {
--- 790,800 ----
//------------------------------TypeOopPtr-------------------------------------
// Some kind of oop (Java pointer), either klass or instance or array.
class TypeOopPtr : public TypePtr {
protected:
! TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative);
public:
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
enum {
*** 808,822 ****
--- 816,851 ----
// If not InstanceTop or InstanceBot, indicates that this is
// a particular instance of this type which is distinct.
// This is the the node index of the allocation node creating this instance.
int _instance_id;
+ // Extra type information profiling gave us. We propagate it the
+ // same way the rest of the type info is propagated. If we want to
+ // use it, then we have to emit a guard: this part of the type is
+ // not something we know but something we speculate about the type.
+ const TypeOopPtr* _speculative;
+
static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
int dual_instance_id() const;
int meet_instance_id(int uid) const;
+ // dual of the speculative part of the type
+ const TypeOopPtr* dual_speculative() const;
+ // meet of the speculative parts of 2 types
+ const TypeOopPtr* meet_speculative(const TypeOopPtr* other) const;
+ // Are the speculative parts of 2 types equal?
+ bool eq_speculative(const TypeOopPtr* other) const;
+ // Hash of the speculative part of the type
+ int hash_speculative() const;
+ // add offset to the speculative part of the type
+ const TypeOopPtr* add_offset_speculative(intptr_t offset) const;
+ #ifndef PRODUCT
+ // dump the speculative part of the type
+ void dump_speculative(outputStream *st) const;
+ #endif
+
public:
// Creates a type given a klass. Correctly handles multi-dimensional arrays
// Respects UseUniqueSubclasses.
// If the klass is final, the resulting type will be exact.
static const TypeOopPtr* make_from_klass(ciKlass* klass) {
*** 839,849 ****
static const TypeOopPtr* make_from_constant(ciObject* o,
bool require_constant = false,
bool not_null_elements = false);
// Make a generic (unclassed) pointer to an oop.
! static const TypeOopPtr* make(PTR ptr, int offset, int instance_id);
ciObject* const_oop() const { return _const_oop; }
virtual ciKlass* klass() const { return _klass; }
bool klass_is_exact() const { return _klass_is_exact; }
--- 868,878 ----
static const TypeOopPtr* make_from_constant(ciObject* o,
bool require_constant = false,
bool not_null_elements = false);
// Make a generic (unclassed) pointer to an oop.
! static const TypeOopPtr* make(PTR ptr, int offset, int instance_id, const TypeOopPtr* speculative);
ciObject* const_oop() const { return _const_oop; }
virtual ciKlass* klass() const { return _klass; }
bool klass_is_exact() const { return _klass_is_exact; }
*** 853,862 ****
--- 882,892 ----
bool is_ptr_to_narrowklass_nv() const { return _is_ptr_to_narrowklass; }
bool is_ptr_to_boxed_value() const { return _is_ptr_to_boxed_value; }
bool is_known_instance() const { return _instance_id > 0; }
int instance_id() const { return _instance_id; }
bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
+ const TypeOopPtr* speculative() const { return _speculative; }
virtual intptr_t get_con() const;
virtual const Type *cast_to_ptr_type(PTR ptr) const;
*** 866,894 ****
// corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const;
virtual const TypePtr *add_offset( intptr_t offset ) const;
! virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
// Do not allow interface-vs.-noninterface joins to collapse to top.
virtual const Type *filter( const Type *kills ) const;
// Convenience common pre-built type.
static const TypeOopPtr *BOTTOM;
#ifndef PRODUCT
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
#endif
};
//------------------------------TypeInstPtr------------------------------------
// Class of Java object pointers, pointing either to non-array Java instances
// or to a Klass* (including array klasses).
class TypeInstPtr : public TypeOopPtr {
! TypeInstPtr( PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id );
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
ciSymbol* _name; // class name
--- 896,940 ----
// corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const;
virtual const TypePtr *add_offset( intptr_t offset ) const;
+ // Return same type without a speculative part
+ virtual const TypeOopPtr* remove_speculative() const;
! virtual const Type *xmeet(const Type *t) const;
virtual const Type *xdual() const; // Compute dual right now.
+ // the core of the computation of the meet for TypeOopPtr and for its subclasses
+ virtual const Type *xmeet_helper(const Type *t) const;
// Do not allow interface-vs.-noninterface joins to collapse to top.
virtual const Type *filter( const Type *kills ) const;
// Convenience common pre-built type.
static const TypeOopPtr *BOTTOM;
#ifndef PRODUCT
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
#endif
+
+ // The speculative type if any: what klass we believe this is but a
+ // guard must be emitted
+ ciKlass* speculative_type() const {
+ if (_speculative != NULL) {
+ const TypeOopPtr* speculative = _speculative->join(this)->is_oopptr();
+ if (speculative->klass_is_exact()) {
+ return speculative->klass();
+ }
+ }
+ return NULL;
+ }
};
//------------------------------TypeInstPtr------------------------------------
// Class of Java object pointers, pointing either to non-array Java instances
// or to a Klass* (including array klasses).
class TypeInstPtr : public TypeOopPtr {
! TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative);
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
ciSymbol* _name; // class name
*** 897,930 ****
bool is_loaded() const { return _klass->is_loaded(); }
// Make a pointer to a constant oop.
static const TypeInstPtr *make(ciObject* o) {
! return make(TypePtr::Constant, o->klass(), true, o, 0);
}
// Make a pointer to a constant oop with offset.
static const TypeInstPtr *make(ciObject* o, int offset) {
! return make(TypePtr::Constant, o->klass(), true, o, offset);
}
// Make a pointer to some value of type klass.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass) {
! return make(ptr, klass, false, NULL, 0);
}
// Make a pointer to some non-polymorphic value of exactly type klass.
static const TypeInstPtr *make_exact(PTR ptr, ciKlass* klass) {
! return make(ptr, klass, true, NULL, 0);
}
// Make a pointer to some value of type klass with offset.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass, int offset) {
! return make(ptr, klass, false, NULL, offset);
}
// Make a pointer to an oop.
! static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
/** Create constant type for a constant boxed value */
const Type* get_const_boxed_value() const;
// If this is a java.lang.Class constant, return the type for it or NULL.
--- 943,976 ----
bool is_loaded() const { return _klass->is_loaded(); }
// Make a pointer to a constant oop.
static const TypeInstPtr *make(ciObject* o) {
! return make(TypePtr::Constant, o->klass(), true, o, 0, InstanceBot);
}
// Make a pointer to a constant oop with offset.
static const TypeInstPtr *make(ciObject* o, int offset) {
! return make(TypePtr::Constant, o->klass(), true, o, offset, InstanceBot);
}
// Make a pointer to some value of type klass.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass) {
! return make(ptr, klass, false, NULL, 0, InstanceBot);
}
// Make a pointer to some non-polymorphic value of exactly type klass.
static const TypeInstPtr *make_exact(PTR ptr, ciKlass* klass) {
! return make(ptr, klass, true, NULL, 0, InstanceBot);
}
// Make a pointer to some value of type klass with offset.
static const TypeInstPtr *make(PTR ptr, ciKlass* klass, int offset) {
! return make(ptr, klass, false, NULL, offset, InstanceBot);
}
// Make a pointer to an oop.
! static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL);
/** Create constant type for a constant boxed value */
const Type* get_const_boxed_value() const;
// If this is a java.lang.Class constant, return the type for it or NULL.
*** 937,948 ****
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypePtr *add_offset( intptr_t offset ) const;
! virtual const Type *xmeet( const Type *t ) const;
virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
// Convenience common pre-built types.
static const TypeInstPtr *NOTNULL;
--- 983,997 ----
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypePtr *add_offset( intptr_t offset ) const;
+ // Return same type without a speculative part
+ virtual const TypeOopPtr* remove_speculative() const;
! // the core of the computation of the meet of 2 types
! virtual const Type *xmeet_helper(const Type *t) const;
virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
// Convenience common pre-built types.
static const TypeInstPtr *NOTNULL;
*** 957,968 ****
//------------------------------TypeAryPtr-------------------------------------
// Class of Java array pointers
class TypeAryPtr : public TypeOopPtr {
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
! int offset, int instance_id, bool is_autobox_cache )
! : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id),
_ary(ary),
_is_autobox_cache(is_autobox_cache)
{
#ifdef ASSERT
if (k != NULL) {
--- 1006,1017 ----
//------------------------------TypeAryPtr-------------------------------------
// Class of Java array pointers
class TypeAryPtr : public TypeOopPtr {
TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
! int offset, int instance_id, bool is_autobox_cache, const TypeOopPtr* speculative)
! : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id, speculative),
_ary(ary),
_is_autobox_cache(is_autobox_cache)
{
#ifdef ASSERT
if (k != NULL) {
*** 996,1008 ****
const TypeInt* size() const { return _ary->_size; }
bool is_stable() const { return _ary->_stable; }
bool is_autobox_cache() const { return _is_autobox_cache; }
! static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Constant pointer to array
! static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, bool is_autobox_cache = false);
// Return a 'ptr' version of this type
virtual const Type *cast_to_ptr_type(PTR ptr) const;
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
--- 1045,1057 ----
const TypeInt* size() const { return _ary->_size; }
bool is_stable() const { return _ary->_stable; }
bool is_autobox_cache() const { return _is_autobox_cache; }
! static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL);
// Constant pointer to array
! static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, bool is_autobox_cache = false);
// Return a 'ptr' version of this type
virtual const Type *cast_to_ptr_type(PTR ptr) const;
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
*** 1012,1023 ****
virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
virtual const TypeInt* narrow_size_type(const TypeInt* size) const;
virtual bool empty(void) const; // TRUE if type is vacuous
virtual const TypePtr *add_offset( intptr_t offset ) const;
! virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
int stable_dimension() const;
--- 1061,1075 ----
virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
virtual const TypeInt* narrow_size_type(const TypeInt* size) const;
virtual bool empty(void) const; // TRUE if type is vacuous
virtual const TypePtr *add_offset( intptr_t offset ) const;
+ // Return same type without a speculative part
+ virtual const TypeOopPtr* remove_speculative() const;
! // the core of the computation of the meet of 2 types
! virtual const Type *xmeet_helper(const Type *t) const;
virtual const Type *xdual() const; // Compute dual right now.
const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
int stable_dimension() const;
src/share/vm/opto/type.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File