< 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/referenceType.hpp"
#include "oops/annotations.hpp"
#include "oops/constMethod.hpp"
#include "oops/fieldInfo.hpp"
#include "oops/instanceOop.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 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;
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;
+ 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:
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);
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);
// 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
// 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 {
// 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 {
_misc_shared_loading_failed = 1 << 8, // class has been loaded from shared archive
_misc_is_scratch_class = 1 << 9, // class is the redefined scratch class
_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_contended_annotations = 1 << 13 // 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
_misc_shared_loading_failed = 1 << 8, // class has been loaded from shared archive
_misc_is_scratch_class = 1 << 9, // class is the redefined scratch class
_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_contended_annotations = 1 << 13, // has @Contended annotation
+ _misc_has_inline_type_fields = 1 << 14, // has inline fields and related embedded section is not empty
+ _misc_is_empty_inline_type = 1 << 15, // empty inline type (*)
+ _misc_is_naturally_atomic = 1 << 16, // loaded/stored in one instruction
+ _misc_is_declared_atomic = 1 << 17, // implements jl.NonTearable
+ _misc_invalid_inline_super = 1 << 18, // invalid super type for an inline type
+ _misc_invalid_identity_super = 1 << 19, // invalid super type for an identity type
};
+
+ // (*) 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
// 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
+ Array<u2>* _preload_classes;
+ 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
if (b) {
_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;
+ }
+
// 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
// 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
// methods
Array<Method*>* methods() const { return _methods; }
void set_methods(Array<Method*>* a) { _methods = a; }
Method* method_with_idnum(int idnum);
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; }
guarantee(_fields == NULL || f == NULL, "Just checking");
_fields = f;
_java_fields_count = java_fields_count;
}
+ Array<u2>* preload_classes() const { return _preload_classes; }
+ void set_preload_classes(Array<u2>* c) { _preload_classes = c; }
+ bool is_preload_class(Symbol* name) const;
+
// 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 _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_flag_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
// 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;
// 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
// 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:
// 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:
virtual void release_C_heap_structures(bool release_constant_pool = 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.
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;
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 >