< prev index next >

src/hotspot/share/oops/klass.hpp

Print this page
@@ -42,14 +42,15 @@
    InstanceKlassID,
    InstanceRefKlassID,
    InstanceMirrorKlassID,
    InstanceClassLoaderKlassID,
    TypeArrayKlassID,
+   FlatArrayKlassID,
    ObjArrayKlassID
  };
  
- const uint KLASS_ID_COUNT = 6;
+ const uint KLASS_ID_COUNT = 7;
  
  //
  // A Klass provides:
  //  1: language level class object (method dictionary etc.)
  //  2: provide vm dispatch behavior for the object

@@ -96,11 +97,11 @@
    //
    // For arrays, layout helper is a negative number, containing four
    // distinct bytes, as follows:
    //    MSB:[tag, hsz, ebt, log2(esz)]:LSB
    // where:
-   //    tag is 0x80 if the elements are oops, 0xC0 if non-oops
+   //    tag is 0x80 if the elements are oops, 0xC0 if non-oops, 0xA0 if value types
    //    hsz is array header size in bytes (i.e., offset of first element)
    //    ebt is the BasicType of the elements
    //    esz is the element size in bytes
    // This packed word is arranged so as to be quickly unpacked by the
    // various fast paths that use the various subfields.

@@ -157,10 +158,11 @@
    jint        _modifier_flags;  // Processed access flags, for use by Class.getModifiers.
    AccessFlags _access_flags;    // Access flags. The class/interface distinction is stored here.
  
    JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
  
+   markWord _prototype_header;  // inline type and inline array mark patterns
  private:
    // This is an index into FileMapHeader::_shared_path_table[], to
    // associate this class with the JAR file where it's loaded from during
    // dump time. If a class is not loaded from the shared archive, this field is
    // -1.

@@ -366,15 +368,23 @@
    static const int _lh_log2_element_size_mask  = BitsPerLong-1;
    static const int _lh_element_type_shift      = BitsPerByte*1;
    static const int _lh_element_type_mask       = right_n_bits(BitsPerByte);  // shifted mask
    static const int _lh_header_size_shift       = BitsPerByte*2;
    static const int _lh_header_size_mask        = right_n_bits(BitsPerByte);  // shifted mask
-   static const int _lh_array_tag_bits          = 2;
+   static const int _lh_array_tag_bits          = 3;
    static const int _lh_array_tag_shift         = BitsPerInt - _lh_array_tag_bits;
-   static const int _lh_array_tag_obj_value     = ~0x01;   // 0x80000000 >> 30
  
-   static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00,  // 0xC0000000 >> 30
+   static const unsigned int _lh_array_tag_type_value = 0Xfffffffc;
+   static const unsigned int _lh_array_tag_vt_value   = 0Xfffffffd;
+   static const unsigned int _lh_array_tag_obj_value  = 0Xfffffffe;
+ 
+   // null-free array flag bit under the array tag bits, shift one more to get array tag value
+   static const int _lh_null_free_shift = _lh_array_tag_shift - 1;
+   static const int _lh_null_free_mask  = 1;
+ 
+   static const jint _lh_array_tag_vt_value_bit_inplace = (jint) (1 << _lh_array_tag_shift);
+   static const jint _lh_null_free_bit_inplace = (jint) (_lh_null_free_mask << _lh_null_free_shift);
  
    static int layout_helper_size_in_bytes(jint lh) {
      assert(lh > (jint)_lh_neutral_value, "must be instance");
      return (int) lh & ~_lh_instance_slow_path_bit;
    }

@@ -387,27 +397,37 @@
    }
    static bool layout_helper_is_array(jint lh) {
      return (jint)lh < (jint)_lh_neutral_value;
    }
    static bool layout_helper_is_typeArray(jint lh) {
-     // _lh_array_tag_type_value == (lh >> _lh_array_tag_shift);
-     return (juint)lh >= (juint)(_lh_array_tag_type_value << _lh_array_tag_shift);
+     return (juint) _lh_array_tag_type_value == (juint)(lh >> _lh_array_tag_shift);
    }
    static bool layout_helper_is_objArray(jint lh) {
-     // _lh_array_tag_obj_value == (lh >> _lh_array_tag_shift);
-     return (jint)lh < (jint)(_lh_array_tag_type_value << _lh_array_tag_shift);
+     return (juint)_lh_array_tag_obj_value == (juint)(lh >> _lh_array_tag_shift);
+   }
+   static bool layout_helper_is_flatArray(jint lh) {
+     return (juint)_lh_array_tag_vt_value == (juint)(lh >> _lh_array_tag_shift);
+   }
+   static bool layout_helper_is_null_free(jint lh) {
+     assert(layout_helper_is_flatArray(lh) || layout_helper_is_objArray(lh), "must be array of inline types");
+     return ((lh >> _lh_null_free_shift) & _lh_null_free_mask);
+   }
+   static jint layout_helper_set_null_free(jint lh) {
+     lh |= (_lh_null_free_mask << _lh_null_free_shift);
+     assert(layout_helper_is_null_free(lh), "Bad encoding");
+     return lh;
    }
    static int layout_helper_header_size(jint lh) {
      assert(lh < (jint)_lh_neutral_value, "must be array");
      int hsize = (lh >> _lh_header_size_shift) & _lh_header_size_mask;
      assert(hsize > 0 && hsize < (int)sizeof(oopDesc)*3, "sanity");
      return hsize;
    }
    static BasicType layout_helper_element_type(jint lh) {
      assert(lh < (jint)_lh_neutral_value, "must be array");
      int btvalue = (lh >> _lh_element_type_shift) & _lh_element_type_mask;
-     assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity");
+     assert((btvalue >= T_BOOLEAN && btvalue <= T_OBJECT) || btvalue == T_INLINE_TYPE, "sanity");
      return (BasicType) btvalue;
    }
  
    // Want a pattern to quickly diff against layout header in register
    // find something less clever!

@@ -424,16 +444,17 @@
    }
  
    static int layout_helper_log2_element_size(jint lh) {
      assert(lh < (jint)_lh_neutral_value, "must be array");
      int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
-     assert(l2esz <= LogBytesPerLong,
+     assert(layout_helper_element_type(lh) == T_INLINE_TYPE || l2esz <= LogBytesPerLong,
             "sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh);
      return l2esz;
    }
-   static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
+   static jint array_layout_helper(jint tag, bool null_free, int hsize, BasicType etype, int log2_esize) {
      return (tag        << _lh_array_tag_shift)
+       |    ((null_free ? 1 : 0) <<  _lh_null_free_shift)
        |    (hsize      << _lh_header_size_shift)
        |    ((int)etype << _lh_element_type_shift)
        |    (log2_esize << _lh_log2_element_size_shift);
    }
    static jint instance_layout_helper(jint size, bool slow_path_flag) {

@@ -578,11 +599,14 @@
   protected:
    virtual bool is_instance_klass_slow()     const { return false; }
    virtual bool is_array_klass_slow()        const { return false; }
    virtual bool is_objArray_klass_slow()     const { return false; }
    virtual bool is_typeArray_klass_slow()    const { return false; }
+   virtual bool is_flatArray_klass_slow()    const { return false; }
  #endif // ASSERT
+   // current implementation uses this method even in non debug builds
+   virtual bool is_inline_klass_slow()       const { return false; }
   public:
  
    // Fast non-virtual versions
    #ifndef ASSERT
    #define assert_same_query(xval, xcheck) xval

@@ -604,12 +628,19 @@
                                                      layout_helper_is_objArray(layout_helper()),
                                                      is_objArray_klass_slow()); }
    inline  bool is_typeArray_klass()           const { return assert_same_query(
                                                      layout_helper_is_typeArray(layout_helper()),
                                                      is_typeArray_klass_slow()); }
+   inline  bool is_inline_klass()              const { return is_inline_klass_slow(); } //temporary hack
+   inline  bool is_flatArray_klass()           const { return assert_same_query(
+                                                     layout_helper_is_flatArray(layout_helper()),
+                                                     is_flatArray_klass_slow()); }
+ 
    #undef assert_same_query
  
+   inline bool is_null_free_array_klass()      const { return layout_helper_is_null_free(layout_helper()); }
+ 
    // Access flags
    AccessFlags access_flags() const         { return _access_flags;  }
    void set_access_flags(AccessFlags flags) { _access_flags = flags; }
  
    bool is_public() const                { return _access_flags.is_public(); }

@@ -637,10 +668,21 @@
    inline bool is_non_strong_hidden() const;
  
    bool is_cloneable() const;
    void set_is_cloneable();
  
+   // inline types and inline type array patterns
+   markWord prototype_header() const {
+     return _prototype_header;
+   }
+   static inline markWord default_prototype_header(Klass* k) {
+     return (k == NULL) ? markWord::prototype() : k->prototype_header();
+   }
+ 
+   inline void set_prototype_header(markWord header);
+   static ByteSize prototype_header_offset() { return in_ByteSize(offset_of(Klass, _prototype_header)); }
+ 
    JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
  
    virtual void metaspace_pointers_do(MetaspaceClosure* iter);
    virtual MetaspaceObj::Type type() const { return ClassType; }
  
< prev index next >