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