< prev index next >

src/hotspot/share/opto/type.hpp

Print this page

        

*** 23,34 **** --- 23,36 ---- */ #ifndef SHARE_OPTO_TYPE_HPP #define SHARE_OPTO_TYPE_HPP + #include "ci/ciValueKlass.hpp" #include "opto/adlcVMDeps.hpp" #include "runtime/handles.hpp" + #include "runtime/sharedRuntime.hpp" // Portions of code courtesy of Clifford Click // Optimization - Graph Style
*** 50,59 **** --- 52,62 ---- class TypeNarrowPtr; class TypeNarrowOop; class TypeNarrowKlass; class TypeAry; class TypeTuple; + class TypeValueType; class TypeVect; class TypeVectS; class TypeVectD; class TypeVectX; class TypeVectY;
*** 90,99 **** --- 93,103 ---- VectorS, // 32bit Vector types VectorD, // 64bit Vector types VectorX, // 128bit Vector types VectorY, // 256bit Vector types VectorZ, // 512bit Vector types + ValueType, // Value type AnyPtr, // Any old raw, klass, inst, or array pointer RawPtr, // Raw (non-oop) pointers OopPtr, // Any and all Java heap entities InstPtr, // Instance pointers (non-array objects)
*** 121,130 **** --- 125,158 ---- enum OFFSET_SIGNALS { OffsetTop = -2000000000, // undefined offset OffsetBot = -2000000001 // any possible offset }; + class Offset { + private: + int _offset; + + public: + explicit Offset(int offset) : _offset(offset) {} + + const Offset meet(const Offset other) const; + const Offset dual() const; + const Offset add(intptr_t offset) const; + bool operator==(const Offset& other) const { + return _offset == other._offset; + } + bool operator!=(const Offset& other) const { + return _offset != other._offset; + } + int get() const { return _offset; } + + void dump2(outputStream *st) const; + + static const Offset top; + static const Offset bottom; + }; + // Min and max WIDEN values. enum WIDEN { WidenMin = 0, WidenMax = 3 };
*** 183,193 **** inline void* operator new( size_t x ) throw() { Compile* compile = Compile::current(); compile->set_type_last_size(x); void *temp = compile->type_arena()->Amalloc_D(x); - compile->set_type_hwm(temp); return temp; } inline void operator delete( void* ptr ) { Compile* compile = Compile::current(); compile->type_arena()->Afree(ptr,compile->type_last_size()); --- 211,220 ----
*** 271,283 **** // Returns true if this pointer points at memory which contains a // compressed oop references. bool is_ptr_to_narrowoop() const; bool is_ptr_to_narrowklass() const; - bool is_ptr_to_boxing_obj() const; - - // Convenience access float getf() const; double getd() const; const TypeInt *is_int() const; --- 298,307 ----
*** 306,324 **** --- 330,353 ---- const TypeOopPtr *is_oopptr() const; // Java-style GC'd pointer const TypeInstPtr *isa_instptr() const; // Returns NULL if not InstPtr const TypeInstPtr *is_instptr() const; // Instance const TypeAryPtr *isa_aryptr() const; // Returns NULL if not AryPtr const TypeAryPtr *is_aryptr() const; // Array oop + const TypeValueType* isa_valuetype() const; // Returns NULL if not Value Type + const TypeValueType* is_valuetype() const; // Value Type const TypeMetadataPtr *isa_metadataptr() const; // Returns NULL if not oop ptr type const TypeMetadataPtr *is_metadataptr() const; // Java-style GC'd pointer const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr virtual bool is_finite() const; // Has a finite value virtual bool is_nan() const; // Is not a number (NaN) + bool is_valuetypeptr() const; + virtual ciValueKlass* value_klass() const; + // Returns this ptr type or the equivalent ptr type for this compressed pointer. const TypePtr* make_ptr() const; // Returns this oopptr type or the equivalent oopptr type for this compressed pointer. // Asserts if the underlying type is not an oopptr or narrowoop.
*** 661,672 **** assert(i < _cnt, "oob"); _fields[i] = t; } static const TypeTuple *make( uint cnt, const Type **fields ); ! static const TypeTuple *make_range(ciSignature *sig); ! static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig); // Subroutine call type with space allocated for argument types // Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly static const Type **fields( uint arg_cnt ); --- 690,701 ---- assert(i < _cnt, "oob"); _fields[i] = t; } static const TypeTuple *make( uint cnt, const Type **fields ); ! static const TypeTuple *make_range(ciSignature* sig, bool ret_vt_fields = false); ! static const TypeTuple *make_domain(ciMethod* method, bool vt_fields_as_args = false); // Subroutine call type with space allocated for argument types // Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly static const Type **fields( uint arg_cnt );
*** 691,731 **** }; //------------------------------TypeAry---------------------------------------- // Class of Array Types class TypeAry : public Type { ! TypeAry(const Type* elem, const TypeInt* size, bool stable) : Type(Array), ! _elem(elem), _size(size), _stable(stable) {} 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 virtual bool empty(void) const; // TRUE if type is vacuous private: const Type *_elem; // Element type of array const TypeInt *_size; // Elements in array const bool _stable; // Are elements @Stable? friend class TypeAryPtr; public: ! static const TypeAry* make(const Type* elem, const TypeInt* size, bool stable = false); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. bool ary_must_be_exact() const; // true if arrays of such are never generic virtual const Type* remove_speculative() const; virtual const Type* cleanup_speculative() const; #ifdef ASSERT // One type is interface, the other is oop virtual bool interface_vs_oop(const Type *t) const; #endif #ifndef PRODUCT virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping #endif }; //------------------------------TypeVect--------------------------------------- // Class of Vector Types class TypeVect : public Type { const Type* _elem; // Vector's element type const uint _length; // Elements in vector (power of 2) --- 720,804 ---- }; //------------------------------TypeAry---------------------------------------- // Class of Array Types class TypeAry : public Type { ! TypeAry(const Type* elem, const TypeInt* size, bool stable, bool not_flat, bool not_null_free) : Type(Array), ! _elem(elem), _size(size), _stable(stable), _not_flat(not_flat), _not_null_free(not_null_free) {} 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 virtual bool empty(void) const; // TRUE if type is vacuous private: const Type *_elem; // Element type of array const TypeInt *_size; // Elements in array const bool _stable; // Are elements @Stable? + + // Value type array properties + const bool _not_flat; // Array is never flattened + const bool _not_null_free; // Array is never null-free + friend class TypeAryPtr; public: ! static const TypeAry* make(const Type* elem, const TypeInt* size, bool stable = false, ! bool not_flat = false, bool not_null_free = false); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. bool ary_must_be_exact() const; // true if arrays of such are never generic virtual const Type* remove_speculative() const; virtual const Type* cleanup_speculative() const; + #ifdef ASSERT // One type is interface, the other is oop virtual bool interface_vs_oop(const Type *t) const; #endif #ifndef PRODUCT virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping #endif }; + + //------------------------------TypeValue--------------------------------------- + // Class of Value Type Types + class TypeValueType : public Type { + private: + ciValueKlass* _vk; + bool _larval; + + protected: + TypeValueType(ciValueKlass* vk, bool larval) + : Type(ValueType), + _vk(vk), _larval(larval) { + } + + public: + static const TypeValueType* make(ciValueKlass* vk, bool larval = false); + virtual ciValueKlass* value_klass() const { return _vk; } + bool larval() const { return _larval; } + + 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 + virtual bool empty(void) const; // TRUE if type is vacuous + + virtual const Type* xmeet(const Type* t) const; + virtual const Type* xdual() const; // Compute dual right now. + + virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const { return false; } + virtual bool would_improve_ptr(ProfilePtrKind ptr_kind) const { return false; } + + static const TypeValueType *BOTTOM; + + #ifndef PRODUCT + virtual void dump2(Dict &d, uint, outputStream* st) const; // Specialized per-Type dumping + #endif + }; + //------------------------------TypeVect--------------------------------------- // Class of Vector Types class TypeVect : public Type { const Type* _elem; // Vector's element type const uint _length; // Elements in vector (power of 2)
*** 801,811 **** class TypePtr : public Type { friend class TypeNarrowPtr; public: enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR }; protected: ! TypePtr(TYPES t, PTR ptr, int offset, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom) : Type(t), _speculative(speculative), _inline_depth(inline_depth), _offset(offset), _ptr(ptr) {} static const PTR ptr_meet[lastPTR][lastPTR]; --- 874,884 ---- class TypePtr : public Type { friend class TypeNarrowPtr; public: enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR }; protected: ! TypePtr(TYPES t, PTR ptr, Offset offset, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom) : Type(t), _speculative(speculative), _inline_depth(inline_depth), _offset(offset), _ptr(ptr) {} static const PTR ptr_meet[lastPTR][lastPTR];
*** 844,879 **** #ifndef PRODUCT void dump_inline_depth(outputStream *st) const; #endif public: ! const int _offset; // Offset into oop, with TOP & BOT const PTR _ptr; // Pointer equivalence class ! const int offset() const { return _offset; } const PTR ptr() const { return _ptr; } ! static const TypePtr *make(TYPES t, PTR ptr, int offset, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); // Return a 'ptr' version of this type virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual intptr_t get_con() const; ! int xadd_offset( intptr_t offset ) const; virtual const TypePtr *add_offset( intptr_t offset ) const; 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 virtual bool empty(void) const; // TRUE if type is vacuous virtual const Type *xmeet( const Type *t ) const; virtual const Type *xmeet_helper( const Type *t ) const; ! int meet_offset( int offset ) const; ! int dual_offset( ) const; virtual const Type *xdual() const; // Compute dual right now. // meet, dual and join over pointer equivalence sets PTR meet_ptr( const PTR in_ptr ) const { return ptr_meet[in_ptr][ptr()]; } PTR dual_ptr() const { return ptr_dual[ptr()]; } --- 917,954 ---- #ifndef PRODUCT void dump_inline_depth(outputStream *st) const; #endif public: ! const Offset _offset; // Offset into oop, with TOP & BOT const PTR _ptr; // Pointer equivalence class ! const int offset() const { return _offset.get(); } const PTR ptr() const { return _ptr; } ! static const TypePtr* make(TYPES t, PTR ptr, Offset offset, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); // Return a 'ptr' version of this type virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual intptr_t get_con() const; ! Offset xadd_offset(intptr_t offset) const; virtual const TypePtr *add_offset( intptr_t offset ) const; + virtual const int flattened_offset() const { return offset(); } + 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 virtual bool empty(void) const; // TRUE if type is vacuous virtual const Type *xmeet( const Type *t ) const; virtual const Type *xmeet_helper( const Type *t ) const; ! Offset meet_offset(int offset) const; ! Offset dual_offset() const; virtual const Type *xdual() const; // Compute dual right now. // meet, dual and join over pointer equivalence sets PTR meet_ptr( const PTR in_ptr ) const { return ptr_meet[in_ptr][ptr()]; } PTR dual_ptr() const { return ptr_dual[ptr()]; }
*** 914,924 **** //------------------------------TypeRawPtr------------------------------------- // Class of raw pointers, pointers to things other than Oops. Examples // include the stack pointer, top of heap, card-marking area, handles, etc. class TypeRawPtr : public TypePtr { protected: ! TypeRawPtr( PTR ptr, address bits ) : TypePtr(RawPtr,ptr,0), _bits(bits){} public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing const address _bits; // Constant value, if applicable --- 989,999 ---- //------------------------------TypeRawPtr------------------------------------- // Class of raw pointers, pointers to things other than Oops. Examples // include the stack pointer, top of heap, card-marking area, handles, etc. class TypeRawPtr : public TypePtr { protected: ! TypeRawPtr(PTR ptr, address bits) : TypePtr(RawPtr,ptr,Offset(0)), _bits(bits){} public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing const address _bits; // Constant value, if applicable
*** 945,956 **** //------------------------------TypeOopPtr------------------------------------- // Some kind of oop (Java pointer), either 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 TypePtr* speculative, int inline_depth); 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 { --- 1020,1031 ---- //------------------------------TypeOopPtr------------------------------------- // Some kind of oop (Java pointer), either instance or array. class TypeOopPtr : public TypePtr { protected: ! TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, Offset field_offset, ! int instance_id, const TypePtr* speculative, int inline_depth); 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 {
*** 1005,1015 **** // If require_constant, produce a NULL if a singleton is not possible. static const TypeOopPtr* make_from_constant(ciObject* o, bool require_constant = false); // Make a generic (unclassed) pointer to an oop. ! static const TypeOopPtr* make(PTR ptr, int offset, int instance_id, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); ciObject* const_oop() const { return _const_oop; } virtual ciKlass* klass() const { return _klass; } --- 1080,1090 ---- // If require_constant, produce a NULL if a singleton is not possible. static const TypeOopPtr* make_from_constant(ciObject* o, bool require_constant = false); // Make a generic (unclassed) pointer to an oop. ! static const TypeOopPtr* make(PTR ptr, Offset offset, int instance_id, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); ciObject* const_oop() const { return _const_oop; } virtual ciKlass* klass() const { return _klass; }
*** 1020,1030 **** bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; } 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; } virtual intptr_t get_con() const; virtual const Type *cast_to_ptr_type(PTR ptr) const; --- 1095,1108 ---- bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; } 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.get() >= 0; } ! ! virtual bool can_be_value_type() const { return EnableValhalla && can_be_value_type_raw(); } ! virtual bool can_be_value_type_raw() const { return _klass == NULL || !_klass->is_loaded() || _klass->is_valuetype() || ((_klass->is_java_lang_Object() || _klass->is_interface()) && !klass_is_exact()); } virtual intptr_t get_con() const; virtual const Type *cast_to_ptr_type(PTR ptr) const;
*** 1060,1070 **** //------------------------------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 TypePtr* speculative, int inline_depth); virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing ciSymbol* _name; // class name --- 1138,1148 ---- //------------------------------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, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth); virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing ciSymbol* _name; // class name
*** 1074,1118 **** 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 TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); /** 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. // Pass to Type::get_const_type to turn it to a type, which will usually // be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc. ! ciType* java_mirror_type() const; virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual const Type *cast_to_exactness(bool klass_is_exact) const; --- 1152,1196 ---- 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, Offset(0), InstanceBot); } // Make a pointer to a constant oop with offset. ! static const TypeInstPtr* make(ciObject* o, Offset 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, Offset(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, Offset(0), InstanceBot); } // Make a pointer to some value of type klass with offset. ! static const TypeInstPtr *make(PTR ptr, ciKlass* klass, Offset 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, Offset offset, int instance_id = InstanceBot, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); /** 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. // Pass to Type::get_const_type to turn it to a type, which will usually // be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc. ! ciType* java_mirror_type(bool* is_indirect_type = NULL) const; virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual const Type *cast_to_exactness(bool klass_is_exact) const;
*** 1144,1159 **** }; //------------------------------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 TypePtr* speculative, int inline_depth) ! : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id, speculative, inline_depth), _ary(ary), ! _is_autobox_cache(is_autobox_cache) { #ifdef ASSERT if (k != NULL) { // Verify that specified klass and TypeAryPtr::klass() follow the same rules. ciKlass* ck = compute_klass(true); --- 1222,1238 ---- }; //------------------------------TypeAryPtr------------------------------------- // Class of Java array pointers class TypeAryPtr : public TypeOopPtr { ! TypeAryPtr(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, ! Offset offset, Offset field_offset, int instance_id, bool is_autobox_cache, ! const TypePtr* speculative, int inline_depth) ! : TypeOopPtr(AryPtr, ptr, k, xk, o, offset, field_offset, instance_id, speculative, inline_depth), _ary(ary), ! _is_autobox_cache(is_autobox_cache), ! _field_offset(field_offset) { #ifdef ASSERT if (k != NULL) { // Verify that specified klass and TypeAryPtr::klass() follow the same rules. ciKlass* ck = compute_klass(true);
*** 1172,1181 **** --- 1251,1266 ---- } virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing const TypeAry *_ary; // Array we point into const bool _is_autobox_cache; + // For flattened value type arrays, each field of the value type in + // the array has its own memory slice so we need to keep track of + // which field is accessed + const Offset _field_offset; + Offset meet_field_offset(const Type::Offset offset) const; + Offset dual_field_offset() const; ciKlass* compute_klass(DEBUG_ONLY(bool verify = false)) const; public: // Accessors
*** 1183,1203 **** const TypeAry* ary() const { return _ary; } const Type* elem() const { return _ary->_elem; } 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 TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); // 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 TypePtr* speculative = NULL, ! int inline_depth = InlineDepthBottom, 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; --- 1268,1295 ---- const TypeAry* ary() const { return _ary; } const Type* elem() const { return _ary->_elem; } const TypeInt* size() const { return _ary->_size; } bool is_stable() const { return _ary->_stable; } + // Value type array properties + bool is_not_flat() const { return _ary->_not_flat; } + bool is_not_null_free() const { return _ary->_not_null_free; } + bool is_autobox_cache() const { return _is_autobox_cache; } ! static const TypeAryPtr* make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, Offset offset, ! Offset field_offset = Offset::bottom, int instance_id = InstanceBot, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); // Constant pointer to array ! static const TypeAryPtr* make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, Offset offset, ! Offset field_offset = Offset::bottom, int instance_id = InstanceBot, const TypePtr* speculative = NULL, ! int inline_depth = InlineDepthBottom, ! 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;
*** 1212,1233 **** --- 1304,1336 ---- virtual bool empty(void) const; // TRUE if type is vacuous virtual const TypePtr *add_offset( intptr_t offset ) const; // Speculative type helper methods. virtual const Type* remove_speculative() const; + virtual const Type* cleanup_speculative() const; virtual const TypePtr* with_inline_depth(int depth) const; virtual const TypePtr* with_instance_id(int instance_id) 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_not_flat(bool not_flat = true) const; + const TypeAryPtr* cast_to_not_null_free(bool not_null_free = true) const; + const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const; int stable_dimension() const; const TypeAryPtr* cast_to_autobox_cache(bool cache) const; + const int flattened_offset() const; + const Offset field_offset() const { return _field_offset; } + const TypeAryPtr* with_field_offset(int offset) const; + const TypePtr* add_field_offset_and_offset(intptr_t offset) const; + + virtual bool can_be_value_type() const { return false; } + // Convenience common pre-built types. static const TypeAryPtr *RANGE; static const TypeAryPtr *OOPS; static const TypeAryPtr *NARROWOOPS; static const TypeAryPtr *BYTES;
*** 1235,1244 **** --- 1338,1348 ---- static const TypeAryPtr *CHARS; static const TypeAryPtr *INTS; static const TypeAryPtr *LONGS; static const TypeAryPtr *FLOATS; static const TypeAryPtr *DOUBLES; + static const TypeAryPtr *VALUES; // selects one of the above: static const TypeAryPtr *get_array_body_type(BasicType elem) { assert((uint)elem <= T_CONFLICT && _array_body_type[elem] != NULL, "bad elem type"); return _array_body_type[elem]; }
*** 1255,1265 **** //------------------------------TypeMetadataPtr------------------------------------- // Some kind of metadata, either Method*, MethodData* or CPCacheOop class TypeMetadataPtr : public TypePtr { protected: ! TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset); // Do not allow interface-vs.-noninterface joins to collapse to top. virtual const Type *filter_helper(const Type *kills, bool include_speculative) const; public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing --- 1359,1369 ---- //------------------------------TypeMetadataPtr------------------------------------- // Some kind of metadata, either Method*, MethodData* or CPCacheOop class TypeMetadataPtr : public TypePtr { protected: ! TypeMetadataPtr(PTR ptr, ciMetadata* metadata, Offset offset); // Do not allow interface-vs.-noninterface joins to collapse to top. virtual const Type *filter_helper(const Type *kills, bool include_speculative) const; public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing
*** 1267,1277 **** private: ciMetadata* _metadata; public: ! static const TypeMetadataPtr* make(PTR ptr, ciMetadata* m, int offset); static const TypeMetadataPtr* make(ciMethod* m); static const TypeMetadataPtr* make(ciMethodData* m); ciMetadata* metadata() const { return _metadata; } --- 1371,1381 ---- private: ciMetadata* _metadata; public: ! static const TypeMetadataPtr* make(PTR ptr, ciMetadata* m, Offset offset); static const TypeMetadataPtr* make(ciMethod* m); static const TypeMetadataPtr* make(ciMethodData* m); ciMetadata* metadata() const { return _metadata; }
*** 1294,1354 **** }; //------------------------------TypeKlassPtr----------------------------------- // Class of Java Klass pointers class TypeKlassPtr : public TypePtr { ! TypeKlassPtr( PTR ptr, ciKlass* klass, int offset ); protected: virtual const Type *filter_helper(const Type *kills, bool include_speculative) const; 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 private: - static const TypeKlassPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact); - ciKlass* _klass; // Does the type exclude subclasses of the klass? (Inexact == polymorphic.) bool _klass_is_exact; public: - ciSymbol* name() const { return klass()->name(); } - ciKlass* klass() const { return _klass; } bool klass_is_exact() const { return _klass_is_exact; } ! bool is_loaded() const { return klass()->is_loaded(); } ! ! // 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 TypeKlassPtr* make_from_klass(ciKlass* klass) { ! return make_from_klass_common(klass, true, false); ! } ! // Same as before, but will produce an exact type, even if ! // the klass is not final, as long as it has exactly one implementation. ! static const TypeKlassPtr* make_from_klass_unique(ciKlass* klass) { ! return make_from_klass_common(klass, true, true); ! } ! // Same as before, but does not respects UseUniqueSubclasses. ! // Use this only for creating array element types. ! static const TypeKlassPtr* make_from_klass_raw(ciKlass* klass) { ! return make_from_klass_common(klass, false, false); ! } ! ! // Make a generic (unclassed) pointer to metadata. ! static const TypeKlassPtr* make(PTR ptr, int offset); // ptr to klass 'k' ! static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); } // ptr to klass 'k' with offset ! static const TypeKlassPtr *make( ciKlass* k, int offset ) { return make( TypePtr::Constant, k, offset); } // ptr to klass 'k' or sub-klass ! static const TypeKlassPtr *make( PTR ptr, ciKlass* k, int offset); virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual const Type *cast_to_exactness(bool klass_is_exact) const; --- 1398,1434 ---- }; //------------------------------TypeKlassPtr----------------------------------- // Class of Java Klass pointers class TypeKlassPtr : public TypePtr { ! TypeKlassPtr(PTR ptr, ciKlass* klass, Offset offset); protected: virtual const Type *filter_helper(const Type *kills, bool include_speculative) const; 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 private: ciKlass* _klass; // Does the type exclude subclasses of the klass? (Inexact == polymorphic.) bool _klass_is_exact; public: ciKlass* klass() const { return _klass; } bool klass_is_exact() const { return _klass_is_exact; } ! bool is_loaded() const { return klass() != NULL && klass()->is_loaded(); } // ptr to klass 'k' ! static const TypeKlassPtr* make(ciKlass* k) { return make( TypePtr::Constant, k, Offset(0)); } // ptr to klass 'k' with offset ! static const TypeKlassPtr* make(ciKlass* k, Offset offset) { return make( TypePtr::Constant, k, offset); } // ptr to klass 'k' or sub-klass ! static const TypeKlassPtr* make(PTR ptr, ciKlass* k, Offset offset); virtual const Type *cast_to_ptr_type(PTR ptr) const; virtual const Type *cast_to_exactness(bool klass_is_exact) const;
*** 1491,1508 **** }; //------------------------------TypeFunc--------------------------------------- // Class of Array Types class TypeFunc : public Type { ! TypeFunc( const TypeTuple *domain, const TypeTuple *range ) : Type(Function), _domain(domain), _range(range) {} 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 virtual bool empty(void) const; // TRUE if type is vacuous ! const TypeTuple* const _domain; // Domain of inputs ! const TypeTuple* const _range; // Range of results public: // Constants are shared among ADLC and VM enum { Control = AdlcVMDeps::Control, I_O = AdlcVMDeps::I_O, --- 1571,1600 ---- }; //------------------------------TypeFunc--------------------------------------- // Class of Array Types class TypeFunc : public Type { ! TypeFunc(const TypeTuple *domain_sig, const TypeTuple *domain_cc, const TypeTuple *range_sig, const TypeTuple *range_cc) ! : Type(Function), _domain_sig(domain_sig), _domain_cc(domain_cc), _range_sig(range_sig), _range_cc(range_cc) {} 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 virtual bool empty(void) const; // TRUE if type is vacuous ! // Domains of inputs: value type arguments are not passed by ! // reference, instead each field of the value type is passed as an ! // argument. We maintain 2 views of the argument list here: one ! // based on the signature (with a value type argument as a single ! // slot), one based on the actual calling convention (with a value ! // type argument as a list of its fields). ! const TypeTuple* const _domain_sig; ! const TypeTuple* const _domain_cc; ! // Range of results. Similar to domains: a value type result can be ! // returned in registers in which case range_cc lists all fields and ! // is the actual calling convention. ! const TypeTuple* const _range_sig; ! const TypeTuple* const _range_cc; public: // Constants are shared among ADLC and VM enum { Control = AdlcVMDeps::Control, I_O = AdlcVMDeps::I_O,
*** 1512,1533 **** Parms = AdlcVMDeps::Parms }; // Accessors: ! const TypeTuple* domain() const { return _domain; } ! const TypeTuple* range() const { return _range; } static const TypeFunc *make(ciMethod* method); ! static const TypeFunc *make(ciSignature signature, const Type* extra); static const TypeFunc *make(const TypeTuple* domain, const TypeTuple* range); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. BasicType return_type() const; #ifndef PRODUCT virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping #endif // Convenience common pre-built types. }; --- 1604,1630 ---- Parms = AdlcVMDeps::Parms }; // Accessors: ! const TypeTuple* domain_sig() const { return _domain_sig; } ! const TypeTuple* domain_cc() const { return _domain_cc; } ! const TypeTuple* range_sig() const { return _range_sig; } ! const TypeTuple* range_cc() const { return _range_cc; } static const TypeFunc *make(ciMethod* method); ! static const TypeFunc *make(const TypeTuple* domain_sig, const TypeTuple* domain_cc, ! const TypeTuple* range_sig, const TypeTuple* range_cc); static const TypeFunc *make(const TypeTuple* domain, const TypeTuple* range); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. BasicType return_type() const; + bool returns_value_type_as_fields() const { return range_sig() != range_cc(); } + #ifndef PRODUCT virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping #endif // Convenience common pre-built types. };
*** 1673,1682 **** --- 1770,1788 ---- inline const TypeAryPtr *Type::is_aryptr() const { assert( _base == AryPtr, "Not an array pointer" ); return (TypeAryPtr*)this; } + inline const TypeValueType* Type::isa_valuetype() const { + return (_base == ValueType) ? (TypeValueType*)this : NULL; + } + + inline const TypeValueType* Type::is_valuetype() const { + assert(_base == ValueType, "Not a value type"); + return (TypeValueType*)this; + } + inline const TypeNarrowOop *Type::is_narrowoop() const { // OopPtr is the first and KlassPtr the last, with no non-oops between. assert(_base == NarrowOop, "Not a narrow oop" ) ; return (TypeNarrowOop*)this; }
*** 1739,1753 **** (_base == DoubleCon) || (_base == DoubleBot) ) return true; return false; } ! inline bool Type::is_ptr_to_boxing_obj() const { ! const TypeInstPtr* tp = isa_instptr(); ! return (tp != NULL) && (tp->offset() == 0) && ! tp->klass()->is_instance_klass() && ! tp->klass()->as_instance_klass()->is_box_klass(); } // =============================================================== // Things that need to be 64-bits in the 64-bit build but --- 1845,1862 ---- (_base == DoubleCon) || (_base == DoubleBot) ) return true; return false; } ! inline bool Type::is_valuetypeptr() const { ! return isa_instptr() != NULL && is_instptr()->klass()->is_valuetype(); ! } ! ! ! inline ciValueKlass* Type::value_klass() const { ! assert(is_valuetypeptr(), "must be a value type ptr"); ! return is_instptr()->klass()->as_value_klass(); } // =============================================================== // Things that need to be 64-bits in the 64-bit build but
*** 1772,1781 **** --- 1881,1891 ---- // For array index arithmetic #define MulXNode MulLNode #define AndXNode AndLNode #define OrXNode OrLNode #define CmpXNode CmpLNode + #define CmpUXNode CmpULNode #define SubXNode SubLNode #define LShiftXNode LShiftLNode // For object size computation: #define AddXNode AddLNode #define RShiftXNode RShiftLNode
*** 1791,1800 **** --- 1901,1912 ---- #define Op_AndX Op_AndL #define Op_AddX Op_AddL #define Op_SubX Op_SubL #define Op_XorX Op_XorL #define Op_URShiftX Op_URShiftL + #define Op_LoadX Op_LoadL + #define Op_StoreX Op_StoreL // conversions #define ConvI2X(x) ConvI2L(x) #define ConvL2X(x) (x) #define ConvX2I(x) ConvL2I(x) #define ConvX2L(x) (x)
*** 1819,1828 **** --- 1931,1941 ---- // For array index arithmetic #define MulXNode MulINode #define AndXNode AndINode #define OrXNode OrINode #define CmpXNode CmpINode + #define CmpUXNode CmpUNode #define SubXNode SubINode #define LShiftXNode LShiftINode // For object size computation: #define AddXNode AddINode #define RShiftXNode RShiftINode
*** 1838,1847 **** --- 1951,1962 ---- #define Op_AndX Op_AndI #define Op_AddX Op_AddI #define Op_SubX Op_SubI #define Op_XorX Op_XorI #define Op_URShiftX Op_URShiftI + #define Op_LoadX Op_LoadI + #define Op_StoreX Op_StoreI // conversions #define ConvI2X(x) (x) #define ConvL2X(x) ConvL2I(x) #define ConvX2I(x) (x) #define ConvX2L(x) ConvI2L(x)
< prev index next >