1.1 --- a/src/share/vm/opto/type.hpp Fri Apr 11 09:56:35 2008 -0400 1.2 +++ b/src/share/vm/opto/type.hpp Sun Apr 13 17:43:42 2008 -0400 1.3 @@ -41,6 +41,7 @@ 1.4 class TypeF; 1.5 class TypeInt; 1.6 class TypeLong; 1.7 +class TypeNarrowOop; 1.8 class TypeAry; 1.9 class TypeTuple; 1.10 class TypePtr; 1.11 @@ -64,6 +65,7 @@ 1.12 Int, // Integer range (lo-hi) 1.13 Long, // Long integer range (lo-hi) 1.14 Half, // Placeholder half of doubleword 1.15 + NarrowOop, // Compressed oop pointer 1.16 1.17 Tuple, // Method signature or object layout 1.18 Array, // Array types 1.19 @@ -188,6 +190,11 @@ 1.20 // Currently, it also works around limitations involving interface types. 1.21 virtual const Type *filter( const Type *kills ) const; 1.22 1.23 + // Returns true if this pointer points at memory which contains a 1.24 + // compressed oop references. In 32-bit builds it's non-virtual 1.25 + // since we don't support compressed oops at all in the mode. 1.26 + LP64_ONLY(virtual) bool is_narrow() const { return false; } 1.27 + 1.28 // Convenience access 1.29 float getf() const; 1.30 double getd() const; 1.31 @@ -204,15 +211,18 @@ 1.32 const TypeAry *is_ary() const; // Array, NOT array pointer 1.33 const TypePtr *is_ptr() const; // Asserts it is a ptr type 1.34 const TypePtr *isa_ptr() const; // Returns NULL if not ptr type 1.35 - const TypeRawPtr *is_rawptr() const; // NOT Java oop 1.36 - const TypeOopPtr *isa_oopptr() const; // Returns NULL if not ptr type 1.37 - const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr 1.38 - const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr 1.39 - const TypeOopPtr *is_oopptr() const; // Java-style GC'd pointer 1.40 - const TypeInstPtr *isa_instptr() const; // Returns NULL if not InstPtr 1.41 - const TypeInstPtr *is_instptr() const; // Instance 1.42 - const TypeAryPtr *isa_aryptr() const; // Returns NULL if not AryPtr 1.43 - const TypeAryPtr *is_aryptr() const; // Array oop 1.44 + const TypeRawPtr *isa_rawptr() const; // NOT Java oop 1.45 + const TypeRawPtr *is_rawptr() const; // Asserts is rawptr 1.46 + const TypeNarrowOop *is_narrowoop() const; // Java-style GC'd pointer 1.47 + const TypeNarrowOop *isa_narrowoop() const; // Returns NULL if not oop ptr type 1.48 + const TypeOopPtr *isa_oopptr() const; // Returns NULL if not oop ptr type 1.49 + const TypeOopPtr *is_oopptr() const; // Java-style GC'd pointer 1.50 + const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr 1.51 + const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr 1.52 + const TypeInstPtr *isa_instptr() const; // Returns NULL if not InstPtr 1.53 + const TypeInstPtr *is_instptr() const; // Instance 1.54 + const TypeAryPtr *isa_aryptr() const; // Returns NULL if not AryPtr 1.55 + const TypeAryPtr *is_aryptr() const; // Array oop 1.56 virtual bool is_finite() const; // Has a finite value 1.57 virtual bool is_nan() const; // Is not a number (NaN) 1.58 1.59 @@ -540,6 +550,7 @@ 1.60 // Otherwise the _base will indicate which subset of pointers is affected, 1.61 // and the class will be inherited from. 1.62 class TypePtr : public Type { 1.63 + friend class TypeNarrowOop; 1.64 public: 1.65 enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR }; 1.66 protected: 1.67 @@ -701,6 +712,15 @@ 1.68 1.69 virtual const TypePtr *add_offset( int offset ) const; 1.70 1.71 + // returns the equivalent compressed version of this pointer type 1.72 + virtual const TypeNarrowOop* make_narrowoop() const; 1.73 + 1.74 +#ifdef _LP64 1.75 + virtual bool is_narrow() const { 1.76 + return (UseCompressedOops && _offset != 0); 1.77 + } 1.78 +#endif 1.79 + 1.80 virtual const Type *xmeet( const Type *t ) const; 1.81 virtual const Type *xdual() const; // Compute dual right now. 1.82 1.83 @@ -822,6 +842,12 @@ 1.84 virtual const Type *xmeet( const Type *t ) const; 1.85 virtual const Type *xdual() const; // Compute dual right now. 1.86 1.87 +#ifdef _LP64 1.88 + virtual bool is_narrow() const { 1.89 + return (UseCompressedOops && klass() != NULL && _offset != 0); 1.90 + } 1.91 +#endif 1.92 + 1.93 // Convenience common pre-built types. 1.94 static const TypeAryPtr *RANGE; 1.95 static const TypeAryPtr *OOPS; 1.96 @@ -874,6 +900,18 @@ 1.97 virtual const Type *xmeet( const Type *t ) const; 1.98 virtual const Type *xdual() const; // Compute dual right now. 1.99 1.100 +#ifdef _LP64 1.101 + // Perm objects don't use compressed references, except for static fields 1.102 + // which are currently compressed 1.103 + virtual bool is_narrow() const { 1.104 + if (UseCompressedOops && _offset != 0 && _klass->is_instance_klass()) { 1.105 + ciInstanceKlass* ik = _klass->as_instance_klass(); 1.106 + return ik != NULL && ik->get_field_by_offset(_offset, true) != NULL; 1.107 + } 1.108 + return false; 1.109 + } 1.110 +#endif 1.111 + 1.112 // Convenience common pre-built types. 1.113 static const TypeKlassPtr* OBJECT; // Not-null object klass or below 1.114 static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same 1.115 @@ -882,6 +920,56 @@ 1.116 #endif 1.117 }; 1.118 1.119 +//------------------------------TypeNarrowOop---------------------------------------- 1.120 +// A compressed reference to some kind of Oop. This type wraps around 1.121 +// a preexisting TypeOopPtr and forwards most of it's operations to 1.122 +// the underlying type. It's only real purpose is to track the 1.123 +// oopness of the compressed oop value when we expose the conversion 1.124 +// between the normal and the compressed form. 1.125 +class TypeNarrowOop : public Type { 1.126 +protected: 1.127 + const TypePtr* _ooptype; 1.128 + 1.129 + TypeNarrowOop( const TypePtr* ooptype): Type(NarrowOop), 1.130 + _ooptype(ooptype) { 1.131 + assert(ooptype->offset() == 0 || 1.132 + ooptype->offset() == OffsetBot || 1.133 + ooptype->offset() == OffsetTop, "no real offsets"); 1.134 + } 1.135 +public: 1.136 + virtual bool eq( const Type *t ) const; 1.137 + virtual int hash() const; // Type specific hashing 1.138 + virtual bool singleton(void) const; // TRUE if type is a singleton 1.139 + 1.140 + virtual const Type *xmeet( const Type *t ) const; 1.141 + virtual const Type *xdual() const; // Compute dual right now. 1.142 + 1.143 + virtual intptr_t get_con() const; 1.144 + 1.145 + // Do not allow interface-vs.-noninterface joins to collapse to top. 1.146 + virtual const Type *filter( const Type *kills ) const; 1.147 + 1.148 + virtual bool empty(void) const; // TRUE if type is vacuous 1.149 + 1.150 + static const TypeNarrowOop *make( const TypePtr* type); 1.151 + 1.152 + static const TypeNarrowOop* make_from_constant(ciObject* con) { 1.153 + return make(TypeOopPtr::make_from_constant(con)); 1.154 + } 1.155 + 1.156 + // returns the equivalent oopptr type for this compressed pointer 1.157 + virtual const TypePtr *make_oopptr() const { 1.158 + return _ooptype; 1.159 + } 1.160 + 1.161 + static const TypeNarrowOop *BOTTOM; 1.162 + static const TypeNarrowOop *NULL_PTR; 1.163 + 1.164 +#ifndef PRODUCT 1.165 + virtual void dump2( Dict &d, uint depth, outputStream *st ) const; 1.166 +#endif 1.167 +}; 1.168 + 1.169 //------------------------------TypeFunc--------------------------------------- 1.170 // Class of Array Types 1.171 class TypeFunc : public Type { 1.172 @@ -1002,6 +1090,10 @@ 1.173 return (_base >= OopPtr && _base <= KlassPtr) ? (TypeOopPtr*)this : NULL; 1.174 } 1.175 1.176 +inline const TypeRawPtr *Type::isa_rawptr() const { 1.177 + return (_base == RawPtr) ? (TypeRawPtr*)this : NULL; 1.178 +} 1.179 + 1.180 inline const TypeRawPtr *Type::is_rawptr() const { 1.181 assert( _base == RawPtr, "Not a raw pointer" ); 1.182 return (TypeRawPtr*)this; 1.183 @@ -1025,6 +1117,17 @@ 1.184 return (TypeAryPtr*)this; 1.185 } 1.186 1.187 +inline const TypeNarrowOop *Type::is_narrowoop() const { 1.188 + // OopPtr is the first and KlassPtr the last, with no non-oops between. 1.189 + assert(_base == NarrowOop, "Not a narrow oop" ) ; 1.190 + return (TypeNarrowOop*)this; 1.191 +} 1.192 + 1.193 +inline const TypeNarrowOop *Type::isa_narrowoop() const { 1.194 + // OopPtr is the first and KlassPtr the last, with no non-oops between. 1.195 + return (_base == NarrowOop) ? (TypeNarrowOop*)this : NULL; 1.196 +} 1.197 + 1.198 inline const TypeKlassPtr *Type::isa_klassptr() const { 1.199 return (_base == KlassPtr) ? (TypeKlassPtr*)this : NULL; 1.200 }