< 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 >