< prev index next >
src/hotspot/share/opto/type.hpp
Print this page
@@ -23,12 +23,14 @@
*/
#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,10 +52,11 @@
class TypeNarrowPtr;
class TypeNarrowOop;
class TypeNarrowKlass;
class TypeAry;
class TypeTuple;
+class TypeValueType;
class TypeVect;
class TypeVectS;
class TypeVectD;
class TypeVectX;
class TypeVectY;
@@ -90,10 +93,11 @@
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,10 +125,34 @@
enum OFFSET_SIGNALS {
OffsetTop = -2000000000, // undefined offset
OffsetBot = -2000000001 // any possible offset
};
+ class Offset {
+ private:
+ const 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
};
@@ -271,13 +299,10 @@
// 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;
@@ -306,19 +331,24 @@
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;
+ 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,12 +691,12 @@
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);
+ 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 );
@@ -713,19 +743,57 @@
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;
+
+ bool is_value_type_array() const { return _elem->isa_valuetype() != NULL; }
+
#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);
+ 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; }
+
+#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,11 +869,11 @@
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,
+ 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,36 +912,38 @@
#ifndef PRODUCT
void dump_inline_depth(outputStream *st) const;
#endif
public:
- const int _offset; // Offset into oop, with TOP & BOT
+ const Offset _offset; // Offset into oop, with TOP & BOT
const PTR _ptr; // Pointer equivalence class
- const int offset() const { return _offset; }
+ const int offset() const { return _offset.get(); }
const PTR ptr() const { return _ptr; }
- static const TypePtr *make(TYPES t, PTR ptr, int offset,
+ 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;
- int xadd_offset( intptr_t offset ) 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;
- int meet_offset( int offset ) const;
- int dual_offset( ) 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,11 +984,11 @@
//------------------------------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){}
+ 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,12 +1015,12 @@
//------------------------------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);
+ 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,11 +1075,11 @@
// 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,
+ 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,11 +1090,14 @@
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; }
+ 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_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,11 +1133,11 @@
//------------------------------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,
+ 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,34 +1147,34 @@
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);
+ 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, int 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, 0, InstanceBot);
+ 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, 0, InstanceBot);
+ 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, int 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, int offset,
+ 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 */
@@ -1144,16 +1217,17 @@
};
//------------------------------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,
+ 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, instance_id, speculative, inline_depth),
+ : TypeOopPtr(AryPtr, ptr, k, xk, o, offset, field_offset, instance_id, speculative, inline_depth),
_ary(ary),
- _is_autobox_cache(is_autobox_cache)
+ _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,10 +1246,16 @@
}
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
@@ -1185,19 +1265,22 @@
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,
+ 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, int offset,
+ 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);
+ 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;
@@ -1224,10 +1307,17 @@
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;
@@ -1255,11 +1345,11 @@
//------------------------------TypeMetadataPtr-------------------------------------
// Some kind of metadata, either Method*, MethodData* or CPCacheOop
class TypeMetadataPtr : public TypePtr {
protected:
- TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset);
+ 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,11 +1357,11 @@
private:
ciMetadata* _metadata;
public:
- static const TypeMetadataPtr* make(PTR ptr, ciMetadata* m, int offset);
+ 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,61 +1384,37 @@
};
//------------------------------TypeKlassPtr-----------------------------------
// Class of Java Klass pointers
class TypeKlassPtr : public TypePtr {
- TypeKlassPtr( PTR ptr, ciKlass* klass, int offset );
+ 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:
- 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);
+ 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, 0); }
+ 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, int offset ) { return make( TypePtr::Constant, k, 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, int offset);
+ 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,18 +1557,30 @@
};
//------------------------------TypeFunc---------------------------------------
// Class of Array Types
class TypeFunc : public Type {
- TypeFunc( const TypeTuple *domain, const TypeTuple *range ) : Type(Function), _domain(domain), _range(range) {}
+ 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
- const TypeTuple* const _domain; // Domain of inputs
- const TypeTuple* const _range; // Range of results
+ // 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,22 +1590,28 @@
Parms = AdlcVMDeps::Parms
};
// Accessors:
- const TypeTuple* domain() const { return _domain; }
- const TypeTuple* range() const { return _range; }
+ 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(ciSignature signature, const Type* extra);
+ 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,10 +1757,19 @@
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,15 +1832,18 @@
(_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();
+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,10 +1868,11 @@
// 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,10 +1888,12 @@
#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,10 +1918,11 @@
// 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,10 +1938,12 @@
#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 >