< prev index next >

src/hotspot/share/oops/instanceKlass.hpp

Print this page
*** 23,10 ***
--- 23,11 ---
   */
  
  #ifndef SHARE_OOPS_INSTANCEKLASS_HPP
  #define SHARE_OOPS_INSTANCEKLASS_HPP
  
+ #include "code/vmreg.hpp"
  #include "memory/referenceType.hpp"
  #include "oops/annotations.hpp"
  #include "oops/constMethod.hpp"
  #include "oops/fieldInfo.hpp"
  #include "oops/instanceOop.hpp"

*** 48,10 ***
--- 49,12 ---
  //    [EMBEDDED Java vtable             ] size in words = vtable_len
  //    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
  //      The embedded nonstatic oop-map blocks are short pairs (offset, length)
  //      indicating where oops are located in instances of this klass.
  //    [EMBEDDED implementor of the interface] only exist for interface
+ //    [EMBEDDED inline_type_field_klasses] only if has_inline_fields() == true
+ //    [EMBEDDED InlineKlassFixedBlock] only if is an InlineKlass instance
  
  
  // forward declaration for class -- see below for definition
  #if INCLUDE_JVMTI
  class BreakpointInfo;

*** 64,10 ***
--- 67,11 ---
  class jniIdMapBase;
  class JNIid;
  class JvmtiCachedClassFieldMap;
  class nmethodBucket;
  class OopMapCache;
+ class BufferedInlineTypeBlob;
  class InterpreterOopMap;
  class PackageEntry;
  class ModuleEntry;
  
  // This is used in iterators below.

*** 124,15 ***
--- 128,33 ---
    uint _count;
  };
  
  struct JvmtiCachedClassFileData;
  
+ class SigEntry;
+ 
+ class InlineKlassFixedBlock {
+   Array<SigEntry>** _extended_sig;
+   Array<VMRegPair>** _return_regs;
+   address* _pack_handler;
+   address* _pack_handler_jobject;
+   address* _unpack_handler;
+   int* _default_value_offset;
+   ArrayKlass** _null_free_inline_array_klasses;
+   int _alignment;
+   int _first_field_offset;
+   int _exact_size_in_bytes;
+ 
+   friend class InlineKlass;
+ };
+ 
  class InstanceKlass: public Klass {
    friend class VMStructs;
    friend class JVMCIVMStructs;
    friend class ClassFileParser;
    friend class CompileReplay;
+   friend class TemplateTable;
  
   public:
    static const KlassID ID = InstanceKlassID;
  
   protected:

*** 146,11 ***
    enum ClassState {
      allocated,                          // allocated (but not yet linked)
      loaded,                             // loaded and inserted in class hierarchy (but not linked yet)
      linked,                             // successfully linked/verified (but not initialized yet)
      being_initialized,                  // currently running class initializer
!     fully_initialized,                  // initialized (successfull final state)
      initialization_error                // error happened during initialization
    };
  
   private:
    static InstanceKlass* allocate_instance_klass(const ClassFileParser& parser, TRAPS);
--- 168,11 ---
    enum ClassState {
      allocated,                          // allocated (but not yet linked)
      loaded,                             // loaded and inserted in class hierarchy (but not linked yet)
      linked,                             // successfully linked/verified (but not initialized yet)
      being_initialized,                  // currently running class initializer
!     fully_initialized,                  // initialized (successful final state)
      initialization_error                // error happened during initialization
    };
  
   private:
    static InstanceKlass* allocate_instance_klass(const ClassFileParser& parser, TRAPS);

*** 162,11 ***
    // Annotations for this class
    Annotations*    _annotations;
    // Package this class is defined in
    PackageEntry*   _package_entry;
    // Array classes holding elements of this class.
!   ObjArrayKlass* volatile _array_klasses;
    // Constant pool for this class.
    ConstantPool* _constants;
    // The InnerClasses attribute and EnclosingMethod attribute. The
    // _inner_classes is an array of shorts. If the class has InnerClasses
    // attribute, then the _inner_classes array begins with 4-tuples of shorts
--- 184,11 ---
    // Annotations for this class
    Annotations*    _annotations;
    // Package this class is defined in
    PackageEntry*   _package_entry;
    // Array classes holding elements of this class.
!   ArrayKlass* volatile _array_klasses;
    // Constant pool for this class.
    ConstantPool* _constants;
    // The InnerClasses attribute and EnclosingMethod attribute. The
    // _inner_classes is an array of shorts. If the class has InnerClasses
    // attribute, then the _inner_classes array begins with 4-tuples of shorts

*** 227,16 ***
    // Class states are defined as ClassState (see above).
    // Place the _init_state here to utilize the unused 2-byte after
    // _idnum_allocated_count.
    u1              _init_state;              // state of class
  
!   // This can be used to quickly discriminate among the four kinds of
    // InstanceKlass. This should be an enum (?)
    static const unsigned _kind_other        = 0; // concrete InstanceKlass
    static const unsigned _kind_reference    = 1; // InstanceRefKlass
    static const unsigned _kind_class_loader = 2; // InstanceClassLoaderKlass
    static const unsigned _kind_mirror       = 3; // InstanceMirrorKlass
  
    u1              _reference_type;                // reference type
    u1              _kind;                          // kind of InstanceKlass
  
    enum {
--- 249,17 ---
    // Class states are defined as ClassState (see above).
    // Place the _init_state here to utilize the unused 2-byte after
    // _idnum_allocated_count.
    u1              _init_state;              // state of class
  
!   // This can be used to quickly discriminate among the five kinds of
    // InstanceKlass. This should be an enum (?)
    static const unsigned _kind_other        = 0; // concrete InstanceKlass
    static const unsigned _kind_reference    = 1; // InstanceRefKlass
    static const unsigned _kind_class_loader = 2; // InstanceClassLoaderKlass
    static const unsigned _kind_mirror       = 3; // InstanceMirrorKlass
+   static const unsigned _kind_inline_type  = 4; // InlineKlass
  
    u1              _reference_type;                // reference type
    u1              _kind;                          // kind of InstanceKlass
  
    enum {

*** 253,16 ***
      _misc_is_shared_boot_class                = 1 << 10, // defining class loader is boot class loader
      _misc_is_shared_platform_class            = 1 << 11, // defining class loader is platform class loader
      _misc_is_shared_app_class                 = 1 << 12, // defining class loader is app class loader
      _misc_has_resolved_methods                = 1 << 13, // resolved methods table entries added for this class
      _misc_is_being_redefined                  = 1 << 14, // used for locking redefinition
!     _misc_has_contended_annotations           = 1 << 15  // has @Contended annotation
    };
    u2 shared_loader_type_bits() const {
      return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
    }
!   u2              _misc_flags;           // There is more space in access_flags for more flags.
  
    Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recursive initialization)
    OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
    JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
    jmethodID*      volatile _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
--- 276,30 ---
      _misc_is_shared_boot_class                = 1 << 10, // defining class loader is boot class loader
      _misc_is_shared_platform_class            = 1 << 11, // defining class loader is platform class loader
      _misc_is_shared_app_class                 = 1 << 12, // defining class loader is app class loader
      _misc_has_resolved_methods                = 1 << 13, // resolved methods table entries added for this class
      _misc_is_being_redefined                  = 1 << 14, // used for locking redefinition
!     _misc_has_contended_annotations           = 1 << 15,  // has @Contended annotation
+     _misc_has_inline_type_fields              = 1 << 16, // has inline fields and related embedded section is not empty
+     _misc_is_empty_inline_type                = 1 << 17, // empty inline type (*)
+     _misc_is_naturally_atomic                 = 1 << 18, // loaded/stored in one instruction
+     _misc_is_declared_atomic                  = 1 << 19, // implements jl.NonTearable
+     _misc_invalid_inline_super                = 1 << 20, // invalid super type for an inline type
+     _misc_invalid_identity_super              = 1 << 21, // invalid super type for an identity type
+     _misc_has_injected_identityObject         = 1 << 22, // IdentityObject has been injected by the JVM
+     _misc_has_injected_primitiveObject        = 1 << 23  // PrimitiveObject has been injected by the JVM
    };
+ 
+   // (*) An inline type is considered empty if it contains no non-static fields or
+   // if it contains only empty inline fields. Note that JITs have a slightly different
+   // definition: empty inline fields must be flattened otherwise the container won't
+   // be considered empty
+ 
    u2 shared_loader_type_bits() const {
      return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
    }
!   u4              _misc_flags;           // There is more space in access_flags for more flags.
  
    Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recursive initialization)
    OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
    JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
    jmethodID*      volatile _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none

*** 310,10 ***
--- 347,13 ---
    // fn: [access, name index, sig index, initial value index, low_offset, high_offset]
    //     [generic signature index]
    //     [generic signature index]
    //     ...
    Array<u2>*      _fields;
+   const Klass**   _inline_type_field_klasses; // For "inline class" fields, NULL if none present
+ 
+   const InlineKlassFixedBlock* _adr_inlineklass_fixed_block;
  
    // embedded Java vtable follows here
    // embedded Java itables follows here
    // embedded static fields follows here
    // embedded nonstatic oop-map blocks follows here

*** 374,10 ***
--- 414,83 ---
      } else {
        _misc_flags &= ~_misc_has_nonstatic_fields;
      }
    }
  
+   bool has_inline_type_fields() const          {
+     return (_misc_flags & _misc_has_inline_type_fields) != 0;
+   }
+   void set_has_inline_type_fields()  {
+     _misc_flags |= _misc_has_inline_type_fields;
+   }
+ 
+   bool is_empty_inline_type() const {
+     return (_misc_flags & _misc_is_empty_inline_type) != 0;
+   }
+   void set_is_empty_inline_type() {
+     _misc_flags |= _misc_is_empty_inline_type;
+   }
+ 
+   // Note:  The naturally_atomic property only applies to
+   // inline classes; it is never true on identity classes.
+   // The bit is placed on instanceKlass for convenience.
+ 
+   // Query if h/w provides atomic load/store for instances.
+   bool is_naturally_atomic() const {
+     return (_misc_flags & _misc_is_naturally_atomic) != 0;
+   }
+   // Initialized in the class file parser, not changed later.
+   void set_is_naturally_atomic() {
+     _misc_flags |= _misc_is_naturally_atomic;
+   }
+ 
+   // Query if this class implements jl.NonTearable or was
+   // mentioned in the JVM option ForceNonTearable.
+   // This bit can occur anywhere, but is only significant
+   // for inline classes *and* their super types.
+   // It inherits from supers along with NonTearable.
+   bool is_declared_atomic() const {
+     return (_misc_flags & _misc_is_declared_atomic) != 0;
+   }
+   // Initialized in the class file parser, not changed later.
+   void set_is_declared_atomic() {
+     _misc_flags |= _misc_is_declared_atomic;
+   }
+ 
+   // Query if class is an invalid super class for an inline type.
+   bool invalid_inline_super() const {
+     return (_misc_flags & _misc_invalid_inline_super) != 0;
+   }
+   // Initialized in the class file parser, not changed later.
+   void set_invalid_inline_super() {
+     _misc_flags |= _misc_invalid_inline_super;
+   }
+   // Query if class is an invalid super class for an identity type.
+   bool invalid_identity_super() const {
+     return (_misc_flags & _misc_invalid_identity_super) != 0;
+   }
+   // Initialized in the class file parser, not changed later.
+   void set_invalid_identity_super() {
+     _misc_flags |= _misc_invalid_identity_super;
+   }
+ 
+   bool has_injected_identityObject() const {
+     return (_misc_flags & _misc_has_injected_identityObject);
+   }
+ 
+   void set_has_injected_identityObject() {
+     _misc_flags |= _misc_has_injected_identityObject;
+   }
+ 
+   bool has_injected_primitiveObject() const {
+     return (_misc_flags & _misc_has_injected_primitiveObject);
+   }
+ 
+   void set_has_injected_primitiveObject() {
+     _misc_flags |= _misc_has_injected_primitiveObject;
+   }
+ 
    // field sizes
    int nonstatic_field_size() const         { return _nonstatic_field_size; }
    void set_nonstatic_field_size(int size)  { _nonstatic_field_size = size; }
  
    int static_field_size() const            { return _static_field_size; }

*** 389,14 ***
    // Java itable
    int  itable_length() const               { return _itable_len; }
    void set_itable_length(int len)          { _itable_len = len; }
  
    // array klasses
!   ObjArrayKlass* array_klasses() const     { return _array_klasses; }
!   inline ObjArrayKlass* array_klasses_acquire() const; // load with acquire semantics
!   void set_array_klasses(ObjArrayKlass* k) { _array_klasses = k; }
!   inline void release_set_array_klasses(ObjArrayKlass* k); // store with release semantics
  
    // methods
    Array<Method*>* methods() const          { return _methods; }
    void set_methods(Array<Method*>* a)      { _methods = a; }
    Method* method_with_idnum(int idnum);
--- 502,14 ---
    // Java itable
    int  itable_length() const               { return _itable_len; }
    void set_itable_length(int len)          { _itable_len = len; }
  
    // array klasses
!   ArrayKlass* array_klasses() const     { return _array_klasses; }
!   inline ArrayKlass* array_klasses_acquire() const; // load with acquire semantics
!   void set_array_klasses(ArrayKlass* k) { _array_klasses = k; }
!   inline void release_set_array_klasses(ArrayKlass* k); // store with release semantics
  
    // methods
    Array<Method*>* methods() const          { return _methods; }
    void set_methods(Array<Method*>* a)      { _methods = a; }
    Method* method_with_idnum(int idnum);

*** 436,10 ***
--- 549,12 ---
   public:
    int     field_offset      (int index) const { return field(index)->offset(); }
    int     field_access_flags(int index) const { return field(index)->access_flags(); }
    Symbol* field_name        (int index) const { return field(index)->name(constants()); }
    Symbol* field_signature   (int index) const { return field(index)->signature(constants()); }
+   bool    field_is_inlined(int index) const { return field(index)->is_inlined(); }
+   bool    field_is_null_free_inline_type(int index) const;
  
    // Number of Java declared fields
    int java_fields_count() const           { return (int)_java_fields_count; }
  
    Array<u2>* fields() const            { return _fields; }

*** 564,10 ***
--- 679,14 ---
  
    // marking
    bool is_marked_dependent() const         { return _is_marked_dependent; }
    void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
  
+   static ByteSize kind_offset() { return in_ByteSize(offset_of(InstanceKlass, _kind)); }
+   static ByteSize misc_flags_offset() { return in_ByteSize(offset_of(InstanceKlass, _misc_flags)); }
+   static u4 misc_flags_is_empty_inline_type() { return _misc_is_empty_inline_type; }
+ 
    // initialization (virtuals from Klass)
    bool should_be_initialized() const;  // means that initialize should be called
    void initialize(TRAPS);
    void link_class(TRAPS);
    bool link_class_or_fail(TRAPS); // returns false on failure

*** 732,12 ***
      }
    }
  
  #if INCLUDE_JVMTI
    // Redefinition locking.  Class can only be redefined by one thread at a time.
    bool is_being_redefined() const          {
!     return ((_misc_flags & _misc_is_being_redefined) != 0);
    }
    void set_is_being_redefined(bool value)  {
      if (value) {
        _misc_flags |= _misc_is_being_redefined;
      } else {
--- 851,13 ---
      }
    }
  
  #if INCLUDE_JVMTI
    // Redefinition locking.  Class can only be redefined by one thread at a time.
+ 
    bool is_being_redefined() const          {
!     return (_misc_flags & _misc_is_being_redefined);
    }
    void set_is_being_redefined(bool value)  {
      if (value) {
        _misc_flags |= _misc_is_being_redefined;
      } else {

*** 800,10 ***
--- 920,11 ---
    // Other is anything that is not one of the more specialized kinds of InstanceKlass.
    bool is_other_instance_klass() const        { return is_kind(_kind_other); }
    bool is_reference_instance_klass() const    { return is_kind(_kind_reference); }
    bool is_mirror_instance_klass() const       { return is_kind(_kind_mirror); }
    bool is_class_loader_instance_klass() const { return is_kind(_kind_class_loader); }
+   bool is_inline_type_klass()           const { return is_kind(_kind_inline_type); }
  
  #if INCLUDE_JVMTI
  
    void init_previous_versions() {
      _previous_versions = NULL;

*** 969,10 ***
--- 1090,13 ---
    // support for stub routines
    static ByteSize init_state_offset()  { return in_ByteSize(offset_of(InstanceKlass, _init_state)); }
    JFR_ONLY(DEFINE_KLASS_TRACE_ID_OFFSET;)
    static ByteSize init_thread_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_thread)); }
  
+   static ByteSize inline_type_field_klasses_offset() { return in_ByteSize(offset_of(InstanceKlass, _inline_type_field_klasses)); }
+   static ByteSize adr_inlineklass_fixed_block_offset() { return in_ByteSize(offset_of(InstanceKlass, _adr_inlineklass_fixed_block)); }
+ 
    // subclass/subinterface checks
    bool implements_interface(Klass* k) const;
    bool is_same_or_direct_interface(Klass* k) const;
  
  #ifdef ASSERT

*** 1004,12 ***
    void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
    void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
    void print_nonstatic_fields(FieldClosure* cl); // including inherited and injected fields
  
    void methods_do(void f(Method* method));
!   void array_klasses_do(void f(Klass* k));
!   void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
  
    static InstanceKlass* cast(Klass* k) {
      return const_cast<InstanceKlass*>(cast(const_cast<const Klass*>(k)));
    }
  
--- 1128,12 ---
    void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
    void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
    void print_nonstatic_fields(FieldClosure* cl); // including inherited and injected fields
  
    void methods_do(void f(Method* method));
!   virtual void array_klasses_do(void f(Klass* k));
!   virtual void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
  
    static InstanceKlass* cast(Klass* k) {
      return const_cast<InstanceKlass*>(cast(const_cast<const Klass*>(k)));
    }
  

*** 1026,37 ***
    // Sizing (in words)
    static int header_size()            { return sizeof(InstanceKlass)/wordSize; }
  
    static int size(int vtable_length, int itable_length,
                    int nonstatic_oop_map_size,
!                   bool is_interface) {
      return align_metadata_size(header_size() +
             vtable_length +
             itable_length +
             nonstatic_oop_map_size +
!            (is_interface ? (int)sizeof(Klass*)/wordSize : 0));
    }
  
    int size() const                    { return size(vtable_length(),
                                                 itable_length(),
                                                 nonstatic_oop_map_size(),
!                                                is_interface());
    }
  
  
    inline intptr_t* start_of_itable() const;
    inline intptr_t* end_of_itable() const;
    inline int itable_offset_in_words() const;
    inline oop static_field_base_raw();
  
    inline OopMapBlock* start_of_nonstatic_oop_maps() const;
    inline Klass** end_of_nonstatic_oop_maps() const;
  
    inline InstanceKlass* volatile* adr_implementor() const;
  
    // Use this to return the size of an instance in heap words:
!   int size_helper() const {
      return layout_helper_to_size_helper(layout_helper());
    }
  
    // This bit is initialized in classFileParser.cpp.
    // It is false under any of the following conditions:
--- 1150,49 ---
    // Sizing (in words)
    static int header_size()            { return sizeof(InstanceKlass)/wordSize; }
  
    static int size(int vtable_length, int itable_length,
                    int nonstatic_oop_map_size,
!                   bool is_interface,
+                   int java_fields, bool is_inline_type) {
      return align_metadata_size(header_size() +
             vtable_length +
             itable_length +
             nonstatic_oop_map_size +
!            (is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
+            (java_fields * (int)sizeof(Klass*)/wordSize) +
+            (is_inline_type ? (int)sizeof(InlineKlassFixedBlock) : 0));
    }
  
    int size() const                    { return size(vtable_length(),
                                                 itable_length(),
                                                 nonstatic_oop_map_size(),
!                                                is_interface(),
+                                                has_inline_type_fields() ? java_fields_count() : 0,
+                                                is_inline_klass());
    }
  
  
    inline intptr_t* start_of_itable() const;
    inline intptr_t* end_of_itable() const;
    inline int itable_offset_in_words() const;
    inline oop static_field_base_raw();
+   bool bounds_check(address addr, bool edge_ok = false, intptr_t size_in_bytes = -1) const PRODUCT_RETURN0;
  
    inline OopMapBlock* start_of_nonstatic_oop_maps() const;
    inline Klass** end_of_nonstatic_oop_maps() const;
  
    inline InstanceKlass* volatile* adr_implementor() const;
  
+   inline address adr_inline_type_field_klasses() const;
+   inline Klass* get_inline_type_field_klass(int idx) const;
+   inline Klass* get_inline_type_field_klass_or_null(int idx) const;
+   inline void set_inline_type_field_klass(int idx, Klass* k);
+   inline void reset_inline_type_field_klass(int idx);
+ 
    // Use this to return the size of an instance in heap words:
!   virtual int size_helper() const {
      return layout_helper_to_size_helper(layout_helper());
    }
  
    // This bit is initialized in classFileParser.cpp.
    // It is false under any of the following conditions:

*** 1106,10 ***
--- 1242,11 ---
  
    virtual void release_C_heap_structures();
  
    // Naming
    const char* signature_name() const;
+   const char* signature_name_of_carrier(char c) const;
  
    // Oop fields (and metadata) iterators
    //
    // The InstanceKlass iterators also visits the Object's klass.
  

*** 1233,11 ***
    void log_to_classlist() const;
  public:
    // CDS support - remove and restore oops from metadata. Oops are not shared.
    virtual void remove_unshareable_info();
    virtual void remove_java_mirror();
!   void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
    void init_shared_package_entry();
    bool can_be_verified_at_dumptime() const;
  
    jint compute_modifier_flags() const;
  
--- 1370,11 ---
    void log_to_classlist() const;
  public:
    // CDS support - remove and restore oops from metadata. Oops are not shared.
    virtual void remove_unshareable_info();
    virtual void remove_java_mirror();
!   virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
    void init_shared_package_entry();
    bool can_be_verified_at_dumptime() const;
  
    jint compute_modifier_flags() const;
  
< prev index next >