Mercurial > hg > graal-compiler
diff src/share/vm/oops/instanceKlass.hpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | dddcdb7ae209 4735d2c84362 |
children | 2cb439954abf |
line wrap: on
line diff
--- a/src/share/vm/oops/instanceKlass.hpp Mon Nov 12 18:11:17 2012 +0100 +++ b/src/share/vm/oops/instanceKlass.hpp Mon Nov 12 23:14:12 2012 +0100 @@ -25,24 +25,21 @@ #ifndef SHARE_VM_OOPS_INSTANCEKLASS_HPP #define SHARE_VM_OOPS_INSTANCEKLASS_HPP -#include "oops/constMethodOop.hpp" -#include "oops/constantPoolOop.hpp" +#include "classfile/classLoaderData.hpp" +#include "oops/annotations.hpp" +#include "oops/constMethod.hpp" #include "oops/fieldInfo.hpp" #include "oops/instanceOop.hpp" -#include "oops/klassOop.hpp" #include "oops/klassVtable.hpp" -#include "oops/objArrayOop.hpp" #include "runtime/handles.hpp" #include "runtime/os.hpp" #include "utilities/accessFlags.hpp" #include "utilities/bitMap.inline.hpp" -// An instanceKlass is the VM level representation of a Java class. +// An InstanceKlass is the VM level representation of a Java class. // It contains all information needed for at class at execution runtime. -// instanceKlass layout: -// [header ] klassOop -// [klass pointer ] klassOop +// InstanceKlass layout: // [C++ vtbl pointer ] Klass // [subtype cache ] Klass // [instance size ] Klass @@ -98,7 +95,7 @@ virtual void do_field(fieldDescriptor* fd) = 0; }; -//#ifndef PRODUCT +#ifndef PRODUCT // Print fields. // If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields. class FieldPrinter: public FieldClosure { @@ -108,7 +105,7 @@ FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {} void do_field(fieldDescriptor* fd); }; -//#endif // !PRODUCT +#endif // !PRODUCT // ValueObjs embedded in klass. Describes where oops are located in instances of // this klass. @@ -133,13 +130,37 @@ uint _count; }; -class instanceKlass: public Klass { +class InstanceKlass: public Klass { friend class VMStructs; + friend class ClassFileParser; + + protected: + // Constructor + InstanceKlass(int vtable_len, + int itable_len, + int static_field_size, + int nonstatic_oop_map_size, + ReferenceType rt, + AccessFlags access_flags, + bool is_anonymous); public: + static Klass* allocate_instance_klass(ClassLoaderData* loader_data, + int vtable_len, + int itable_len, + int static_field_size, + int nonstatic_oop_map_size, + ReferenceType rt, + AccessFlags access_flags, + Symbol* name, + Klass* super_klass, + KlassHandle host_klass, + TRAPS); + + InstanceKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); } + // See "The Java Virtual Machine Specification" section 2.16.2-5 for a detailed description // of the class loading & initialization procedure, and the use of the states. enum ClassState { - unparsable_by_gc = 0, // object is not yet parsable by gc. Value of _init_state at object allocation. 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) @@ -148,48 +169,22 @@ initialization_error // error happened during initialization }; - public: - oop* oop_block_beg() const { return adr_array_klasses(); } - oop* oop_block_end() const { return adr_methods_default_annotations() + 1; } - protected: - // - // The oop block. See comment in klass.hpp before making changes. - // - - // Array classes holding elements of this class. - klassOop _array_klasses; - // Method array. - objArrayOop _methods; - // Int array containing the original order of method in the class file (for - // JVMTI). - typeArrayOop _method_ordering; - // Interface (klassOops) this class declares locally to implement. - objArrayOop _local_interfaces; - // Interface (klassOops) this class implements transitively. - objArrayOop _transitive_interfaces; - // Instance and static variable information, starts with 6-tuples of shorts - // [access, name index, sig index, initval index, low_offset, high_offset] - // for all fields, followed by the generic signature data at the end of - // the array. Only fields with generic signature attributes have the generic - // signature data set in the array. The fields array looks like following: - // - // f1: [access, name index, sig index, initial value index, low_offset, high_offset] - // f2: [access, name index, sig index, initial value index, low_offset, high_offset] - // ... - // fn: [access, name index, sig index, initial value index, low_offset, high_offset] - // [generic signature index] - // [generic signature index] - // ... - typeArrayOop _fields; - // Constant pool for this class. - constantPoolOop _constants; - // Class loader used to load this class, NULL if VM loader used. - oop _class_loader; // Protection domain. oop _protection_domain; // Class signers. objArrayOop _signers; + // Initialization lock. Must be one per class and it has to be a VM internal + // object so java code cannot lock it (like the mirror) + // It has to be an object not a Mutex because it's held through java calls. + volatile oop _init_lock; + + // Annotations for this class + Annotations* _annotations; + // Array classes holding elements of this class. + Klass* _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 @@ -201,27 +196,7 @@ // number_of_inner_classes * 4. If the class has both InnerClasses // and EnclosingMethod attributes the _inner_classes array length is // number_of_inner_classes * 4 + enclosing_method_attribute_size. - typeArrayOop _inner_classes; - // Annotations for this class, or null if none. - typeArrayOop _class_annotations; - // Annotation objects (byte arrays) for fields, or null if no annotations. - // Indices correspond to entries (not indices) in fields array. - objArrayOop _fields_annotations; - // Annotation objects (byte arrays) for methods, or null if no annotations. - // Index is the idnum, which is initially the same as the methods array index. - objArrayOop _methods_annotations; - // Annotation objects (byte arrays) for methods' parameters, or null if no - // such annotations. - // Index is the idnum, which is initially the same as the methods array index. - objArrayOop _methods_parameter_annotations; - // Annotation objects (byte arrays) for methods' default values, or null if no - // such annotations. - // Index is the idnum, which is initially the same as the methods array index. - objArrayOop _methods_default_annotations; - - // - // End of the oop block. - // + Array<jushort>* _inner_classes; // Name of source file containing this klass, NULL if not specified. Symbol* _source_file_name; @@ -262,15 +237,41 @@ int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL nmethodBucket* _dependencies; // list of dependent nmethods nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class - BreakpointInfo* _breakpoints; // bpt lists, managed by methodOop + BreakpointInfo* _breakpoints; // bpt lists, managed by Method* // Array of interesting part(s) of the previous version(s) of this - // instanceKlass. See PreviousVersionWalker below. + // InstanceKlass. See PreviousVersionWalker below. GrowableArray<PreviousVersionNode *>* _previous_versions; // JVMTI fields can be moved to their own structure - see 6315920 unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH jint _cached_class_file_len; // JVMTI: length of above JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration + + // true if class, superclass, or implemented interfaces have default methods + bool _has_default_methods; + volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change + // Method array. + Array<Method*>* _methods; + // Interface (Klass*s) this class declares locally to implement. + Array<Klass*>* _local_interfaces; + // Interface (Klass*s) this class implements transitively. + Array<Klass*>* _transitive_interfaces; + // Int array containing the original order of method in the class file (for JVMTI). + Array<int>* _method_ordering; + // Instance and static variable information, starts with 6-tuples of shorts + // [access, name index, sig index, initval index, low_offset, high_offset] + // for all fields, followed by the generic signature data at the end of + // the array. Only fields with generic signature attributes have the generic + // signature data set in the array. The fields array looks like following: + // + // f1: [access, name index, sig index, initial value index, low_offset, high_offset] + // f2: [access, name index, sig index, initial value index, low_offset, high_offset] + // ... + // fn: [access, name index, sig index, initial value index, low_offset, high_offset] + // [generic signature index] + // [generic signature index] + // ... + Array<u2>* _fields; // Class states are defined as ClassState (see above). // Place the _init_state here to utilize the unused 2-byte after @@ -288,7 +289,7 @@ // iterface. The possible values of the implementor fall into following // three cases: // NULL: no implementor. - // A klassOop that's not itself: one implementor. + // A Klass* that's not itself: one implementor. // Itsef: more than one implementors. // embedded host klass follows here // The embedded host klass only exists in an anonymous class for @@ -299,7 +300,6 @@ // have this embedded field. // - friend class instanceKlassKlass; friend class SystemDictionary; public: @@ -333,23 +333,27 @@ void set_itable_length(int len) { _itable_len = len; } // array klasses - klassOop array_klasses() const { return _array_klasses; } - void set_array_klasses(klassOop k) { oop_store_without_check((oop*) &_array_klasses, (oop) k); } + Klass* array_klasses() const { return _array_klasses; } + void set_array_klasses(Klass* k) { _array_klasses = k; } // methods - objArrayOop methods() const { return _methods; } - void set_methods(objArrayOop a) { oop_store_without_check((oop*) &_methods, (oop) a); } - methodOop method_with_idnum(int idnum); + Array<Method*>* methods() const { return _methods; } + void set_methods(Array<Method*>* a) { _methods = a; } + Method* method_with_idnum(int idnum); // method ordering - typeArrayOop method_ordering() const { return _method_ordering; } - void set_method_ordering(typeArrayOop m) { oop_store_without_check((oop*) &_method_ordering, (oop) m); } + Array<int>* method_ordering() const { return _method_ordering; } + void set_method_ordering(Array<int>* m) { _method_ordering = m; } // interfaces - objArrayOop local_interfaces() const { return _local_interfaces; } - void set_local_interfaces(objArrayOop a) { oop_store_without_check((oop*) &_local_interfaces, (oop) a); } - objArrayOop transitive_interfaces() const { return _transitive_interfaces; } - void set_transitive_interfaces(objArrayOop a) { oop_store_without_check((oop*) &_transitive_interfaces, (oop) a); } + Array<Klass*>* local_interfaces() const { return _local_interfaces; } + void set_local_interfaces(Array<Klass*>* a) { + guarantee(_local_interfaces == NULL || a == NULL, "Just checking"); + _local_interfaces = a; } + Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; } + void set_transitive_interfaces(Array<Klass*>* a) { + guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking"); + _transitive_interfaces = a; } private: friend class fieldDescriptor; @@ -364,16 +368,17 @@ // Number of Java declared fields int java_fields_count() const { return (int)_java_fields_count; } - typeArrayOop fields() const { return _fields; } + Array<u2>* fields() const { return _fields; } - void set_fields(typeArrayOop f, u2 java_fields_count) { - oop_store_without_check((oop*) &_fields, (oop) f); + void set_fields(Array<u2>* f, u2 java_fields_count) { + guarantee(_fields == NULL || f == NULL, "Just checking"); + _fields = f; _java_fields_count = java_fields_count; } // inner classes - typeArrayOop inner_classes() const { return _inner_classes; } - void set_inner_classes(typeArrayOop f) { oop_store_without_check((oop*) &_inner_classes, (oop) f); } + Array<u2>* inner_classes() const { return _inner_classes; } + void set_inner_classes(Array<u2>* f) { _inner_classes = f; } enum InnerClassAttributeOffset { // From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814 @@ -394,25 +399,25 @@ bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS); // package - bool is_same_class_package(klassOop class2); + bool is_same_class_package(Klass* class2); bool is_same_class_package(oop classloader2, Symbol* classname2); static bool is_same_class_package(oop class_loader1, Symbol* class_name1, oop class_loader2, Symbol* class_name2); // find an enclosing class (defined where original code was, in jvm.cpp!) - klassOop compute_enclosing_class(bool* inner_is_member, TRAPS) { - instanceKlassHandle self(THREAD, this->as_klassOop()); + Klass* compute_enclosing_class(bool* inner_is_member, TRAPS) { + instanceKlassHandle self(THREAD, this); return compute_enclosing_class_impl(self, inner_is_member, THREAD); } - static klassOop compute_enclosing_class_impl(instanceKlassHandle self, + static Klass* compute_enclosing_class_impl(instanceKlassHandle self, bool* inner_is_member, TRAPS); // tell if two classes have the same enclosing class (at package level) - bool is_same_package_member(klassOop class2, TRAPS) { - instanceKlassHandle self(THREAD, this->as_klassOop()); + bool is_same_package_member(Klass* class2, TRAPS) { + instanceKlassHandle self(THREAD, this); return is_same_package_member_impl(self, class2, THREAD); } static bool is_same_package_member_impl(instanceKlassHandle self, - klassOop class2, TRAPS); + Klass* class2, TRAPS); // initialization state bool is_loaded() const { return _init_state >= loaded; } @@ -449,7 +454,7 @@ void unlink_class(); void rewrite_class(TRAPS); void relocate_and_link_methods(TRAPS); - methodOop class_initializer(); + Method* class_initializer(); // set the class to initialized if no static initializer is present void eager_initialize(Thread *thread); @@ -461,16 +466,16 @@ _reference_type = (u1)t; } - static ByteSize reference_type_offset() { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _reference_type)); } + static ByteSize reference_type_offset() { return in_ByteSize(offset_of(InstanceKlass, _reference_type)); } // find local field, returns true if found bool find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find field in direct superinterfaces, returns the interface in which the field is defined - klassOop find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + Klass* find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined - klassOop find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find instance or static fields according to JVM spec 5.4.3.2, returns the klass in which the field is defined - klassOop find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const; + 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) { @@ -481,42 +486,45 @@ bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const; // find a local method (returns NULL if not found) - methodOop find_method(Symbol* name, Symbol* signature) const; - static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature); + Method* find_method(Symbol* name, Symbol* signature) const; + static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature); // lookup operation (returns NULL if not found) - methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; + Method* uncached_lookup_method(Symbol* name, Symbol* signature) const; // lookup a method in all the interfaces that this class implements // (returns NULL if not found) - methodOop lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const; + Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const; + + // Find method indices by name. If a method with the specified name is + // found the index to the first method is returned, and 'end' is filled in + // with the index of first non-name-matching method. If no method is found + // -1 is returned. + int find_method_by_name(Symbol* name, int* end); + static int find_method_by_name(Array<Method*>* methods, Symbol* name, int* end); // constant pool - constantPoolOop constants() const { return _constants; } - void set_constants(constantPoolOop c) { oop_store_without_check((oop*) &_constants, (oop) c); } - - // class loader - oop class_loader() const { return _class_loader; } - void set_class_loader(oop l) { oop_store((oop*) &_class_loader, l); } + ConstantPool* constants() const { return _constants; } + void set_constants(ConstantPool* c) { _constants = c; } // protection domain oop protection_domain() { return _protection_domain; } - void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); } + void set_protection_domain(oop pd) { klass_oop_store(&_protection_domain, pd); } // host class - oop host_klass() const { - oop* hk = adr_host_klass(); + Klass* host_klass() const { + Klass** hk = (Klass**)adr_host_klass(); if (hk == NULL) { return NULL; } else { return *hk; } } - void set_host_klass(oop host) { + void set_host_klass(Klass* host) { assert(is_anonymous(), "not anonymous"); - oop* addr = adr_host_klass(); + Klass** addr = (Klass**)adr_host_klass(); assert(addr != NULL, "no reversed space"); - oop_store(addr, host); + *addr = host; } bool is_anonymous() const { return (_misc_flags & _misc_is_anonymous) != 0; @@ -531,7 +539,7 @@ // signers objArrayOop signers() const { return _signers; } - void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); } + void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); } // source file name Symbol* source_file_name() const { return _source_file_name; } @@ -578,6 +586,8 @@ return _previous_versions; } + static void purge_previous_versions(InstanceKlass* ik); + // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation void set_cached_class_file(unsigned char *class_file_bytes, jint class_file_len) { _cached_class_file_len = class_file_len; @@ -593,7 +603,10 @@ return _jvmti_cached_class_field_map; } - // for adding methods, constMethodOopDesc::UNSET_IDNUM means no more ids available + bool has_default_methods() const { return _has_default_methods; } + void set_has_default_methods(bool b) { _has_default_methods = b; } + + // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } @@ -620,40 +633,26 @@ jmethodID** to_dealloc_jmeths_p); static void get_jmethod_id_length_value(jmethodID* cache, size_t idnum, size_t *length_p, jmethodID* id_p); - jmethodID jmethod_id_or_null(methodOop method); + jmethodID jmethod_id_or_null(Method* method); // cached itable index support void set_cached_itable_index(size_t idnum, int index); int cached_itable_index(size_t idnum); // annotations support - typeArrayOop class_annotations() const { return _class_annotations; } - objArrayOop fields_annotations() const { return _fields_annotations; } - objArrayOop methods_annotations() const { return _methods_annotations; } - objArrayOop methods_parameter_annotations() const { return _methods_parameter_annotations; } - objArrayOop methods_default_annotations() const { return _methods_default_annotations; } - void set_class_annotations(typeArrayOop md) { oop_store_without_check((oop*)&_class_annotations, (oop)md); } - void set_fields_annotations(objArrayOop md) { set_annotations(md, &_fields_annotations); } - void set_methods_annotations(objArrayOop md) { set_annotations(md, &_methods_annotations); } - void set_methods_parameter_annotations(objArrayOop md) { set_annotations(md, &_methods_parameter_annotations); } - void set_methods_default_annotations(objArrayOop md) { set_annotations(md, &_methods_default_annotations); } - typeArrayOop get_method_annotations_of(int idnum) - { return get_method_annotations_from(idnum, _methods_annotations); } - typeArrayOop get_method_parameter_annotations_of(int idnum) - { return get_method_annotations_from(idnum, _methods_parameter_annotations); } - typeArrayOop get_method_default_annotations_of(int idnum) - { return get_method_annotations_from(idnum, _methods_default_annotations); } - void set_method_annotations_of(int idnum, typeArrayOop anno) - { set_methods_annotations_of(idnum, anno, &_methods_annotations); } - void set_method_parameter_annotations_of(int idnum, typeArrayOop anno) - { set_methods_annotations_of(idnum, anno, &_methods_parameter_annotations); } - void set_method_default_annotations_of(int idnum, typeArrayOop anno) - { set_methods_annotations_of(idnum, anno, &_methods_default_annotations); } + Annotations* annotations() const { return _annotations; } + void set_annotations(Annotations* anno) { _annotations = anno; } + AnnotationArray* class_annotations() const { + if (annotations() == NULL) return NULL; + return annotations()->class_annotations(); + } + Array<AnnotationArray*>* fields_annotations() const { + if (annotations() == NULL) return NULL; + return annotations()->fields_annotations(); + } // allocation - DEFINE_ALLOCATE_PERMANENT(instanceKlass); instanceOop allocate_instance(TRAPS); - instanceOop allocate_permanent_instance(TRAPS); // additional member function to return a handle instanceHandle allocate_instance_handle(TRAPS) { return instanceHandle(THREAD, allocate_instance(THREAD)); } @@ -690,24 +689,24 @@ void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; void add_osr_nmethod(nmethod* n); void remove_osr_nmethod(nmethod* n); - nmethod* lookup_osr_nmethod(const methodOop m, int bci, int level, bool match_level) const; + nmethod* lookup_osr_nmethod(Method* const m, int bci, int level, bool match_level) const; - // Breakpoint support (see methods on methodOop for details) + // Breakpoint support (see methods on Method* for details) BreakpointInfo* breakpoints() const { return _breakpoints; }; void set_breakpoints(BreakpointInfo* bps) { _breakpoints = bps; }; // support for stub routines - static ByteSize init_state_offset() { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _init_state)); } + static ByteSize init_state_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_state)); } TRACE_DEFINE_OFFSET; - static ByteSize init_thread_offset() { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _init_thread)); } + static ByteSize init_thread_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_thread)); } // subclass/subinterface checks - bool implements_interface(klassOop k) const; + bool implements_interface(Klass* k) const; // Access to the implementor of an interface. - klassOop implementor() const + Klass* implementor() const { - klassOop* k = (klassOop*)adr_implementor(); + Klass** k = adr_implementor(); if (k == NULL) { return NULL; } else { @@ -715,36 +714,35 @@ } } - void set_implementor(klassOop k) { + void set_implementor(Klass* k) { assert(is_interface(), "not interface"); - oop* addr = adr_implementor(); - oop_store_without_check(addr, k); + Klass** addr = adr_implementor(); + *addr = k; } int nof_implementors() const { - klassOop k = implementor(); + Klass* k = implementor(); if (k == NULL) { return 0; - } else if (k != this->as_klassOop()) { + } else if (k != this) { return 1; } else { return 2; } } - void add_implementor(klassOop k); // k is a new class that implements this interface + void add_implementor(Klass* k); // k is a new class that implements this interface void init_implementor(); // initialize // link this class into the implementors list of every interface it implements void process_interfaces(Thread *thread); // virtual operations from Klass - objArrayOop compute_secondary_supers(int num_extra_slots, TRAPS); - bool compute_is_subtype_of(klassOop k); + bool is_leaf_class() const { return _subklass == NULL; } + GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots); + bool compute_is_subtype_of(Klass* k); bool can_be_primary_super_slow() const; - klassOop java_super() const { return super(); } int oop_size(oop obj) const { return size_helper(); } - int klass_oop_size() const { return object_size(); } bool oop_is_instance_slow() const { return true; } // Iterators @@ -752,39 +750,50 @@ void do_nonstatic_fields(FieldClosure* cl); // including inherited fields void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS); - void methods_do(void f(methodOop method)); - void array_klasses_do(void f(klassOop k)); - void with_array_klasses_do(void f(klassOop k)); + void methods_do(void f(Method* method)); + void array_klasses_do(void f(Klass* k)); + void array_klasses_do(void f(Klass* k, TRAPS), TRAPS); + void with_array_klasses_do(void f(Klass* k)); bool super_types_do(SuperTypeClosure* blk); - // Casting from klassOop - static instanceKlass* cast(klassOop k) { + // Casting from Klass* + static InstanceKlass* cast(Klass* k) { assert(k->is_klass(), "must be"); - Klass* kp = k->klass_part(); - assert(kp->null_vtbl() || kp->oop_is_instance_slow(), "cast to instanceKlass"); - return (instanceKlass*) kp; + assert(k->oop_is_instance(), "cast to InstanceKlass"); + return (InstanceKlass*) k; + } + + InstanceKlass* java_super() const { + return (super() == NULL) ? NULL : cast(super()); } // Sizing (in words) - static int header_size() { return align_object_offset(oopDesc::header_size() + sizeof(instanceKlass)/HeapWordSize); } + static int header_size() { return align_object_offset(sizeof(InstanceKlass)/HeapWordSize); } + static int size(int vtable_length, int itable_length, + int nonstatic_oop_map_size, + bool is_interface, bool is_anonymous) { + return align_object_size(header_size() + + align_object_offset(vtable_length) + + align_object_offset(itable_length) + + ((is_interface || is_anonymous) ? + align_object_offset(nonstatic_oop_map_size) : + nonstatic_oop_map_size) + + (is_interface ? (int)sizeof(Klass*)/HeapWordSize : 0) + + (is_anonymous ? (int)sizeof(Klass*)/HeapWordSize : 0)); + } + int size() const { return size(vtable_length(), + itable_length(), + nonstatic_oop_map_size(), + is_interface(), + is_anonymous()); + } - int object_size() const - { - return object_size(align_object_offset(vtable_length()) + - align_object_offset(itable_length()) + - ((is_interface() || is_anonymous()) ? - align_object_offset(nonstatic_oop_map_size()) : - nonstatic_oop_map_size()) + - (is_interface() ? (int)sizeof(klassOop)/HeapWordSize : 0) + - (is_anonymous() ? (int)sizeof(klassOop)/HeapWordSize : 0)); - } static int vtable_start_offset() { return header_size(); } - static int vtable_length_offset() { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; } - static int object_size(int extra) { return align_object_size(header_size() + extra); } + static int vtable_length_offset() { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; } - intptr_t* start_of_vtable() const { return ((intptr_t*)as_klassOop()) + vtable_start_offset(); } + intptr_t* start_of_vtable() const { return ((intptr_t*)this) + vtable_start_offset(); } intptr_t* start_of_itable() const { return start_of_vtable() + align_object_offset(vtable_length()); } - int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)as_klassOop(); } + int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; } intptr_t* end_of_itable() const { return start_of_itable() + itable_length(); } @@ -794,22 +803,22 @@ return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length())); } - oop* adr_implementor() const { + Klass** adr_implementor() const { if (is_interface()) { - return (oop*)(start_of_nonstatic_oop_maps() + + return (Klass**)(start_of_nonstatic_oop_maps() + nonstatic_oop_map_count()); } else { return NULL; } }; - oop* adr_host_klass() const { + Klass** adr_host_klass() const { if (is_anonymous()) { - oop* adr_impl = adr_implementor(); + Klass** adr_impl = adr_implementor(); if (adr_impl != NULL) { return adr_impl + 1; } else { - return (oop*)(start_of_nonstatic_oop_maps() + + return (Klass**)(start_of_nonstatic_oop_maps() + nonstatic_oop_map_count()); } } else { @@ -838,18 +847,27 @@ // Java vtable/itable klassVtable* vtable() const; // return new klassVtable wrapper - inline methodOop method_at_vtable(int index); + inline Method* method_at_vtable(int index); klassItable* itable() const; // return new klassItable wrapper - methodOop method_at_itable(klassOop holder, int index, TRAPS); + Method* method_at_itable(Klass* holder, int index, TRAPS); // Garbage collection + virtual void oops_do(OopClosure* cl); + void oop_follow_contents(oop obj); int oop_adjust_pointers(oop obj); - bool object_is_parsable() const { return _init_state != unparsable_by_gc; } - // Value of _init_state must be zero (unparsable_by_gc) when klass field is set. + + void clean_implementors_list(BoolObjectClosure* is_alive); + void clean_method_data(BoolObjectClosure* is_alive); - void follow_weak_klass_links( - BoolObjectClosure* is_alive, OopClosure* keep_alive); + // Explicit metaspace deallocation of fields + // For RedefineClasses, we need to deallocate instanceKlasses + void deallocate_contents(ClassLoaderData* loader_data); + + // The constant pool is on stack if any of the methods are executing or + // referenced by handles. + bool on_stack() const { return _constants->on_stack(); } + void release_C_heap_structures(); // Parallel Scavenge and Parallel Old @@ -859,11 +877,11 @@ const char* signature_name() const; // Iterators - int oop_oop_iterate(oop obj, OopClosure* blk) { + int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) { return oop_oop_iterate_v(obj, blk); } - int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { + int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) { return oop_oop_iterate_v_m(obj, blk, mr); } @@ -883,6 +901,7 @@ ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) #endif // !SERIALGC + u2 idnum_allocated_count() const { return _idnum_allocated_count; } private: // initialization state #ifdef ASSERT @@ -893,7 +912,6 @@ void set_rewritten() { _misc_flags |= _misc_rewritten; } void set_init_thread(Thread *thread) { _init_thread = thread; } - u2 idnum_allocated_count() const { return _idnum_allocated_count; } // The RedefineClasses() API can cause new method idnums to be needed // which will cause the caches to grow. Safety requires different // cache management logic if the caches can grow instead of just @@ -909,29 +927,15 @@ void release_set_methods_cached_itable_indices(int* indices) { OrderAccess::release_store_ptr(&_methods_cached_itable_indices, indices); } - inline typeArrayOop get_method_annotations_from(int idnum, objArrayOop annos); - void set_annotations(objArrayOop md, objArrayOop* md_p) { oop_store_without_check((oop*)md_p, (oop)md); } - void set_methods_annotations_of(int idnum, typeArrayOop anno, objArrayOop* md_p); + // Lock during initialization + volatile oop init_lock() const; + void set_init_lock(oop value) { klass_oop_store(&_init_lock, value); } + void fence_and_clear_init_lock(); // after fully_initialized // Offsets for memory management - oop* adr_array_klasses() const { return (oop*)&this->_array_klasses;} - oop* adr_methods() const { return (oop*)&this->_methods;} - oop* adr_method_ordering() const { return (oop*)&this->_method_ordering;} - oop* adr_local_interfaces() const { return (oop*)&this->_local_interfaces;} - oop* adr_transitive_interfaces() const { return (oop*)&this->_transitive_interfaces;} - oop* adr_fields() const { return (oop*)&this->_fields;} - oop* adr_constants() const { return (oop*)&this->_constants;} - oop* adr_class_loader() const { return (oop*)&this->_class_loader;} oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;} oop* adr_signers() const { return (oop*)&this->_signers;} - oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;} - oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;} - oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;} - oop* adr_class_annotations() const { return (oop*)&this->_class_annotations;} - oop* adr_fields_annotations() const { return (oop*)&this->_fields_annotations;} - oop* adr_methods_annotations() const { return (oop*)&this->_methods_annotations;} - oop* adr_methods_parameter_annotations() const { return (oop*)&this->_methods_parameter_annotations;} - oop* adr_methods_default_annotations() const { return (oop*)&this->_methods_default_annotations;} + oop* adr_init_lock() const { return (oop*)&this->_init_lock;} // Static methods that are used to implement member methods where an exposed this pointer // is needed due to possible GCs @@ -941,21 +945,21 @@ static void eager_initialize_impl (instanceKlassHandle this_oop); static void set_initialization_state_and_notify_impl (instanceKlassHandle this_oop, ClassState state, TRAPS); static void call_class_initializer_impl (instanceKlassHandle this_oop, TRAPS); - static klassOop array_klass_impl (instanceKlassHandle this_oop, bool or_null, int n, TRAPS); + static Klass* array_klass_impl (instanceKlassHandle this_oop, bool or_null, int n, TRAPS); static void do_local_static_fields_impl (instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS); /* jni_id_for_impl for jfieldID only */ static JNIid* jni_id_for_impl (instanceKlassHandle this_oop, int offset); // Returns the array class for the n'th dimension - klassOop array_klass_impl(bool or_null, int n, TRAPS); + Klass* array_klass_impl(bool or_null, int n, TRAPS); // Returns the array class with this class as element type - klassOop array_klass_impl(bool or_null, TRAPS); + Klass* array_klass_impl(bool or_null, TRAPS); public: - // sharing support + // CDS support - remove and restore oops from metadata. Oops are not shared. virtual void remove_unshareable_info(); - virtual void shared_symbols_iterate(SymbolClosure* closure); + virtual void restore_unshareable_info(TRAPS); // jvm support jint compute_modifier_flags(TRAPS) const; @@ -966,19 +970,28 @@ public: // Printing +#ifndef PRODUCT + void print_on(outputStream* st) const; +#endif + void print_value_on(outputStream* st) const; + void oop_print_value_on(oop obj, outputStream* st); - +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); void print_dependent_nmethods(bool verbose = false); bool is_dependent_nmethod(nmethod* nm); +#endif + + const char* internal_name() const; // Verification - const char* internal_name() const; + void verify_on(outputStream* st); + void oop_verify_on(oop obj, outputStream* st); }; -inline methodOop instanceKlass::method_at_vtable(int index) { +inline Method* InstanceKlass::method_at_vtable(int index) { #ifndef PRODUCT assert(index >= 0, "valid vtable index"); if (DebugVtables) { @@ -989,18 +1002,11 @@ return ve[index].method(); } -inline typeArrayOop instanceKlass::get_method_annotations_from(int idnum, objArrayOop annos) { - if (annos == NULL || annos->length() <= idnum) { - return NULL; - } - return typeArrayOop(annos->obj_at(idnum)); -} - // for adding methods // UNSET_IDNUM return means no more ids available -inline u2 instanceKlass::next_method_idnum() { - if (_idnum_allocated_count == constMethodOopDesc::MAX_IDNUM) { - return constMethodOopDesc::UNSET_IDNUM; // no more ids available +inline u2 InstanceKlass::next_method_idnum() { + if (_idnum_allocated_count == ConstMethod::MAX_IDNUM) { + return ConstMethod::UNSET_IDNUM; // no more ids available } else { return _idnum_allocated_count++; } @@ -1011,7 +1017,7 @@ class JNIid: public CHeapObj<mtClass> { friend class VMStructs; private: - klassOop _holder; + Klass* _holder; JNIid* _next; int _offset; #ifdef ASSERT @@ -1020,45 +1026,42 @@ public: // Accessors - klassOop holder() const { return _holder; } + Klass* holder() const { return _holder; } int offset() const { return _offset; } JNIid* next() { return _next; } // Constructor - JNIid(klassOop holder, int offset, JNIid* next); + JNIid(Klass* holder, int offset, JNIid* next); // Identifier lookup JNIid* find(int offset); bool find_local_field(fieldDescriptor* fd) { - return instanceKlass::cast(holder())->find_local_field_from_offset(offset(), true, fd); + return InstanceKlass::cast(holder())->find_local_field_from_offset(offset(), true, fd); } - // Garbage collection support - oop* holder_addr() { return (oop*)&_holder; } - void oops_do(OopClosure* f); static void deallocate(JNIid* id); // Debugging #ifdef ASSERT bool is_static_field_id() const { return _is_static_field_id; } void set_is_static_field_id() { _is_static_field_id = true; } #endif - void verify(klassOop holder); + void verify(Klass* holder); }; // If breakpoints are more numerous than just JVMTI breakpoints, // consider compressing this data structure. -// It is currently a simple linked list defined in methodOop.hpp. +// It is currently a simple linked list defined in method.hpp. class BreakpointInfo; // A collection point for interesting information about the previous -// version(s) of an instanceKlass. This class uses weak references to +// version(s) of an InstanceKlass. This class uses weak references to // the information so that the information may be collected as needed // by the system. If the information is shared, then a regular // reference must be used because a weak reference would be seen as // collectible. A GrowableArray of PreviousVersionNodes is attached -// to the instanceKlass as needed. See PreviousVersionWalker below. +// to the InstanceKlass as needed. See PreviousVersionWalker below. class PreviousVersionNode : public CHeapObj<mtClass> { private: // A shared ConstantPool is never collected so we'll always have @@ -1066,23 +1069,23 @@ // have a weak reference to a non-shared ConstantPool until all // of the methods (EMCP or obsolete) have been collected; the // non-shared ConstantPool becomes collectible at that point. - jobject _prev_constant_pool; // regular or weak reference + ConstantPool* _prev_constant_pool; // regular or weak reference bool _prev_cp_is_weak; // true if not a shared ConstantPool - // If the previous version of the instanceKlass doesn't have any + // If the previous version of the InstanceKlass doesn't have any // EMCP methods, then _prev_EMCP_methods will be NULL. If all the // EMCP methods have been collected, then _prev_EMCP_methods can // have a length of zero. - GrowableArray<jweak>* _prev_EMCP_methods; + GrowableArray<Method*>* _prev_EMCP_methods; public: - PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak, - GrowableArray<jweak>* prev_EMCP_methods); + PreviousVersionNode(ConstantPool* prev_constant_pool, bool prev_cp_is_weak, + GrowableArray<Method*>* prev_EMCP_methods); ~PreviousVersionNode(); - jobject prev_constant_pool() const { + ConstantPool* prev_constant_pool() const { return _prev_constant_pool; } - GrowableArray<jweak>* prev_EMCP_methods() const { + GrowableArray<Method*>* prev_EMCP_methods() const { return _prev_EMCP_methods; } }; @@ -1092,7 +1095,7 @@ class PreviousVersionInfo : public ResourceObj { private: constantPoolHandle _prev_constant_pool_handle; - // If the previous version of the instanceKlass doesn't have any + // If the previous version of the InstanceKlass doesn't have any // EMCP methods, then _prev_EMCP_methods will be NULL. Since the // methods cannot be collected while we hold a handle, // _prev_EMCP_methods should never have a length of zero. @@ -1135,7 +1138,7 @@ PreviousVersionInfo * _current_p; public: - PreviousVersionWalker(instanceKlass *ik); + PreviousVersionWalker(InstanceKlass *ik); ~PreviousVersionWalker(); // Return the interesting information for the next previous version @@ -1176,10 +1179,10 @@ }; // An iterator that's used to access the inner classes indices in the -// instanceKlass::_inner_classes array. +// InstanceKlass::_inner_classes array. class InnerClassesIterator : public StackObj { private: - typeArrayHandle _inner_classes; + Array<jushort>* _inner_classes; int _length; int _idx; public: @@ -1193,12 +1196,12 @@ // attribute data, or it should be // n*inner_class_next_offset+enclosing_method_attribute_size // if it also contains the EnclosingMethod data. - assert((_length % instanceKlass::inner_class_next_offset == 0 || - _length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size), + assert((_length % InstanceKlass::inner_class_next_offset == 0 || + _length % InstanceKlass::inner_class_next_offset == InstanceKlass::enclosing_method_attribute_size), "just checking"); // Remove the enclosing_method portion if exists. - if (_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size) { - _length -= instanceKlass::enclosing_method_attribute_size; + if (_length % InstanceKlass::inner_class_next_offset == InstanceKlass::enclosing_method_attribute_size) { + _length -= InstanceKlass::enclosing_method_attribute_size; } } else { _length = 0; @@ -1211,7 +1214,7 @@ } void next() { - _idx += instanceKlass::inner_class_next_offset; + _idx += InstanceKlass::inner_class_next_offset; } bool done() const { @@ -1219,38 +1222,38 @@ } u2 inner_class_info_index() const { - return _inner_classes->ushort_at( - _idx + instanceKlass::inner_class_inner_class_info_offset); + return _inner_classes->at( + _idx + InstanceKlass::inner_class_inner_class_info_offset); } void set_inner_class_info_index(u2 index) { - _inner_classes->ushort_at_put( - _idx + instanceKlass::inner_class_inner_class_info_offset, index); + _inner_classes->at_put( + _idx + InstanceKlass::inner_class_inner_class_info_offset, index); } u2 outer_class_info_index() const { - return _inner_classes->ushort_at( - _idx + instanceKlass::inner_class_outer_class_info_offset); + return _inner_classes->at( + _idx + InstanceKlass::inner_class_outer_class_info_offset); } void set_outer_class_info_index(u2 index) { - _inner_classes->ushort_at_put( - _idx + instanceKlass::inner_class_outer_class_info_offset, index); + _inner_classes->at_put( + _idx + InstanceKlass::inner_class_outer_class_info_offset, index); } u2 inner_name_index() const { - return _inner_classes->ushort_at( - _idx + instanceKlass::inner_class_inner_name_offset); + return _inner_classes->at( + _idx + InstanceKlass::inner_class_inner_name_offset); } void set_inner_name_index(u2 index) { - _inner_classes->ushort_at_put( - _idx + instanceKlass::inner_class_inner_name_offset, index); + _inner_classes->at_put( + _idx + InstanceKlass::inner_class_inner_name_offset, index); } u2 inner_access_flags() const { - return _inner_classes->ushort_at( - _idx + instanceKlass::inner_class_access_flags_offset); + return _inner_classes->at( + _idx + InstanceKlass::inner_class_access_flags_offset); } };