OOP-Klass 二分模型
OOP是指ordinary object pointer,普通对象指针,用来描述 JVM 中的实例对象的实例信息。Klass是 Java 类在 C++ 中的对等体,用来描述 Java 类,在其中包括了类的相关信息。
这个模型也体现了编程设计的最根本的一个设计原则:分离变化的与不变化的部分。其中 Java 实例信息相对 Java 类而言,是包含了变化的部分数据,Java 类描述了类的行为和类信息,为所有实例所共享。这个二分模型中的 Klass 向 JVM 提供了二个功能:
- 实现语言层面的 Java 类
- 实现 Java 对象的方法分发(dispatch)功能
oop 基类
vm/oops/oop.hpp 第35行,**OopDesc类型都继承自class oopDesc,源码如下:
30313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | // oopDesc is the top baseclass for objects classes. The {name}Desc classes describe// the format of Java objects so the fields can be accessed from C++.// oopDesc is abstract.// (see oopHierarchy for complete oop class hierarchy)//// no virtual functions allowed// store into oop with store checktemplate <class T> void oop_store(T* p, oop v);template <class T> void oop_store(volatile T* p, oop v);extern bool always_do_update_barrier;// Forward declarations.class OopClosure;class ScanClosure;class FastScanClosure;class FilteringClosure;class BarrierSet;class CMSIsAliveClosure;class PSPromotionManager;class ParCompactionManager;class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { Klass* _klass; narrowKlass _compressed_klass; } _metadata; // Fast access to barrier set. Must be initialized. static BarrierSet* _bs; public: markOop mark() const { return _mark; } markOop* mark_addr() const { return (markOop*) &_mark; } void set_mark(volatile markOop m) { _mark = m; } void release_set_mark(markOop m); markOop cas_set_mark(markOop new_mark, markOop old_mark); // Used only to re-initialize the mark word (e.g., of promoted // objects during a GC) -- requires a valid klass pointer void init_mark(); Klass* klass() const; Klass* klass_or_null() const volatile; Klass** klass_addr(); narrowKlass* compressed_klass_addr(); void set_klass(Klass* k); // For klass field compression int klass_gap() const; void set_klass_gap(int z); // For when the klass pointer is being used as a linked list "next" field. void set_klass_to_list_ptr(oop k); oop list_ptr_from_klass(); // size of object header, aligned to platform wordSize static int header_size() { return sizeof(oopDesc)/HeapWordSize; } // Returns whether this is an instance of k or an instance of a subclass of k bool is_a(Klass* k) const; // Returns the actual oop size of the object int size(); // Sometimes (for complicated concurrency-related reasons), it is useful // to be able to figure out the size of an object knowing its klass. int size_given_klass(Klass* klass); // type test operations (inlined in oop.inline.h) bool is_instance() const; bool is_instanceMirror() const; bool is_instanceClassLoader() const; bool is_instanceRef() const; bool is_array() const; bool is_objArray() const; bool is_typeArray() const; |
Klass 数据结构
vm/oops/klass.hpp 第44行,Klass类型数据结构说明,源码如下:
4445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | /// A Klass provides:// 1: language level class object (method dictionary etc.)// 2: provide vm dispatch behavior for the object// Both functions are combined into one C++ class.// One reason for the oop/klass dichotomy in the implementation is// that we don't want a C++ vtbl pointer in every object. Thus,// normal oops don't have any virtual functions. Instead, they// forward all "virtual" functions to their klass, which does have// a vtbl and does the C++ dispatch depending on the object's// actual type. (See oop.inline.hpp for some of the forwarding code.)// ALL FUNCTIONS IMPLEMENTING THIS DISPATCH ARE PREFIXED WITH "oop_"!// Klass layout:// [C++ vtbl ptr ] (contained in Metadata)// [layout_helper ]// [super_check_offset ] for fast subtype checks// [name ]// [secondary_super_cache] for fast subtype checks// [secondary_supers ] array of 2ndary supertypes// [primary_supers 0]// [primary_supers 1]// [primary_supers 2]// ...// [primary_supers 7]// [java_mirror ]// [super ]// [subklass ] first subclass// [next_sibling ] link to chain additional subklasses// [next_link ]// [class_loader_data]// [modifier_flags]// [access_flags ]// [last_biased_lock_bulk_revocation_time] (64 bits)// [prototype_header]// [biased_lock_revocation_count]// [_modified_oops]// [_accumulated_modified_oops]// [trace_id]// Forward declarations.template <class T> class Array;template <class T> class GrowableArray;class ClassLoaderData;class klassVtable;class ParCompactionManager;class KlassSizeStats;class fieldDescriptor;class Klass : public Metadata { friend class VMStructs; protected: // note: put frequently-used fields together at start of klass structure // for better cache behavior (may not make much of a difference but sure won't hurt) enum { _primary_super_limit = 8 }; // The "layout helper" is a combined descriptor of object layout. // For klasses which are neither instance nor array, the value is zero. // // For instances, layout helper is a positive number, the instance size. // This size is already passed through align_object_size and scaled to bytes. // The low order bit is set if instances of this class cannot be // allocated using the fastpath. // // For arrays, layout helper is a negative number, containing four // distinct bytes, as follows: // MSB:[tag, hsz, ebt, log2(esz)]:LSB // where: // tag is 0x80 if the elements are oops, 0xC0 if non-oops // hsz is array header size in bytes (i.e., offset of first element) // ebt is the BasicType of the elements // esz is the element size in bytes // This packed word is arranged so as to be quickly unpacked by the // various fast paths that use the various subfields. // // The esz bits can be used directly by a SLL instruction, without masking. // // Note that the array-kind tag looks like 0x00 for instance klasses, // since their length in bytes is always less than 24Mb. // // Final note: This comes first, immediately after C++ vtable, // because it is frequently queried. jint _layout_helper; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers // and _primary_supers all help make fast subtype checks. See big discussion // in doc/server_compiler/checktype.txt // // Where to look to observe a supertype (it is &_secondary_super_cache for // secondary supers, else is &_primary_supers[depth()]. juint _super_check_offset; // Class name. Instance classes: java/lang/String, etc. Array classes: [I, // [Ljava/lang/String;, etc. Set to zero for all other kinds of classes. Symbol* _name; // Cache of last observed secondary supertype Klass* _secondary_super_cache; // Array of all secondary supertypes Array<Klass*>* _secondary_supers; // Ordered list of all primary supertypes Klass* _primary_supers[_primary_super_limit]; // java/lang/Class instance mirroring this class oop _java_mirror; // Superclass Klass* _super; // First subclass (NULL if none); _subklass->next_sibling() is next one Klass* _subklass; // Sibling link (or NULL); links all subklasses of a klass Klass* _next_sibling; // All klasses loaded by a class loader are chained through these links Klass* _next_link; // The VM's representation of the ClassLoader used to load this class. // Provide access the corresponding instance java.lang.ClassLoader. ClassLoaderData* _class_loader_data; jint _modifier_flags; // Processed access flags, for use by Class.getModifiers. AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. // Biased locking implementation and statistics // (the 64-bit chunk goes first, to avoid some fragmentation) jlong _last_biased_lock_bulk_revocation_time; markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type jint _biased_lock_revocation_count; TRACE_DEFINE_KLASS_TRACE_ID; // Remembered sets support for the oops in the klasses. jbyte _modified_oops; // Card Table Equivalent (YC/CMS support) jbyte _accumulated_modified_oops; // Mod Union Equivalent (CMS support) |
instanceKlass
vm/oops/instanceKlass.hpp 第43行,instanceKlass是 JVM 中 Java 类的对等体,instanceKlass类型数据结构说明,源码如下:
434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | // An InstanceKlass is the VM level representation of a Java class.// It contains all information needed for at class at execution runtime.// InstanceKlass layout:// [C++ vtbl pointer ] Klass// [subtype cache ] Klass// [instance size ] Klass// [java mirror ] Klass// [super ] Klass// [access_flags ] Klass// [name ] Klass// [first subklass ] Klass// [next sibling ] Klass// [array klasses ]// [methods ]// [local interfaces ]// [transitive interfaces ]// [fields ]// [constants ]// [class loader ]// [source file name ]// [inner classes ]// [static field size ]// [nonstatic field size ]// [static oop fields size ]// [nonstatic oop maps size ]// [has finalize method ]// [deoptimization mark bit ]// [initialization state ]// [initializing thread ]// [Java vtable length ]// [oop map cache (stack maps) ]// [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 host klass ] only exist for an anonymous class (JSR 292 enabled)// forward declaration for class -- see below for definitionclass SuperTypeClosure;class JNIid;class jniIdMapBase;class BreakpointInfo;class fieldDescriptor;class DepChange;class nmethodBucket;class JvmtiCachedClassFieldMap;class MemberNameTable;// This is used in iterators below.class FieldClosure: public StackObj {public: virtual void do_field(fieldDescriptor* fd) = 0;};// Print fields.// If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields.class FieldPrinter: public FieldClosure { oop _obj; outputStream* _st; public: FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {} void do_field(fieldDescriptor* fd);};// ValueObjs embedded in klass. Describes where oops are located in instances of// this klass.class OopMapBlock VALUE_OBJ_CLASS_SPEC { public: // Byte offset of the first oop mapped by this block. int offset() const { return _offset; } void set_offset(int offset) { _offset = offset; } // Number of oops in this block. uint count() const { return _count; } void set_count(uint count) { _count = count; } // sizeof(OopMapBlock) in HeapWords. static const int size_in_words() { return align_size_up(int(sizeof(OopMapBlock)), HeapWordSize) >> LogHeapWordSize; } private: int _offset; uint _count;};struct JvmtiCachedClassFileData;class InstanceKlass: public Klass { friend class VMStructs; friend class ClassFileParser; friend class CompileReplay; |