< 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/ciInlineKlass.hpp"
  #include "opto/adlcVMDeps.hpp"
  #include "runtime/handles.hpp"
+ #include "runtime/sharedRuntime.hpp"
  
  // Portions of code courtesy of Clifford Click
  
  // Optimization - Graph Style
  

*** 51,10 ***
--- 53,11 ---
  class   TypeNarrowPtr;
  class     TypeNarrowOop;
  class     TypeNarrowKlass;
  class   TypeAry;
  class   TypeTuple;
+ class   TypeInlineType;
  class   TypeVect;
  class     TypeVectA;
  class     TypeVectS;
  class     TypeVectD;
  class     TypeVectX;

*** 98,10 ***
--- 101,11 ---
      VectorS,                    //  32bit Vector types
      VectorD,                    //  64bit Vector types
      VectorX,                    // 128bit Vector types
      VectorY,                    // 256bit Vector types
      VectorZ,                    // 512bit Vector types
+     InlineType,                 // Inline 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)

*** 131,10 ***
--- 135,34 ---
    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
    };

*** 278,13 ***
    // 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,10 ---

*** 318,10 ***
--- 343,12 ---
    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 TypeInlineType* isa_inlinetype() const;  // Returns NULL if not Inline Type
+   const TypeInlineType* is_inlinetype() const;   // Inline 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

*** 331,10 ***
--- 358,13 ---
    const TypeAryKlassPtr   *is_aryklassptr() const;    // assert if not AryKlassPtr
  
    virtual bool      is_finite() const;           // Has a finite value
    virtual bool      is_nan()    const;           // Is not a number (NaN)
  
+   bool is_inlinetypeptr() const;
+   virtual ciInlineKlass* inline_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.

*** 718,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);
  
    // 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 );
  
--- 748,12 ---
      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 );
  

*** 748,41 ***
  };
  
  //------------------------------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)
--- 778,87 ---
  };
  
  //------------------------------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?
+ 
+   // Inline 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 Inline Type Types
+ class TypeInlineType : public Type {
+ private:
+   ciInlineKlass* _vk;
+   bool _larval;
+ 
+ protected:
+   TypeInlineType(ciInlineKlass* vk, bool larval)
+     : Type(InlineType),
+       _vk(vk), _larval(larval) {
+   }
+ 
+ public:
+   static const TypeInlineType* make(ciInlineKlass* vk, bool larval = false);
+   virtual ciInlineKlass* inline_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; }
+ 
+   virtual bool maybe_null() const { return false; }
+ 
+   static const TypeInlineType* 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)

*** 880,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,
            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];
--- 956,11 ---
  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];

*** 936,41 ***
      NOT_SUBTYPE,
      LCA
    };
    static MeetResult
    meet_instptr(PTR &ptr, ciKlass* this_klass, ciKlass* tinst_klass, bool this_xk, bool tinst_xk, PTR this_ptr,
!                PTR tinst_ptr, ciKlass*&res_klass, bool &res_xk);
!   static MeetResult
!   meet_aryptr(PTR& ptr, const Type*& elem, ciKlass* this_klass, ciKlass* tap_klass, bool this_xk, bool tap_xk, PTR this_ptr, PTR tap_ptr, ciKlass*& res_klass, bool& res_xk);
  
  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()];      }
--- 1012,47 ---
      NOT_SUBTYPE,
      LCA
    };
    static MeetResult
    meet_instptr(PTR &ptr, ciKlass* this_klass, ciKlass* tinst_klass, bool this_xk, bool tinst_xk, PTR this_ptr,
!                PTR tinst_ptr, bool this_flatten_array, bool tinst_flatten_array, ciKlass*&res_klass, bool &res_xk,
!                bool& res_flatten_array);
! 
+   static MeetResult meet_aryptr(PTR &ptr, const Type* this_elem, const Type* tap_elem, ciKlass* this_klass, ciKlass* tap_klass,
+                                 bool this_xk, bool tap_xk, PTR this_ptr, PTR tap_ptr, bool this_not_flat, bool tap_not_flat,
+                                 bool this_not_null_free, bool tap_not_null_free, const Type*& res_elem, ciKlass*&res_klass,
+                                 bool &res_xk, bool &res_not_flat, bool &res_not_null_free);
  
  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()];      }

*** 994,10 ***
--- 1076,15 ---
    virtual bool would_improve_ptr(ProfilePtrKind maybe_null) const;
    virtual const TypePtr* with_inline_depth(int depth) const;
  
    virtual bool maybe_null() const { return meet_ptr(Null) == ptr(); }
  
+   virtual bool can_be_inline_type() const { return false; }
+   virtual bool flatten_array() const { return false; }
+   virtual bool is_not_flat() const { return false; }
+   virtual bool is_not_null_free() const { return false; }
+ 
    // Tests for relation to centerline of type lattice:
    static bool above_centerline(PTR ptr) { return (ptr <= AnyNull); }
    static bool below_centerline(PTR ptr) { return (ptr >= NotNull); }
    // Convenience common pre-built types.
    static const TypePtr *NULL_PTR;

*** 1011,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){}
  public:
    virtual bool eq( const Type *t ) const;
    virtual int  hash() const;     // Type specific hashing
  
    const address _bits;          // Constant value, if applicable
--- 1098,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,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

*** 1042,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);
  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 {
--- 1129,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, 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 {

*** 1102,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,
                                  const TypePtr* speculative = NULL,
                                  int inline_depth = InlineDepthBottom);
  
    ciObject* const_oop()    const { return _const_oop; }
    virtual ciKlass* klass() const { return _klass;     }
--- 1189,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, 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;     }

*** 1117,11 ***
    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 TypeOopPtr* cast_to_ptr_type(PTR ptr) const;
  
--- 1204,13 ---
    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_inline_type() const { return EnableValhalla && (_klass == NULL || _klass->can_be_inline_klass(_klass_is_exact)); }
  
    virtual intptr_t get_con() const;
  
    virtual const TypeOopPtr* cast_to_ptr_type(PTR ptr) const;
  

*** 1155,59 ***
  
  //------------------------------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
  
   public:
    ciSymbol* name()         const { return _name; }
  
    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 TypeInstPtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const Type *cast_to_exactness(bool klass_is_exact) const;
  
--- 1244,62 ---
  
  //------------------------------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,
!               bool flatten_array, 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
+   bool _flatten_array;     // Type is flat in arrays
  
   public:
    ciSymbol* name()         const { return _name; }
  
    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));
    }
    // 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);
    }
  
    // 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));
    }
  
    // 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));
    }
  
    // 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);
    }
  
    // Make a pointer to an oop.
!   static const TypeInstPtr* make(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset,
+                                  bool flatten_array = false,
                                   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_val_mirror = NULL) const;
  
    virtual const TypeInstPtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const Type *cast_to_exactness(bool klass_is_exact) const;
  

*** 1218,10 ***
--- 1310,13 ---
    // Speculative type helper methods.
    virtual const Type* remove_speculative() const;
    virtual const TypePtr* with_inline_depth(int depth) const;
    virtual const TypePtr* with_instance_id(int instance_id) const;
  
+   virtual const TypeInstPtr* cast_to_flatten_array() const;
+   virtual bool flatten_array() const { return _flatten_array; }
+ 
    // the core of the computation of the meet of 2 types
    virtual const Type *xmeet_helper(const Type *t) const;
    virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
    virtual const Type *xdual() const;    // Compute dual right now.
  

*** 1239,16 ***
  };
  
  //------------------------------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);
--- 1334,17 ---
  };
  
  //------------------------------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);

*** 1267,10 ***
--- 1363,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 inline type arrays, each field of the inline 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

*** 1278,21 ***
    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 TypeAryPtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const Type *cast_to_exactness(bool klass_is_exact) const;
--- 1380,30 ---
    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; }
  
+   // Inline type array properties
+   bool is_flat()          const { return _ary->_elem->isa_inlinetype() != NULL; }
+   bool is_not_flat()      const { return _ary->_not_flat; }
+   bool is_null_free()     const { return is_flat() || (_ary->_elem->make_ptr() != NULL && _ary->_elem->make_ptr()->is_inlinetypeptr() && !_ary->_elem->make_ptr()->maybe_null()); }
+   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 TypeAryPtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const Type *cast_to_exactness(bool klass_is_exact) const;

*** 1305,23 ***
    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 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_stable(bool stable, int stable_dimension = 1) const;
    int stable_dimension() const;
  
    const TypeAryPtr* cast_to_autobox_cache() const;
  
!   static jint max_array_length(BasicType etype) ;
    virtual const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
  
    // Convenience common pre-built types.
    static const TypeAryPtr *RANGE;
    static const TypeAryPtr *OOPS;
--- 1416,36 ---
    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.
  
+   // Inline type array properties
+   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* update_properties(const TypeAryPtr* new_type) const;
+ 
    const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
    int stable_dimension() const;
  
    const TypeAryPtr* cast_to_autobox_cache() const;
  
!   static jint max_array_length(BasicType etype);
+ 
+   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_inline_type() const { return false; }
    virtual const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
  
    // Convenience common pre-built types.
    static const TypeAryPtr *RANGE;
    static const TypeAryPtr *OOPS;

*** 1331,10 ***
--- 1455,11 ---
    static const TypeAryPtr *CHARS;
    static const TypeAryPtr *INTS;
    static const TypeAryPtr *LONGS;
    static const TypeAryPtr *FLOATS;
    static const TypeAryPtr *DOUBLES;
+   static const TypeAryPtr *INLINES;
    // 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];
    }

*** 1351,11 ***
  
  //------------------------------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
--- 1476,11 ---
  
  //------------------------------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

*** 1363,11 ***
  
  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; }
--- 1488,11 ---
  
  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; }

*** 1391,11 ***
  
  //------------------------------TypeKlassPtr-----------------------------------
  // Class of Java Klass pointers
  class TypeKlassPtr : public TypePtr {
  protected:
!   TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, int offset);
  
    virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
  
  public:
    virtual bool eq( const Type *t ) const;
--- 1516,11 ---
  
  //------------------------------TypeKlassPtr-----------------------------------
  // Class of Java Klass pointers
  class TypeKlassPtr : public TypePtr {
  protected:
!   TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, Offset offset);
  
    virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
  
  public:
    virtual bool eq( const Type *t ) const;

*** 1412,11 ***
    virtual ciKlass* klass() const { return  _klass; }
    bool klass_is_exact()    const { return _ptr == Constant; }
    bool  is_loaded() const { return klass()->is_loaded(); }
  
    static const TypeKlassPtr* make(ciKlass* klass);
!   static const TypeKlassPtr *make(PTR ptr, ciKlass* klass, int offset);
  
  
    virtual const TypePtr* cast_to_ptr_type(PTR ptr) const { ShouldNotReachHere(); return NULL; }
  
    virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const { ShouldNotReachHere(); return NULL; }
--- 1537,11 ---
    virtual ciKlass* klass() const { return  _klass; }
    bool klass_is_exact()    const { return _ptr == Constant; }
    bool  is_loaded() const { return klass()->is_loaded(); }
  
    static const TypeKlassPtr* make(ciKlass* klass);
!   static const TypeKlassPtr *make(PTR ptr, ciKlass* klass, Offset offset);
  
  
    virtual const TypePtr* cast_to_ptr_type(PTR ptr) const { ShouldNotReachHere(); return NULL; }
  
    virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const { ShouldNotReachHere(); return NULL; }

*** 1429,33 ***
    virtual const Type    *xdual() const { ShouldNotReachHere(); return NULL; }
  
    virtual intptr_t get_con() const;
  
    virtual const TypeKlassPtr* with_offset(intptr_t offset) const { ShouldNotReachHere(); return NULL; }
- 
- #ifndef PRODUCT
-   virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
- #endif
  };
  
  // Instance klass pointer, mirrors TypeInstPtr
  class TypeInstKlassPtr : public TypeKlassPtr {
  
!   TypeInstKlassPtr(PTR ptr, ciKlass* klass, int offset)
!     : TypeKlassPtr(InstKlassPtr, ptr, klass, offset) {
    }
  
    virtual bool must_be_exact() const;
  
  public:
    // Instance klass ignoring any interface
    ciInstanceKlass* instance_klass() const { return klass()->as_instance_klass();     }
  
    static const TypeInstKlassPtr *make(ciKlass* k) {
!     return make(TypePtr::Constant, k, 0);
    }
!   static const TypeInstKlassPtr *make(PTR ptr, ciKlass* k, int offset);
  
    virtual const TypePtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const;
  
--- 1554,33 ---
    virtual const Type    *xdual() const { ShouldNotReachHere(); return NULL; }
  
    virtual intptr_t get_con() const;
  
    virtual const TypeKlassPtr* with_offset(intptr_t offset) const { ShouldNotReachHere(); return NULL; }
  };
  
  // Instance klass pointer, mirrors TypeInstPtr
  class TypeInstKlassPtr : public TypeKlassPtr {
  
!   TypeInstKlassPtr(PTR ptr, ciKlass* klass, Offset offset, bool flatten_array)
!     : TypeKlassPtr(InstKlassPtr, ptr, klass, offset), _flatten_array(flatten_array) {
    }
  
    virtual bool must_be_exact() const;
  
+   const bool _flatten_array; // Type is flat in arrays
+ 
  public:
    // Instance klass ignoring any interface
    ciInstanceKlass* instance_klass() const { return klass()->as_instance_klass();     }
  
+   virtual bool can_be_inline_type() const { return EnableValhalla && (_klass == NULL || _klass->can_be_inline_klass(klass_is_exact())); }
+ 
    static const TypeInstKlassPtr *make(ciKlass* k) {
!     return make(TypePtr::Constant, k, Offset(0), false);
    }
!   static const TypeInstKlassPtr *make(PTR ptr, ciKlass* k, Offset offset, bool flatten_array = false);
  
    virtual const TypePtr* cast_to_ptr_type(PTR ptr) const;
  
    virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const;
  

*** 1467,34 ***
    virtual const TypePtr *add_offset( intptr_t offset ) const;
    virtual const Type    *xmeet( const Type *t ) const;
    virtual const Type    *xdual() const;
    virtual const TypeKlassPtr* with_offset(intptr_t offset) const;
  
    // Convenience common pre-built types.
    static const TypeInstKlassPtr* OBJECT; // Not-null object klass or below
    static const TypeInstKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
  };
  
  // Array klass pointer, mirrors TypeAryPtr
  class TypeAryKlassPtr : public TypeKlassPtr {
    const Type *_elem;
  
!   TypeAryKlassPtr(PTR ptr, const Type *elem, ciKlass* klass, int offset)
!     : TypeKlassPtr(AryKlassPtr, ptr, klass, offset), _elem(elem) {
    }
  
    virtual bool must_be_exact() const;
  
  public:
    virtual ciKlass* klass() const;
  
    // returns base element type, an instance klass (and not interface) for object arrays
    const Type* base_element_type(int& dims) const;
  
!   static const TypeAryKlassPtr *make(PTR ptr, ciKlass* k, int offset);
!   static const TypeAryKlassPtr *make(PTR ptr, const Type *elem, ciKlass* k, int offset);
!   static const TypeAryKlassPtr* make(ciKlass* klass);
  
    const Type *elem() const { return _elem; }
  
    virtual bool eq(const Type *t) const;
    virtual int hash() const;             // Type specific hashing
--- 1592,51 ---
    virtual const TypePtr *add_offset( intptr_t offset ) const;
    virtual const Type    *xmeet( const Type *t ) const;
    virtual const Type    *xdual() const;
    virtual const TypeKlassPtr* with_offset(intptr_t offset) const;
  
+   virtual bool flatten_array() const { return _flatten_array; }
+ 
    // Convenience common pre-built types.
    static const TypeInstKlassPtr* OBJECT; // Not-null object klass or below
    static const TypeInstKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
+ 
+ #ifndef PRODUCT
+   virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
+ #endif
  };
  
  // Array klass pointer, mirrors TypeAryPtr
  class TypeAryKlassPtr : public TypeKlassPtr {
    const Type *_elem;
+   const bool _not_flat;      // Array is never flattened
+   const bool _not_null_free; // Array is never null-free
+   const bool _null_free;
  
!   TypeAryKlassPtr(PTR ptr, const Type *elem, ciKlass* klass, Offset offset, bool not_flat, int not_null_free, bool null_free)
!     : TypeKlassPtr(AryKlassPtr, ptr, klass, offset), _elem(elem), _not_flat(not_flat), _not_null_free(not_null_free), _null_free(null_free) {
    }
  
    virtual bool must_be_exact() const;
  
+   bool dual_null_free() const {
+     return _null_free;
+   }
+ 
+   bool meet_null_free(bool other) const {
+     return _null_free && other;
+   }
+ 
  public:
    virtual ciKlass* klass() const;
  
    // returns base element type, an instance klass (and not interface) for object arrays
    const Type* base_element_type(int& dims) const;
  
!   static const TypeAryKlassPtr *make(PTR ptr, ciKlass* k, Offset offset, bool not_flat, bool not_null_free, bool null_free);
!   static const TypeAryKlassPtr *make(PTR ptr, const Type *elem, ciKlass* k, Offset offset, bool not_flat, bool not_null_free, bool null_free);
!   static const TypeAryKlassPtr* make(ciKlass* klass, PTR ptr = Constant, Offset offset= Offset(0));
  
    const Type *elem() const { return _elem; }
  
    virtual bool eq(const Type *t) const;
    virtual int hash() const;             // Type specific hashing

*** 1514,10 ***
--- 1656,14 ---
  
    virtual bool empty(void) const {
      return TypeKlassPtr::empty() || _elem->empty();
    }
  
+   virtual bool is_not_flat() const { return _not_flat; }
+   virtual bool is_not_null_free() const { return _not_null_free; }
+   bool null_free() const { return _null_free; }
+ 
  #ifndef PRODUCT
    virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
  #endif
  };
  

*** 1647,18 ***
  };
  
  //------------------------------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,
--- 1793,30 ---
  };
  
  //------------------------------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: inline type arguments are not passed by
!   // reference, instead each field of the inline type is passed as an
+   // argument. We maintain 2 views of the argument list here: one
+   // based on the signature (with an inline 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: an inline 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,

*** 1668,22 ***
           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.
  };
--- 1826,27 ---
           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, bool is_osr_compilation = false);
+   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_inline_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.
  };

*** 1851,10 ***
--- 2014,19 ---
  inline const TypeAryPtr *Type::is_aryptr() const {
    assert( _base == AryPtr, "Not an array pointer" );
    return (TypeAryPtr*)this;
  }
  
+ inline const TypeInlineType* Type::isa_inlinetype() const {
+   return (_base == InlineType) ? (TypeInlineType*)this : NULL;
+ }
+ 
+ inline const TypeInlineType* Type::is_inlinetype() const {
+   assert(_base == InlineType, "Not an inline type");
+   return (TypeInlineType*)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;
  }

*** 1935,15 ***
        (_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
--- 2107,18 ---
        (_base == DoubleCon) || (_base == DoubleBot) )
      return true;
    return false;
  }
  
! inline bool Type::is_inlinetypeptr() const {
!   return isa_instptr() != NULL && is_instptr()->klass()->is_inlinetype();
! }
! 
! 
+ inline ciInlineKlass* Type::inline_klass() const {
+   assert(is_inlinetypeptr(), "must be an inline type ptr");
+   return is_instptr()->klass()->as_inline_klass();
  }
  
  
  // ===============================================================
  // Things that need to be 64-bits in the 64-bit build but

*** 1968,10 ***
--- 2143,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

*** 1986,10 ***
--- 2162,11 ---
  #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)

*** 2014,10 ***
--- 2191,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

*** 2032,10 ***
--- 2210,11 ---
  #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 >