diff -r 36d1d483d5d6 -r da91efe96a93 src/share/vm/opto/type.hpp --- a/src/share/vm/opto/type.hpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/opto/type.hpp Sat Sep 01 13:25:18 2012 -0400 @@ -62,6 +62,7 @@ class TypeInstPtr; class TypeAryPtr; class TypeKlassPtr; +class TypeMetadataPtr; //------------------------------Type------------------------------------------- // Basic Type object, represents a set of primitive Values. @@ -93,8 +94,10 @@ OopPtr, // Any and all Java heap entities InstPtr, // Instance pointers (non-array objects) AryPtr, // Array pointers + // (Ptr order matters: See is_ptr, isa_ptr, is_oopptr, isa_oopptr.) + + MetadataPtr, // Generic metadata KlassPtr, // Klass pointers - // (Ptr order matters: See is_ptr, isa_ptr, is_oopptr, isa_oopptr.) Function, // Function signature Abio, // Abstract I/O @@ -123,8 +126,18 @@ }; private: + typedef struct { + const TYPES dual_type; + const BasicType basic_type; + const char* msg; + const bool isa_oop; + const int ideal_reg; + const relocInfo::relocType reloc; + } TypeInfo; + // Dictionary of types shared among compilations. static Dict* _shared_type_dict; + static TypeInfo _type_info[]; static int uhash( const Type *const t ); // Structural equality check. Assumes that cmp() has already compared @@ -241,12 +254,16 @@ const TypeNarrowOop *isa_narrowoop() const; // Returns NULL if not oop ptr type const TypeOopPtr *isa_oopptr() const; // Returns NULL if not oop ptr type const TypeOopPtr *is_oopptr() 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 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 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) @@ -267,9 +284,6 @@ // Do you have memory, directly or through a tuple? bool has_memory( ) const; - // Are you a pointer type or not? - bool isa_oop_ptr() const; - // TRUE if type is a singleton virtual bool singleton(void) const; @@ -284,7 +298,6 @@ static const Type *mreg2type[]; // Printing, statistics - static const char * const msg[lastype]; // Printable strings #ifndef PRODUCT void dump_on(outputStream *st) const; void dump() const { @@ -292,7 +305,6 @@ } virtual void dump2( Dict &d, uint depth, outputStream *st ) const; static void dump_stats(); - static void verify_lastype(); // Check that arrays match type enum #endif void typerr(const Type *t) const; // Mixing types error @@ -336,7 +348,11 @@ static const Type *TOP; // Mapping from compiler type to VM BasicType - BasicType basic_type() const { return _basic_type[_base]; } + BasicType basic_type() const { return _type_info[_base].basic_type; } + int ideal_reg() const { return _type_info[_base].ideal_reg; } + const char* msg() const { return _type_info[_base].msg; } + bool isa_oop_ptr() const { return _type_info[_base].isa_oop; } + relocInfo::relocType reloc() const { return _type_info[_base].reloc; } // Mapping from CI type system to compiler type: static const Type* get_typeflow_type(ciType* type); @@ -842,7 +858,7 @@ //------------------------------TypeInstPtr------------------------------------ // Class of Java object pointers, pointing either to non-array Java instances -// or to a klassOop (including array klasses). +// 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; @@ -859,7 +875,6 @@ 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); @@ -992,18 +1007,92 @@ #endif }; +//------------------------------TypeMetadataPtr------------------------------------- +// Some kind of metadata, either Method*, MethodData* or CPCacheOop +class TypeMetadataPtr : public TypePtr { +protected: + TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset); +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: + 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; } + + virtual const Type *cast_to_ptr_type(PTR ptr) 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. + + virtual intptr_t get_con() const; + + // Do not allow interface-vs.-noninterface joins to collapse to top. + virtual const Type *filter( const Type *kills ) const; + + // Convenience common pre-built types. + static const TypeMetadataPtr *BOTTOM; + +#ifndef PRODUCT + virtual void dump2( Dict &d, uint depth, outputStream *st ) const; +#endif +}; + //------------------------------TypeKlassPtr----------------------------------- // Class of Java Klass pointers -class TypeKlassPtr : public TypeOopPtr { +class TypeKlassPtr : public TypePtr { TypeKlassPtr( PTR ptr, ciKlass* klass, int offset ); + 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(); } + ciSymbol* name() const { return klass()->name(); } - bool is_loaded() const { return _klass->is_loaded(); } + 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); } @@ -1023,6 +1112,8 @@ virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. + virtual intptr_t get_con() const; + // Convenience common pre-built types. static const TypeKlassPtr* OBJECT; // Not-null object klass or below static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same @@ -1117,7 +1208,6 @@ #ifndef PRODUCT virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping - void print_flattened() const; // Print a 'flattened' signature #endif // Convenience common pre-built types. }; @@ -1209,13 +1299,13 @@ inline const TypeOopPtr *Type::is_oopptr() const { // OopPtr is the first and KlassPtr the last, with no non-oops between. - assert(_base >= OopPtr && _base <= KlassPtr, "Not a Java pointer" ) ; + assert(_base >= OopPtr && _base <= AryPtr, "Not a Java pointer" ) ; return (TypeOopPtr*)this; } inline const TypeOopPtr *Type::isa_oopptr() const { // OopPtr is the first and KlassPtr the last, with no non-oops between. - return (_base >= OopPtr && _base <= KlassPtr) ? (TypeOopPtr*)this : NULL; + return (_base >= OopPtr && _base <= AryPtr) ? (TypeOopPtr*)this : NULL; } inline const TypeRawPtr *Type::isa_rawptr() const { @@ -1256,6 +1346,16 @@ return (_base == NarrowOop) ? (TypeNarrowOop*)this : NULL; } +inline const TypeMetadataPtr *Type::is_metadataptr() const { + // MetadataPtr is the first and CPCachePtr the last + assert(_base == MetadataPtr, "Not a metadata pointer" ) ; + return (TypeMetadataPtr*)this; +} + +inline const TypeMetadataPtr *Type::isa_metadataptr() const { + return (_base == MetadataPtr) ? (TypeMetadataPtr*)this : NULL; +} + inline const TypeKlassPtr *Type::isa_klassptr() const { return (_base == KlassPtr) ? (TypeKlassPtr*)this : NULL; }