hotspot source code - klass and oop

OOP-Klass 二分模型

  1. OOP是指ordinary object pointer,普通对象指针,用来描述 JVM 中的实例对象的实例信息。
  2. Klass是 Java 类在 C++ 中的对等体,用来描述 Java 类,在其中包括了类的相关信息。

这个模型也体现了编程设计的最根本的一个设计原则:分离变化的与不变化的部分。其中 Java 实例信息相对 Java 类而言,是包含了变化的部分数据,Java 类描述了类的行为和类信息,为所有实例所共享。这个二分模型中的 Klass 向 JVM 提供了二个功能:

  1. 实现语言层面的 Java 类
  2. 实现 Java 对象的方法分发(dispatch)功能

oop 基类

vm/oops/oop.hpp35行,**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.hpp44行,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.hpp43行,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;};#ifndef PRODUCT// 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);};#endif  // !PRODUCT// 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;

References

  1. vm/oops/oop.hpp
  2. vm/oops/klass.hpp
  3. vm/oops/instanceKlass.hpp