< 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 >