< prev index next >
src/hotspot/share/oops/instanceKlass.hpp
Print this page
*** 27,36 ****
--- 27,37 ----
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/moduleEntry.hpp"
#include "classfile/packageEntry.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"
*** 54,63 ****
--- 55,65 ----
// 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 unsafe_anonymous_host klass] only exist for an unsafe anonymous class (JSR 292 enabled)
// [EMBEDDED fingerprint ] only if should_store_fingerprint()==true
+ // [EMBEDDED ValueKlassFixedBlock] only if is a ValueKlass instance
// forward declaration for class -- see below for definition
#if INCLUDE_JVMTI
class BreakpointInfo;
*** 70,79 ****
--- 72,82 ----
class JNIid;
class JvmtiCachedClassFieldMap;
class nmethodBucket;
class SuperTypeClosure;
class OopMapCache;
+ class BufferedValueTypeBlob;
class InterpreterOopMap;
// This is used in iterators below.
class FieldClosure: public StackObj {
public:
*** 101,123 ****
--- 104,160 ----
// Number of oops in this block.
uint count() const { return _count; }
void set_count(uint count) { _count = count; }
+ void increment_count(int diff) { _count += diff; }
+
+ int offset_span() const { return _count * heapOopSize; }
+
+ int end_offset() const {
+ return offset() + offset_span();
+ }
+
+ bool is_contiguous(int another_offset) const {
+ return another_offset == end_offset();
+ }
+
// sizeof(OopMapBlock) in words.
static const int size_in_words() {
return align_up((int)sizeof(OopMapBlock), wordSize) >>
LogBytesPerWord;
}
+ static int compare_offset(const OopMapBlock* a, const OopMapBlock* b) {
+ return a->offset() - b->offset();
+ }
+
private:
int _offset;
uint _count;
};
struct JvmtiCachedClassFileData;
+ class SigEntry;
+
+ class ValueKlassFixedBlock {
+ Array<SigEntry>** _extended_sig;
+ Array<VMRegPair>** _return_regs;
+ address* _pack_handler;
+ address* _unpack_handler;
+ int* _default_value_offset;
+
+ friend class ValueKlass;
+ };
+
+ class ValueTypes {
+ public:
+ u2 _class_info_index;
+ Symbol* _class_name;
+ };
+
class InstanceKlass: public Klass {
friend class VMStructs;
friend class JVMCIVMStructs;
friend class ClassFileParser;
friend class CompileReplay;
*** 181,190 ****
--- 218,229 ----
// Resolved nest-host klass: either true nest-host or self if we are not nested.
// By always being set it makes nest-member access checks simpler.
InstanceKlass* _nest_host;
+ Array<ValueTypes>* _value_types;
+
// the source debug extension for this klass, NULL if not specified.
// Specified as UTF-8 string without terminating zero byte in the classfile,
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
const char* _source_debug_extension;
// Array name derived from this class which needs unreferencing
*** 207,248 ****
int _itable_len; // length of Java itable (in words)
// _is_marked_dependent can be set concurrently, thus cannot be part of the
// _misc_flags.
bool _is_marked_dependent; // used for marking during flushing and deoptimization
- bool _is_being_redefined; // used for locking redefinition
! // The low two bits of _misc_flags contains the kind field.
! // This can be used to quickly discriminate among the four kinds of
// InstanceKlass.
! static const unsigned _misc_kind_field_size = 2;
static const unsigned _misc_kind_field_pos = 0;
static const unsigned _misc_kind_field_mask = (1u << _misc_kind_field_size) - 1u;
static const unsigned _misc_kind_other = 0; // concrete InstanceKlass
static const unsigned _misc_kind_reference = 1; // InstanceRefKlass
static const unsigned _misc_kind_class_loader = 2; // InstanceClassLoaderKlass
static const unsigned _misc_kind_mirror = 3; // InstanceMirrorKlass
// Start after _misc_kind field.
enum {
! _misc_rewritten = 1 << 2, // methods rewritten.
! _misc_has_nonstatic_fields = 1 << 3, // for sizing with UseCompressedOops
! _misc_should_verify_class = 1 << 4, // allow caching of preverification
! _misc_is_unsafe_anonymous = 1 << 5, // has embedded _unsafe_anonymous_host field
! _misc_is_contended = 1 << 6, // marked with contended annotation
! _misc_has_nonstatic_concrete_methods = 1 << 7, // class/superclass/implemented interfaces has non-static, concrete methods
! _misc_declares_nonstatic_concrete_methods = 1 << 8, // directly declares non-static, concrete methods
! _misc_has_been_redefined = 1 << 9, // class has been redefined
! _misc_has_passed_fingerprint_check = 1 << 10, // when this class was loaded, the fingerprint computed from its
// code source was found to be matching the value recorded by AOT.
! _misc_is_scratch_class = 1 << 11, // class is the redefined scratch class
! _misc_is_shared_boot_class = 1 << 12, // defining class loader is boot class loader
! _misc_is_shared_platform_class = 1 << 13, // defining class loader is platform class loader
! _misc_is_shared_app_class = 1 << 14, // defining class loader is app class loader
! _misc_has_resolved_methods = 1 << 15 // resolved methods table entries added for this class
};
u2 loader_type_bits() {
return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
}
u2 _misc_flags;
--- 246,298 ----
int _itable_len; // length of Java itable (in words)
// _is_marked_dependent can be set concurrently, thus cannot be part of the
// _misc_flags.
bool _is_marked_dependent; // used for marking during flushing and deoptimization
! public:
! enum {
! _extra_is_being_redefined = 1 << 0, // used for locking redefinition
! _extra_has_resolved_methods = 1 << 1, // resolved methods table entries added for this class
! _extra_has_value_fields = 1 << 2, // has value fields and related embedded section is not empty
! _extra_is_bufferable = 1 << 3 // value can be buffered out side of the Java heap
! };
!
! protected:
! u1 _extra_flags;
!
! // The low three bits of _misc_flags contains the kind field.
! // This can be used to quickly discriminate among the five kinds of
// InstanceKlass.
! static const unsigned _misc_kind_field_size = 3;
static const unsigned _misc_kind_field_pos = 0;
static const unsigned _misc_kind_field_mask = (1u << _misc_kind_field_size) - 1u;
static const unsigned _misc_kind_other = 0; // concrete InstanceKlass
static const unsigned _misc_kind_reference = 1; // InstanceRefKlass
static const unsigned _misc_kind_class_loader = 2; // InstanceClassLoaderKlass
static const unsigned _misc_kind_mirror = 3; // InstanceMirrorKlass
+ static const unsigned _misc_kind_value_type = 4; // ValueKlass
// Start after _misc_kind field.
enum {
! _misc_rewritten = 1 << 3, // methods rewritten.
! _misc_has_nonstatic_fields = 1 << 4, // for sizing with UseCompressedOops
! _misc_should_verify_class = 1 << 5, // allow caching of preverification
! _misc_is_unsafe_anonymous = 1 << 6, // has embedded _unsafe_anonymous_host field
! _misc_is_contended = 1 << 7, // marked with contended annotation
! _misc_has_nonstatic_concrete_methods = 1 << 8, // class/superclass/implemented interfaces has non-static, concrete methods
! _misc_declares_nonstatic_concrete_methods = 1 << 9, // directly declares non-static, concrete methods
! _misc_has_been_redefined = 1 << 10, // class has been redefined
! _misc_has_passed_fingerprint_check = 1 << 11, // when this class was loaded, the fingerprint computed from its
// code source was found to be matching the value recorded by AOT.
! _misc_is_scratch_class = 1 << 12, // class is the redefined scratch class
! _misc_is_shared_boot_class = 1 << 13, // defining class loader is boot class loader
! _misc_is_shared_platform_class = 1 << 14, // defining class loader is platform class loader
! _misc_is_shared_app_class = 1 << 15 // defining class loader is app class loader
! // u2 _misc_flags full (see _extra_flags)
};
u2 loader_type_bits() {
return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
}
u2 _misc_flags;
*** 306,315 ****
--- 356,367 ----
// [generic signature index]
// [generic signature index]
// ...
Array<u2>* _fields;
+ const ValueKlassFixedBlock* _adr_valueklass_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
*** 375,384 ****
--- 427,443 ----
} else {
_misc_flags &= ~_misc_has_nonstatic_fields;
}
}
+ bool has_value_fields() const {
+ return (_extra_flags & _extra_has_value_fields) != 0;
+ }
+ void set_has_value_fields() {
+ _extra_flags |= _extra_has_value_fields;
+ }
+
// 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; }
*** 437,446 ****
--- 496,506 ----
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_flattened(int index) const { return field(index)->is_flattened(); }
// Number of Java declared fields
int java_fields_count() const { return (int)_java_fields_count; }
Array<u2>* fields() const { return _fields; }
*** 536,545 ****
--- 596,607 ----
// marking
bool is_marked_dependent() const { return _is_marked_dependent; }
void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
+ static ByteSize extra_flags_offset() { return in_ByteSize(offset_of(InstanceKlass, _extra_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
*** 572,582 ****
// find instance or static fields according to JVM spec 5.4.3.2, returns the klass in which the field is defined
Klass* find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const;
// find a non-static or static field given its offset within the class.
bool contains_field_offset(int offset) {
! return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size());
}
bool find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
--- 634,644 ----
// find instance or static fields according to JVM spec 5.4.3.2, returns the klass in which the field is defined
Klass* find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const;
// find a non-static or static field given its offset within the class.
bool contains_field_offset(int offset) {
! return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size(), is_value());
}
bool find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const;
*** 729,740 ****
_nonstatic_oop_map_size = words;
}
#if INCLUDE_JVMTI
// Redefinition locking. Class can only be redefined by one thread at a time.
! bool is_being_redefined() const { return _is_being_redefined; }
! void set_is_being_redefined(bool value) { _is_being_redefined = value; }
// RedefineClasses() support for previous versions:
void add_previous_version(InstanceKlass* ik, int emcp_method_count);
void purge_previous_version_list();
--- 791,810 ----
_nonstatic_oop_map_size = words;
}
#if INCLUDE_JVMTI
// Redefinition locking. Class can only be redefined by one thread at a time.
! bool is_being_redefined() const {
! return (_extra_flags & _extra_is_being_redefined);
! }
! void set_is_being_redefined(bool value) {
! if (value) {
! _extra_flags |= _extra_is_being_redefined;
! } else {
! _extra_flags &= ~_extra_is_being_redefined;
! }
! }
// RedefineClasses() support for previous versions:
void add_previous_version(InstanceKlass* ik, int emcp_method_count);
void purge_previous_version_list();
*** 784,798 ****
void set_is_scratch_class() {
_misc_flags |= _misc_is_scratch_class;
}
bool has_resolved_methods() const {
! return (_misc_flags & _misc_has_resolved_methods) != 0;
}
void set_has_resolved_methods() {
! _misc_flags |= _misc_has_resolved_methods;
}
private:
void set_kind(unsigned kind) {
assert(kind <= _misc_kind_field_mask, "Invalid InstanceKlass kind");
--- 854,868 ----
void set_is_scratch_class() {
_misc_flags |= _misc_is_scratch_class;
}
bool has_resolved_methods() const {
! return (_extra_flags & _extra_has_resolved_methods) != 0;
}
void set_has_resolved_methods() {
! _extra_flags |= _extra_has_resolved_methods;
}
private:
void set_kind(unsigned kind) {
assert(kind <= _misc_kind_field_mask, "Invalid InstanceKlass kind");
*** 811,820 ****
--- 881,891 ----
// Other is anything that is not one of the more specialized kinds of InstanceKlass.
bool is_other_instance_klass() const { return is_kind(_misc_kind_other); }
bool is_reference_instance_klass() const { return is_kind(_misc_kind_reference); }
bool is_mirror_instance_klass() const { return is_kind(_misc_kind_mirror); }
bool is_class_loader_instance_klass() const { return is_kind(_misc_kind_class_loader); }
+ bool is_value_type_klass() const { return is_kind(_misc_kind_value_type); }
#if INCLUDE_JVMTI
void init_previous_versions() {
_previous_versions = NULL;
*** 986,995 ****
--- 1057,1068 ----
// 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 adr_valueklass_fixed_block_offset() { return in_ByteSize(offset_of(InstanceKlass, _adr_valueklass_fixed_block)); }
+
// subclass/subinterface checks
bool implements_interface(Klass* k) const;
bool is_same_or_direct_interface(Klass* k) const;
#ifdef ASSERT
*** 1044,1068 ****
// 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_unsafe_anonymous, bool has_stored_fingerprint) {
return align_metadata_size(header_size() +
vtable_length +
itable_length +
nonstatic_oop_map_size +
(is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
(is_unsafe_anonymous ? (int)sizeof(Klass*)/wordSize : 0) +
! (has_stored_fingerprint ? (int)sizeof(uint64_t*)/wordSize : 0));
}
int size() const { return size(vtable_length(),
itable_length(),
nonstatic_oop_map_size(),
is_interface(),
is_unsafe_anonymous(),
! has_stored_fingerprint());
}
#if INCLUDE_SERVICES
virtual void collect_statistics(KlassSizeStats *sz) const;
#endif
--- 1117,1146 ----
// 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_unsafe_anonymous, bool has_stored_fingerprint,
! int java_fields, bool is_value_type) {
return align_metadata_size(header_size() +
vtable_length +
itable_length +
nonstatic_oop_map_size +
(is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
(is_unsafe_anonymous ? (int)sizeof(Klass*)/wordSize : 0) +
! (has_stored_fingerprint ? (int)sizeof(uint64_t*)/wordSize : 0) +
! (java_fields * (int)sizeof(Klass*)/wordSize) +
! (is_value_type ? (int)sizeof(ValueKlassFixedBlock) : 0));
}
int size() const { return size(vtable_length(),
itable_length(),
nonstatic_oop_map_size(),
is_interface(),
is_unsafe_anonymous(),
! has_stored_fingerprint(),
! has_value_fields() ? java_fields_count() : 0,
! is_value());
}
#if INCLUDE_SERVICES
virtual void collect_statistics(KlassSizeStats *sz) const;
#endif
*** 1071,1080 ****
--- 1149,1160 ----
int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
oop static_field_base_raw() { return java_mirror(); }
+ bool bounds_check(address addr, bool edge_ok = false, intptr_t size_in_bytes = -1) const PRODUCT_RETURN0;
+
OopMapBlock* start_of_nonstatic_oop_maps() const {
return (OopMapBlock*)(start_of_itable() + itable_length());
}
Klass** end_of_nonstatic_oop_maps() const {
*** 1119,1130 ****
} else {
return NULL;
}
}
// 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:
--- 1199,1255 ----
} else {
return NULL;
}
}
+ address adr_value_fields_klasses() const {
+ if (has_value_fields()) {
+ address adr_fing = adr_fingerprint();
+ if (adr_fing != NULL) {
+ return adr_fingerprint() + sizeof(u8);
+ }
+
+ InstanceKlass** adr_host = adr_unsafe_anonymous_host();
+ if (adr_host != NULL) {
+ return (address)(adr_host + 1);
+ }
+
+ Klass* volatile* adr_impl = adr_implementor();
+ if (adr_impl != NULL) {
+ return (address)(adr_impl + 1);
+ }
+
+ return (address)end_of_nonstatic_oop_maps();
+ } else {
+ return NULL;
+ }
+ }
+
+ Klass* get_value_field_klass(int idx) const {
+ assert(has_value_fields(), "Sanity checking");
+ Klass* k = ((Klass**)adr_value_fields_klasses())[idx];
+ assert(k != NULL, "Should always be set before being read");
+ assert(k->is_value(), "Must be a value type");
+ return k;
+ }
+
+ Klass* get_value_field_klass_or_null(int idx) const {
+ assert(has_value_fields(), "Sanity checking");
+ Klass* k = ((Klass**)adr_value_fields_klasses())[idx];
+ assert(k == NULL || k->is_value(), "Must be a value type");
+ return k;
+ }
+
+ void set_value_field_klass(int idx, Klass* k) {
+ assert(has_value_fields(), "Sanity checking");
+ assert(k != NULL, "Should not be set to NULL");
+ assert(((Klass**)adr_value_fields_klasses())[idx] == NULL, "Should not be set twice");
+ ((Klass**)adr_value_fields_klasses())[idx] = k;
+ }
+
// 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:
*** 1169,1178 ****
--- 1294,1304 ----
static void unload_class(InstanceKlass* ik);
static void release_C_heap_structures(InstanceKlass* ik);
// Naming
const char* signature_name() const;
+ const char* signature_name_of(char c) const;
static Symbol* package_from_name(const Symbol* name, TRAPS);
// Oop fields (and metadata) iterators
//
// The InstanceKlass iterators also visits the Object's klass.
*** 1262,1277 ****
void initialize_impl (TRAPS);
void initialize_super_interfaces (TRAPS);
void eager_initialize_impl ();
/* jni_id_for_impl for jfieldID only */
JNIid* jni_id_for_impl (int offset);
!
// Returns the array class for the n'th dimension
! Klass* array_klass_impl(bool or_null, int n, TRAPS);
// Returns the array class with this class as element type
! Klass* array_klass_impl(bool or_null, TRAPS);
// find a local method (returns NULL if not found)
Method* find_method_impl(const Symbol* name,
const Symbol* signature,
OverpassLookupMode overpass_mode,
--- 1388,1405 ----
void initialize_impl (TRAPS);
void initialize_super_interfaces (TRAPS);
void eager_initialize_impl ();
/* jni_id_for_impl for jfieldID only */
JNIid* jni_id_for_impl (int offset);
! protected:
// Returns the array class for the n'th dimension
! virtual Klass* array_klass_impl(bool or_null, int n, TRAPS);
// Returns the array class with this class as element type
! virtual Klass* array_klass_impl(bool or_null, TRAPS);
!
! private:
// find a local method (returns NULL if not found)
Method* find_method_impl(const Symbol* name,
const Symbol* signature,
OverpassLookupMode overpass_mode,
< prev index next >