< prev index next >

src/hotspot/share/oops/fieldInfo.hpp

Print this page
@@ -32,10 +32,18 @@
  
  static constexpr u4 flag_mask(int pos) {
    return (u4)1 << pos;
  }
  
+ enum LayoutKind {
+   REFERENCE            = 0,    // indirection to a heap allocated instance
+   PAYLOAD              = 1,    // layout used in heap allocated standalone instances, probably temporary for the transition
+   NON_ATOMIC_FLAT      = 2,    // flat, no guarantee of atomic updates, no null marker
+   ATOMIC_FLAT          = 3,    // flat, size compatible with atomic updates, alignment requirement is equal to the size
+   NULLABLE_ATOMIC_FLAT = 4,    // flat, include a null marker, plus same properties as ATOMIC layout
+   UNKNOWN              = 5     // used for uninitialized fields of type LayoutKind
+ };
  
  // Helper class for access to the underlying Array<u1> used to
  // store the compressed stream of FieldInfo
  template<typename ARR, typename OFF>
  struct ArrayHelper {

@@ -64,28 +72,34 @@
   public:
  
    class FieldFlags {
      friend class VMStructs;
      friend class JVMCIVMStructs;
+     friend class FieldDesc;
  
      // The ordering of this enum is totally internal.  More frequent
      // flags should come earlier than less frequent ones, because
      // earlier ones compress better.
      enum FieldFlagBitPosition {
+       _ff_null_free_inline_type,  // field's type is an inline type and the field is null free
+       _ff_flat,         // field is a flat field, optional section includes a layout kind
+       _ff_null_marker,  // field has a null marker, optional section includes the null marker offset
        _ff_initialized,  // has ConstantValue initializer attribute
        _ff_injected,     // internal field injected by the JVM
        _ff_generic,      // has a generic signature
        _ff_stable,       // trust as stable b/c declared as @Stable
-       _ff_contended,    // is contended, may have contention-group
+       _ff_contended    // is contended, may have contention-group
      };
  
      // Some but not all of the flag bits signal the presence of an
      // additional 32-bit item in the field record.
      static const u4 _optional_item_bit_mask =
        flag_mask((int)_ff_initialized) |
        flag_mask((int)_ff_generic)     |
-       flag_mask((int)_ff_contended);
+       flag_mask((int)_ff_contended)   |
+       flag_mask((int)_ff_flat)        |
+       flag_mask((int)_ff_null_marker);
  
      // boilerplate:
      u4 _flags;
  
      bool test_flag(FieldFlagBitPosition pos) const {

@@ -104,20 +118,26 @@
      bool has_any_optionals() const {
        return (_flags & _optional_item_bit_mask) != 0;
      }
  
      bool is_initialized() const     { return test_flag(_ff_initialized); }
+     bool is_null_free_inline_type() const { return test_flag(_ff_null_free_inline_type); }
+     bool is_flat() const            { return test_flag(_ff_flat); }
      bool is_injected() const        { return test_flag(_ff_injected); }
      bool is_generic() const         { return test_flag(_ff_generic); }
      bool is_stable() const          { return test_flag(_ff_stable); }
      bool is_contended() const       { return test_flag(_ff_contended); }
+     bool has_null_marker() const    { return test_flag(_ff_null_marker); }
  
      void update_initialized(bool z) { update_flag(_ff_initialized, z); }
+     void update_null_free_inline_type(bool z) { update_flag(_ff_null_free_inline_type, z); }
+     void update_flat(bool z)        { update_flag(_ff_flat, z); }
      void update_injected(bool z)    { update_flag(_ff_injected, z); }
      void update_generic(bool z)     { update_flag(_ff_generic, z); }
      void update_stable(bool z)      { update_flag(_ff_stable, z); }
      void update_contended(bool z)   { update_flag(_ff_contended, z); }
+     void update_null_marker(bool z) { update_flag(_ff_null_marker, z); }
    };
  
   private:
    // The following items are the unpacked bitwise information content
    // of a field record.  Per-field metadata extracted from the class

@@ -129,10 +149,12 @@
    u2 _name_index;               // index in CP of name
    u2 _signature_index;          // index in CP of descriptor
    u4 _offset;                   // offset in object layout
    AccessFlags _access_flags;    // access flags (JVM spec)
    FieldFlags _field_flags;      // VM defined flags (not JVM spec)
+   LayoutKind _layout_kind;      // LayoutKind if the field is flat
+   u4 _null_marker_offset;       // null marker offset for this field in the object layout
    u2 _initializer_index;        // index from ConstantValue attr (or 0)
    u2 _generic_signature_index;  // index from GenericSignature attr (or 0)
    u2 _contention_group;         // index from @Contended group item (or 0)
  
   public:

@@ -140,20 +162,24 @@
    FieldInfo() : _name_index(0),
                  _signature_index(0),
                  _offset(0),
                  _access_flags(AccessFlags(0)),
                  _field_flags(FieldFlags(0)),
+                 _layout_kind(LayoutKind::UNKNOWN),
+                 _null_marker_offset(0),
                  _initializer_index(0),
                  _generic_signature_index(0),
                  _contention_group(0) { }
  
    FieldInfo(AccessFlags access_flags, u2 name_index, u2 signature_index, u2 initval_index, FieldInfo::FieldFlags fflags) :
              _name_index(name_index),
              _signature_index(signature_index),
              _offset(0),
              _access_flags(access_flags),
              _field_flags(fflags),
+             _layout_kind(LayoutKind::UNKNOWN),
+             _null_marker_offset(0),
              _initializer_index(initval_index),
              _generic_signature_index(0),
              _contention_group(0) {
                if (initval_index != 0) {
                  _field_flags.update_initialized(true);

@@ -169,10 +195,20 @@
    u4 offset() const                          { return _offset; }
    void set_offset(u4 offset)                 { _offset = offset; }
    AccessFlags access_flags() const           { return _access_flags; }
    FieldFlags field_flags() const             { return _field_flags; }
    FieldFlags* field_flags_addr()             { return &_field_flags; }
+   LayoutKind layout_kind() const             { return _layout_kind; }
+   void set_layout_kind(LayoutKind lk) {
+     assert(_field_flags.is_flat(), "Must be");
+     _layout_kind = lk;
+   }
+   u4 null_marker_offset() const              { return _null_marker_offset; }
+   void set_null_marker_offset(u4 offset) {
+     _field_flags.update_null_marker(true);
+     _null_marker_offset = offset;
+   }
    u2 initializer_index() const               { return _initializer_index; }
    void set_initializer_index(u2 index)       { _initializer_index = index; }
    u2 generic_signature_index() const         { return _generic_signature_index; }
    void set_generic_signature_index(u2 index) { _generic_signature_index = index; }
    u2 contention_group() const                { return _contention_group; }
< prev index next >