< 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/allocation.hpp"
  #include "memory/referenceType.hpp"
  #include "oops/annotations.hpp"
  #include "oops/constMethod.hpp"
  #include "oops/fieldInfo.hpp"

*** 55,10 ***
--- 56,11 ---
  //    [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 InlineKlassFixedBlock] only if is an InlineKlass instance
  
  
  // forward declaration for class -- see below for definition
  #if INCLUDE_JVMTI
  class BreakpointInfo;

*** 71,10 ***
--- 73,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.

*** 131,15 ***
--- 134,71 ---
    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;
+   int* _null_reset_value_offset;
+   ArrayKlass** _null_free_inline_array_klasses;
+   int _first_field_offset;
+   int _payload_size_in_bytes;   // size of payload layout
+   int _payload_alignment;       // alignment required for payload
+   int _non_atomic_size_in_bytes; // size of null-free non-atomic flat layout
+   int _non_atomic_alignment;    // alignment requirement for null-free non-atomic layout
+   int _atomic_size_in_bytes;    // size and alignment requirement for a null-free atomic layout, -1 if no atomic flat layout is possible
+   int _nullable_size_in_bytes;  // size and alignment requirement for a nullable layout (always atomic), -1 if no nullable flat layout is possible
+   int _null_marker_offset;
+ 
+   friend class InlineKlass;
+ };
+ 
+ class InlineLayoutInfo : public MetaspaceObj {
+   InlineKlass* _klass;
+   LayoutKind _kind;
+   int _null_marker_offset; // null marker offset for this field, relative to the beginning of the current container
+ 
+  public:
+   InlineLayoutInfo(): _klass(nullptr), _kind(LayoutKind::UNKNOWN), _null_marker_offset(-1)  {}
+   InlineLayoutInfo(InlineKlass* ik, LayoutKind kind, int size, int nm_offset):
+     _klass(ik), _kind(kind), _null_marker_offset(nm_offset) {}
+ 
+   InlineKlass* klass() const { return _klass; }
+   void set_klass(InlineKlass* k) { _klass = k; }
+ 
+   LayoutKind kind() const {
+     assert(_kind != LayoutKind::UNKNOWN, "Not set");
+     return _kind;
+   }
+   void set_kind(LayoutKind lk) { _kind = lk; }
+ 
+   int null_marker_offset() const {
+     assert(_null_marker_offset != -1, "Not set");
+     return _null_marker_offset;
+   }
+   void set_null_marker_offset(int o) { _null_marker_offset = o; }
+ 
+   void metaspace_pointers_do(MetaspaceClosure* it);
+   MetaspaceObj::Type type() const { return InlineLayoutInfoType; }
+ 
+   static ByteSize klass_offset() { return in_ByteSize(offset_of(InlineLayoutInfo, _klass)); }
+   static ByteSize null_marker_offset_offset() { return in_ByteSize(offset_of(InlineLayoutInfo, _null_marker_offset)); }
+ };
+ 
  class InstanceKlass: public Klass {
    friend class VMStructs;
    friend class JVMCIVMStructs;
    friend class ClassFileParser;
    friend class CompileReplay;
+   friend class TemplateTable;
  
   public:
    static const KlassKind Kind = InstanceKlassKind;
  
   protected:

*** 171,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
--- 230,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

*** 278,10 ***
--- 337,14 ---
  
    // Fields information is stored in an UNSIGNED5 encoded stream (see fieldInfo.hpp)
    Array<u1>*          _fieldinfo_stream;
    Array<FieldStatus>* _fields_status;
  
+   Array<InlineLayoutInfo>* _inline_layout_info_array;
+   Array<u2>* _loadable_descriptors;
+   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
    // embedded implementor of this interface follows here

*** 331,10 ***
--- 394,31 ---
    void set_has_nonstatic_fields(bool b)    { _misc_flags.set_has_nonstatic_fields(b); }
  
    bool has_localvariable_table() const     { return _misc_flags.has_localvariable_table(); }
    void set_has_localvariable_table(bool b) { _misc_flags.set_has_localvariable_table(b); }
  
+   bool has_inline_type_fields() const { return _misc_flags.has_inline_type_fields(); }
+   void set_has_inline_type_fields()   { _misc_flags.set_has_inline_type_fields(true); }
+ 
+   bool is_naturally_atomic() const  { return _misc_flags.is_naturally_atomic(); }
+   void set_is_naturally_atomic()    { _misc_flags.set_is_naturally_atomic(true); }
+ 
+   // Query if this class has atomicity requirements (default is yes)
+   // This bit can occur anywhere, but is only significant
+   // for inline classes *and* their super types.
+   // It inherits from supers.
+   // Its value depends on the ForceNonTearable VM option, the LooselyConsistentValue annotation
+   // and the presence of flat fields with atomicity requirements
+   bool must_be_atomic() const { return _misc_flags.must_be_atomic(); }
+   void set_must_be_atomic()   { _misc_flags.set_must_be_atomic(true); }
+ 
+   // Query if this class can be implicitly constructed, meaning the VM is allowed
+   // to create instances without calling a constructor
+   // Applies to inline classes and their super types
+   bool is_implicitly_constructible() const { return _misc_flags.is_implicitly_constructible(); }
+   void set_is_implicitly_constructible()   { _misc_flags.set_is_implicitly_constructible(true); }
+ 
    // 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; }

*** 346,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
!   inline void release_set_array_klasses(ObjArrayKlass* k); // store with release semantics
!   void set_array_klasses(ObjArrayKlass* k) { _array_klasses = k; }
  
    // methods
    Array<Method*>* methods() const          { return _methods; }
    void set_methods(Array<Method*>* a)      { _methods = a; }
    Method* method_with_idnum(int idnum);
--- 430,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
!   inline void release_set_array_klasses(ArrayKlass* k); // store with release semantics
!   void set_array_klasses(ArrayKlass* k) { _array_klasses = k; }
  
    // methods
    Array<Method*>* methods() const          { return _methods; }
    void set_methods(Array<Method*>* a)      { _methods = a; }
    Method* method_with_idnum(int idnum);

*** 389,16 ***
   private:
    friend class fieldDescriptor;
    FieldInfo field(int index) const;
  
   public:
!   int     field_offset      (int index) const { return field(index).offset(); }
!   int     field_access_flags(int index) const { return field(index).access_flags().as_int(); }
    FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); }
    FieldStatus field_status(int index)   const { return fields_status()->at(index); }
    inline Symbol* field_name        (int index) const;
    inline Symbol* field_signature   (int index) const;
  
    // Number of Java declared fields
    int java_fields_count() const;
    int total_fields_count() const;
  
--- 473,20 ---
   private:
    friend class fieldDescriptor;
    FieldInfo field(int index) const;
  
   public:
!   int field_offset      (int index) const { return field(index).offset(); }
!   int field_access_flags(int index) const { return field(index).access_flags().as_int(); }
    FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); }
    FieldStatus field_status(int index)   const { return fields_status()->at(index); }
    inline Symbol* field_name        (int index) const;
    inline Symbol* field_signature   (int index) const;
+   bool field_is_flat(int index) const { return field_flags(index).is_flat(); }
+   bool field_has_null_marker(int index) const { return field_flags(index).has_null_marker(); }
+   bool field_is_null_free_inline_type(int index) const;
+   bool is_class_in_loadable_descriptors_attribute(Symbol* name) const;
  
    // Number of Java declared fields
    int java_fields_count() const;
    int total_fields_count() const;
  

*** 406,10 ***
--- 494,13 ---
    void set_fieldinfo_stream(Array<u1>* fis) { _fieldinfo_stream = fis; }
  
    Array<FieldStatus>* fields_status() const {return _fields_status; }
    void set_fields_status(Array<FieldStatus>* array) { _fields_status = array; }
  
+   Array<u2>* loadable_descriptors() const { return _loadable_descriptors; }
+   void set_loadable_descriptors(Array<u2>* c) { _loadable_descriptors = c; }
+ 
    // inner classes
    Array<u2>* inner_classes() const       { return _inner_classes; }
    void set_inner_classes(Array<u2>* f)   { _inner_classes = f; }
  
    // nest members

*** 527,10 ***
--- 618,13 ---
  
    // marking
    bool is_marked_dependent() const         { return _misc_flags.is_marked_dependent(); }
    void set_is_marked_dependent(bool value) { _misc_flags.set_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)); }
+ 
    // 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

*** 853,10 ***
--- 947,13 ---
    // support for stub routines
    static ByteSize init_state_offset()  { return byte_offset_of(InstanceKlass, _init_state); }
    JFR_ONLY(DEFINE_KLASS_TRACE_ID_OFFSET;)
    static ByteSize init_thread_offset() { return byte_offset_of(InstanceKlass, _init_thread); }
  
+   static ByteSize inline_layout_info_array_offset() { return in_ByteSize(offset_of(InstanceKlass, _inline_layout_info_array)); }
+   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

*** 910,36 ***
    // 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 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:
--- 1007,58 ---
    // 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,
+                   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) +
+            (is_inline_type ? (int)sizeof(InlineKlassFixedBlock) : 0));
    }
  
    int size() const                    { return size(vtable_length(),
                                                 itable_length(),
                                                 nonstatic_oop_map_size(),
!                                                is_interface(),
+                                                is_inline_klass());
    }
  
  
    inline intptr_t* start_of_itable() const;
    inline intptr_t* end_of_itable() 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;
  
+   void set_inline_layout_info_array(Array<InlineLayoutInfo>* array) { _inline_layout_info_array = array; }
+   Array<InlineLayoutInfo>* inline_layout_info_array() const { return _inline_layout_info_array; }
+   void set_inline_layout_info(int index, InlineLayoutInfo *info) {
+     assert(_inline_layout_info_array != nullptr ,"Array not created");
+     _inline_layout_info_array->at_put(index, *info);
+   }
+   InlineLayoutInfo inline_layout_info(int index) const {
+     assert(_inline_layout_info_array != nullptr ,"Array not created");
+     return _inline_layout_info_array->at(index);
+   }
+   InlineLayoutInfo* inline_layout_info_adr(int index) {
+     assert(_inline_layout_info_array != nullptr ,"Array not created");
+     return _inline_layout_info_array->adr_at(index);
+   }
+ 
+   inline InlineKlass* get_inline_type_field_klass(int idx) const ;
+   inline InlineKlass* get_inline_type_field_klass_or_null(int idx) const;
+ 
    // 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:

*** 986,10 ***
--- 1105,11 ---
  
    virtual void release_C_heap_structures(bool release_sub_metadata = true);
  
    // 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.
  

*** 1111,11 ***
  #if INCLUDE_CDS
    // CDS support - remove and restore oops from metadata. Oops are not shared.
    virtual void remove_unshareable_info();
    void remove_unshareable_flags();
    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;
    bool methods_contain_jsr_bytecode() const;
    void compute_has_loops_flag_for_methods();
  #endif
--- 1231,11 ---
  #if INCLUDE_CDS
    // CDS support - remove and restore oops from metadata. Oops are not shared.
    virtual void remove_unshareable_info();
    void remove_unshareable_flags();
    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;
    bool methods_contain_jsr_bytecode() const;
    void compute_has_loops_flag_for_methods();
  #endif
< prev index next >