< prev index next > src/hotspot/share/oops/instanceKlass.hpp
Print this page
*/
#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"
// [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;
class jniIdMapBase;
class JNIid;
class JvmtiCachedClassFieldMap;
class nmethodBucket;
class OopMapCache;
+ class BufferedInlineTypeBlob;
class InterpreterOopMap;
class PackageEntry;
class ModuleEntry;
// This is used in iterators below.
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:
// 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
// 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
// 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
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; }
// 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);
// 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);
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;
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;
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
// 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
// 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
// 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:
// 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:
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.
#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
#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 >