ssssssss46


  bool equal(CellTypeState a) const     { return _state == a._state; }
  bool equal_kind(CellTypeState a) const {
    return (_state & bits_mask) == (a._state & bits_mask);
  }
  char to_char() const;
  CellTypeState merge (CellTypeState cts, int slot) const;
  void print(outputStream *os);
  static CellTypeState bottom;
  static CellTypeState uninit;
  static CellTypeState ref;
  static CellTypeState value;
  static CellTypeState refUninit;
  static CellTypeState varUninit;
  static CellTypeState top;
  static CellTypeState addr;
};
class BasicBlock: ResourceObj {
 private:
  bool            _changed;                 // Reached a fixpoint or not
 public:
  enum Constants {
    _dead_basic_block = -2,
    _unreached        = -1                  // Alive but not yet reached by analysis
  };
  int             _bci;                     // Start of basic block
  int             _end_bci;                 // Bci of last instruction in basicblock
  int             _max_locals;              // Determines split between vars and stack
  int             _max_stack;               // Determines split between stack and monitors
  CellTypeState*  _state;                   // State (vars, stack) at entry.
  int             _stack_top;               // -1 indicates bottom stack value.
  int             _monitor_top;             // -1 indicates bottom monitor stack value.
  CellTypeState* vars()                     { return _state; }
  CellTypeState* stack()                    { return _state + _max_locals; }
  bool changed()                            { return _changed; }
  void set_changed(bool s)                  { _changed = s; }
  bool is_reachable() const                 { return _stack_top >= 0; }  // Analysis has reached this basicblock
  bool is_dead() const                      { return _stack_top == _dead_basic_block; }
  bool is_alive() const                     { return _stack_top != _dead_basic_block; }
  void mark_as_alive()                      { assert(is_dead(), "must be dead"); _stack_top = _unreached; }
};
class GenerateOopMap VALUE_OBJ_CLASS_SPEC {
 protected:
  enum { bad_monitors = -1 };
  methodHandle _method;                     // The method we are examine
  RetTable     _rt;                         // Contains the return address mappings
  int          _max_locals;                 // Cached value of no. of locals
  int          _max_stack;                  // Cached value of max. stack depth
  int          _max_monitors;               // Cached value of max. monitor stack depth
  int          _has_exceptions;             // True, if exceptions exist for method
  bool         _got_error;                  // True, if an error occurred during interpretation.
  Handle       _exception;                  // Exception if got_error is true.
  bool         _did_rewriting;              // was bytecodes rewritten
  bool         _did_relocation;             // was relocation neccessary
  bool         _monitor_safe;               // The monitors in this method have been determined
  int            _state_len;                // Size of states
  CellTypeState *_state;                    // list of states
  char          *_state_vec_buf;            // Buffer used to print a readable version of a state
  int            _stack_top;
  int            _monitor_top;
  static elapsedTimer _total_oopmap_time;   // Holds cumulative oopmap generation time
  static long         _total_byte_count;    // Holds cumulative number of bytes inspected
  void            init_state();
  void            make_context_uninitialized ();
  int             methodsig_to_effect        (Symbol* signature, bool isStatic, CellTypeState* effect);
  bool            merge_local_state_vectors  (CellTypeState* cts, CellTypeState* bbts);
  bool            merge_monitor_state_vectors(CellTypeState* cts, CellTypeState* bbts);
  void            copy_state                 (CellTypeState *dst, CellTypeState *src);
  void            merge_state_into_bb        (BasicBlock *bb);
  static void     merge_state                (GenerateOopMap *gom, int bcidelta, int* data);
  void            set_var                    (int localNo, CellTypeState cts);
  CellTypeState   get_var                    (int localNo);
  CellTypeState   pop                        ();
  void            push                       (CellTypeState cts);
  CellTypeState   monitor_pop                ();
  void            monitor_push               (CellTypeState cts);
  CellTypeState * vars                       ()                                             { return _state; }
  CellTypeState * stack                      ()                                             { return _state+_max_locals; }
  CellTypeState * monitors                   ()                                             { return _state+_max_locals+_max_stack; }
  void            replace_all_CTS_matches    (CellTypeState match,
                                              CellTypeState replace);
  void            print_states               (outputStream *os, CellTypeState *vector, int num);
  void            print_current_state        (outputStream   *os,
                                              BytecodeStream *itr,
                                              bool            detailed);
  void            report_monitor_mismatch    (const char *msg);
  BasicBlock *    _basic_blocks;             // Array of basicblock info
  int             _gc_points;
  int             _bb_count;
  BitMap          _bb_hdr_bits;
  void          initialize_bb               ();
  void          mark_bbheaders_and_count_gc_points();
  bool          is_bb_header                (int bci) const   {
    return _bb_hdr_bits.at(bci);
  }
  int           gc_points                   () const                          { return _gc_points; }
  int           bb_count                    () const                          { return _bb_count; }
  void          set_bbmark_bit              (int bci) {
    _bb_hdr_bits.at_put(bci, true);
  }
  void          clear_bbmark_bit            (int bci) {
    _bb_hdr_bits.at_put(bci, false);
  }
  BasicBlock *  get_basic_block_at          (int bci) const;
  BasicBlock *  get_basic_block_containing  (int bci) const;
  void          interp_bb                   (BasicBlock *bb);
  void          restore_state               (BasicBlock *bb);
  int           next_bb_start_pc            (BasicBlock *bb);
  void          update_basic_blocks         (int bci, int delta, int new_method_size);
  static void   bb_mark_fct                 (GenerateOopMap *c, int deltaBci, int *data);
  void          mark_reachable_code();
  static void   reachable_basicblock        (GenerateOopMap *c, int deltaBci, int *data);
  void  do_interpretation                   ();
  void  init_basic_blocks                   ();
  void  setup_method_entry_state            ();
  void  interp_all                          ();
  void  interp1                             (BytecodeStream *itr);
  void  do_exception_edge                   (BytecodeStream *itr);
  void  check_type                          (CellTypeState expected, CellTypeState actual);
  void  ppstore                             (CellTypeState *in,  int loc_no);
  void  ppload                              (CellTypeState *out, int loc_no);
  void  ppush1                              (CellTypeState in);
  void  ppush                               (CellTypeState *in);
  void  ppop1                               (CellTypeState out);
  void  ppop                                (CellTypeState *out);
  void  ppop_any                            (int poplen);
  void  pp                                  (CellTypeState *in, CellTypeState *out);
  void  pp_new_ref                          (CellTypeState *in, int bci);
  void  ppdupswap                           (int poplen, const char *out);
  void  do_ldc                              (int bci);
  void  do_astore                           (int idx);
  void  do_jsr                              (int delta);
  void  do_field                            (int is_get, int is_static, int idx, int bci);
  void  do_method                           (int is_static, int is_interface, int idx, int bci);
  void  do_multianewarray                   (int dims, int bci);
  void  do_monitorenter                     (int bci);
  void  do_monitorexit                      (int bci);
  void  do_return_monitor_check             ();
  void  do_checkcast                        ();
  CellTypeState *sigchar_to_effect          (char sigch, int bci, CellTypeState *out);
  int copy_cts                              (CellTypeState *dst, CellTypeState *src);
  void  error_work                          (const char *format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
  void  report_error                        (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
  void  verify_error                        (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
  bool  got_error()                         { return _got_error; }
  bool  _report_result;
  bool  _report_result_for_send;            // Unfortunatly, stackmaps for sends are special, so we need some extra
  BytecodeStream *_itr_send;                // variables to handle them properly.
  void  report_result                       ();
  GrowableArray<intptr_t> * _init_vars;
  void  initialize_vars                     ();
  void  add_to_ref_init_set                 (int localNo);
  bool      _conflict;                      // True, if a conflict occurred during interpretation
  int       _nof_refval_conflicts;          // No. of conflicts that require rewrites
  int *     _new_var_map;
  void record_refval_conflict               (int varNo);
  void rewrite_refval_conflicts             ();
  void rewrite_refval_conflict              (int from, int to);
  bool rewrite_refval_conflict_inst         (BytecodeStream *i, int from, int to);
  bool rewrite_load_or_store                (BytecodeStream *i, Bytecodes::Code bc, Bytecodes::Code bc0, unsigned int varNo);
  void expand_current_instr                 (int bci, int ilen, int newIlen, u_char inst_buffer[]);
  bool is_astore                            (BytecodeStream *itr, int *index);
  bool is_aload                             (BytecodeStream *itr, int *index);
  GrowableArray<intptr_t> *_ret_adr_tos;
  bool stack_top_holds_ret_addr             (int bci);
  void compute_ret_adr_at_TOS               ();
  void update_ret_adr_at_TOS                (int bci, int delta);
  int  binsToHold                           (int no)                      { return  ((no+(BitsPerWord-1))/BitsPerWord); }
  char *state_vec_to_string                 (CellTypeState* vec, int len);
  void  ret_jump_targets_do                 (BytecodeStream *bcs, jmpFct_t jmpFct, int varNo,int *data);
  bool  jump_targets_do                     (BytecodeStream *bcs, jmpFct_t jmpFct, int *data);
  friend class RelocCallback;
 public:
  GenerateOopMap(methodHandle method);
  void compute_map(TRAPS);
  void result_for_basicblock(int bci);    // Do a callback on fill_stackmap_for_opcodes for basicblock containing bci
  int max_locals() const                           { return _max_locals; }
  Method* method() const                           { return _method(); }
  methodHandle method_as_handle() const            { return _method; }
  bool did_rewriting()                             { return _did_rewriting; }
  bool did_relocation()                            { return _did_relocation; }
  static void print_time();
  bool monitor_safe()                              { return _monitor_safe; }
  virtual bool allow_rewrites             () const                        { return false; }
  virtual bool report_results             () const                        { return true;  }
  virtual bool report_init_vars           () const                        { return true;  }
  virtual bool possible_gc_point          (BytecodeStream *bcs)           { ShouldNotReachHere(); return false; }
  virtual void fill_stackmap_prolog       (int nof_gc_points)             { ShouldNotReachHere(); }
  virtual void fill_stackmap_epilog       ()                              { ShouldNotReachHere(); }
  virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
                                           CellTypeState* vars,
                                           CellTypeState* stack,
                                           int stackTop)                  { ShouldNotReachHere(); }
  virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) { ShouldNotReachHere();; }
};
class ResolveOopMapConflicts: public GenerateOopMap {
 private:
  bool _must_clear_locals;
  virtual bool report_results() const     { return false; }
  virtual bool report_init_vars() const   { return true;  }
  virtual bool allow_rewrites() const     { return true;  }
  virtual bool possible_gc_point          (BytecodeStream *bcs)           { return false; }
  virtual void fill_stackmap_prolog       (int nof_gc_points)             {}
  virtual void fill_stackmap_epilog       ()                              {}
  virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
                                           CellTypeState* vars,
                                           CellTypeState* stack,
                                           int stack_top)                 {}
  virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) { _must_clear_locals = init_vars->length() > 0; }
#ifndef PRODUCT
  static int _nof_invocations;
  static int _nof_rewrites;
  static int _nof_relocations;
#endif
 public:
  ResolveOopMapConflicts(methodHandle method) : GenerateOopMap(method) { _must_clear_locals = false; };
  methodHandle do_potential_rewrite(TRAPS);
  bool must_clear_locals() const { return _must_clear_locals; }
};
class GeneratePairingInfo: public GenerateOopMap {
 private:
  virtual bool report_results() const     { return false; }
  virtual bool report_init_vars() const   { return false; }
  virtual bool allow_rewrites() const     { return false;  }
  virtual bool possible_gc_point          (BytecodeStream *bcs)           { return false; }
  virtual void fill_stackmap_prolog       (int nof_gc_points)             {}
  virtual void fill_stackmap_epilog       ()                              {}
  virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
                                           CellTypeState* vars,
                                           CellTypeState* stack,
                                           int stack_top)                 {}
  virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) {}
 public:
  GeneratePairingInfo(methodHandle method) : GenerateOopMap(method)       {};
};
#endif // SHARE_VM_OOPS_GENERATEOOPMAP_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/instanceClassLoaderKlass.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/oopFactory.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceClassLoaderKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/instanceOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#endif // INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)\
                                                                                \
int InstanceClassLoaderKlass::                                                  \
oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
  int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
                                                                                \
  if_do_metadata_checked(closure, nv_suffix) {                                  \
    ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);             \
    if (cld != NULL) {                                                          \
      closure->do_class_loader_data(cld);                                       \
    }                                                                           \
  }                                                                             \
                                                                                \
  return size;                                                                  \
}
#if INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                \
int InstanceClassLoaderKlass::                                                  \
oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
  int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
  return size;                                                                  \
}
#endif // INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
                                                                                \
int InstanceClassLoaderKlass::                                                  \
oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
                               OopClosureType* closure,                         \
                               MemRegion mr) {                                  \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
  int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
                                                                                \
  if_do_metadata_checked(closure, nv_suffix) {                                  \
    if (mr.contains(obj)) {                                                     \
      ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);           \
      if (cld != NULL) {                                                        \
        closure->do_class_loader_data(cld);                                     \
      }                                                                         \
    }                                                                           \
  }                                                                             \
                                                                                \
  return size;                                                                  \
}
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
void InstanceClassLoaderKlass::oop_follow_contents(oop obj) {
  InstanceKlass::oop_follow_contents(obj);
  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
  if(loader_data != NULL) {
    MarkSweep::follow_class_loader(loader_data);
  }
}
#if INCLUDE_ALL_GCS
void InstanceClassLoaderKlass::oop_follow_contents(ParCompactionManager* cm,
        oop obj) {
  InstanceKlass::oop_follow_contents(cm, obj);
  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
  if (loader_data != NULL) {
    PSParallelCompact::follow_class_loader(cm, loader_data);
  }
}
void InstanceClassLoaderKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
  InstanceKlass::oop_push_contents(pm, obj);
}
int InstanceClassLoaderKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  InstanceKlass::oop_update_pointers(cm, obj);
  return size_helper();
}
#endif // INCLUDE_ALL_GCS
C:\hotspot-69087d08d473\src\share\vm/oops/instanceClassLoaderKlass.hpp
#ifndef SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
#define SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
#include "oops/instanceKlass.hpp"
#include "utilities/macros.hpp"
class InstanceClassLoaderKlass: public InstanceKlass {
  friend class VMStructs;
  friend class InstanceKlass;
  InstanceClassLoaderKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags, bool is_anonymous)
    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
public:
  virtual bool oop_is_instanceClassLoader() const { return true; }
  InstanceClassLoaderKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate_v(obj, blk);
  }
  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
    return oop_oop_iterate_v_m(obj, blk, mr);
  }
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                         \
  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
#if INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
#endif // INCLUDE_ALL_GCS
  void oop_follow_contents(oop obj);
  PARALLEL_GC_DECLS
};
#endif // SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/instanceKlass.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/oopMapCache.hpp"
#include "interpreter/rewriter.hpp"
#include "jvmtifiles/jvmti.h"
#include "memory/genOopClosures.inline.hpp"
#include "memory/heapInspection.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/instanceClassLoaderKlass.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/instanceOop.hpp"
#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfrEvents.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#ifdef DTRACE_ENABLED
#ifndef USDT2
HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
  char*, intptr_t, oop, intptr_t);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error,
  char*, intptr_t, oop, intptr_t, int);
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
  char*, intptr_t, oop, intptr_t, int);
#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)          \
  {                                                              \
    char* data = NULL;                                           \
    int len = 0;                                                 \
    Symbol* name = (clss)->name();                               \
    if (name != NULL) {                                          \
      data = (char*)name->bytes();                               \
      len = name->utf8_length();                                 \
    }                                                            \
    HS_DTRACE_PROBE4(hotspot, class__initialization__##type,     \
      data, len, (void *)(clss)->class_loader(), thread_type);           \
  }
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
  {                                                              \
    char* data = NULL;                                           \
    int len = 0;                                                 \
    Symbol* name = (clss)->name();                               \
    if (name != NULL) {                                          \
      data = (char*)name->bytes();                               \
      len = name->utf8_length();                                 \
    }                                                            \
    HS_DTRACE_PROBE5(hotspot, class__initialization__##type,     \
      data, len, (void *)(clss)->class_loader(), thread_type, wait);     \
  }
#else /* USDT2 */
#define HOTSPOT_CLASS_INITIALIZATION_required HOTSPOT_CLASS_INITIALIZATION_REQUIRED
#define HOTSPOT_CLASS_INITIALIZATION_recursive HOTSPOT_CLASS_INITIALIZATION_RECURSIVE
#define HOTSPOT_CLASS_INITIALIZATION_concurrent HOTSPOT_CLASS_INITIALIZATION_CONCURRENT
#define HOTSPOT_CLASS_INITIALIZATION_erroneous HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS
#define HOTSPOT_CLASS_INITIALIZATION_super__failed HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED
#define HOTSPOT_CLASS_INITIALIZATION_clinit HOTSPOT_CLASS_INITIALIZATION_CLINIT
#define HOTSPOT_CLASS_INITIALIZATION_error HOTSPOT_CLASS_INITIALIZATION_ERROR
#define HOTSPOT_CLASS_INITIALIZATION_end HOTSPOT_CLASS_INITIALIZATION_END
#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)          \
  {                                                              \
    char* data = NULL;                                           \
    int len = 0;                                                 \
    Symbol* name = (clss)->name();                               \
    if (name != NULL) {                                          \
      data = (char*)name->bytes();                               \
      len = name->utf8_length();                                 \
    }                                                            \
    HOTSPOT_CLASS_INITIALIZATION_##type(                         \
      data, len, (void *)(clss)->class_loader(), thread_type); \
  }
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
  {                                                              \
    char* data = NULL;                                           \
    int len = 0;                                                 \
    Symbol* name = (clss)->name();                               \
    if (name != NULL) {                                          \
      data = (char*)name->bytes();                               \
      len = name->utf8_length();                                 \
    }                                                            \
    HOTSPOT_CLASS_INITIALIZATION_##type(                         \
      data, len, (void *)(clss)->class_loader(), thread_type, wait); \
  }
#endif /* USDT2 */
#else //  ndef DTRACE_ENABLED
#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait)
#endif //  ndef DTRACE_ENABLED
volatile int InstanceKlass::_total_instanceKlass_count = 0;
InstanceKlass* InstanceKlass::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,
                                              bool is_anonymous,
                                              TRAPS) {
  int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
                                 access_flags.is_interface(), is_anonymous);
  InstanceKlass* ik;
  if (rt == REF_NONE) {
    if (name == vmSymbols::java_lang_Class()) {
      ik = new (loader_data, size, THREAD) InstanceMirrorKlass(
        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
        access_flags, is_anonymous);
    } else if (name == vmSymbols::java_lang_ClassLoader() ||
          (SystemDictionary::ClassLoader_klass_loaded() &&
          super_klass != NULL &&
          super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass()))) {
      ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(
        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
        access_flags, is_anonymous);
    } else {
      ik = new (loader_data, size, THREAD) InstanceKlass(
        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
        access_flags, is_anonymous);
    }
  } else {
    ik = new (loader_data, size, THREAD) InstanceRefKlass(
        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
        access_flags, is_anonymous);
  }
  if (HAS_PENDING_EXCEPTION) {
    return NULL;
  }
  loader_data->add_class(ik);
  Atomic::inc(&_total_instanceKlass_count);
  return ik;
}
void InstanceKlass::copy_method_ordering(intArray* m, TRAPS) {
  if (m != NULL) {
    _method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK);
    for (int i = 0; i < m->length(); i++) {
      _method_ordering->at_put(i, m->at(i));
    }
  } else {
    _method_ordering = Universe::the_empty_int_array();
  }
}
Array<int>* InstanceKlass::create_new_default_vtable_indices(int len, TRAPS) {
  Array<int>* vtable_indices = MetadataFactory::new_array<int>(class_loader_data(), len, CHECK_NULL);
  assert(default_vtable_indices() == NULL, "only create once");
  set_default_vtable_indices(vtable_indices);
  return vtable_indices;
}
InstanceKlass::InstanceKlass(int vtable_len,
                             int itable_len,
                             int static_field_size,
                             int nonstatic_oop_map_size,
                             ReferenceType rt,
                             AccessFlags access_flags,
                             bool is_anonymous) {
  No_Safepoint_Verifier no_safepoint; // until k becomes parsable
  int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
                                   access_flags.is_interface(), is_anonymous);
  set_vtable_length(vtable_len);
  set_itable_length(itable_len);
  set_static_field_size(static_field_size);
  set_nonstatic_oop_map_size(nonstatic_oop_map_size);
  set_access_flags(access_flags);
  _misc_flags = 0;  // initialize to zero
  set_is_anonymous(is_anonymous);
  assert(size() == iksize, "wrong size for object");
  set_array_klasses(NULL);
  set_methods(NULL);
  set_method_ordering(NULL);
  set_default_methods(NULL);
  set_default_vtable_indices(NULL);
  set_local_interfaces(NULL);
  set_transitive_interfaces(NULL);
  init_implementor();
  set_fields(NULL, 0);
  set_constants(NULL);
  set_class_loader_data(NULL);
  set_source_file_name_index(0);
  set_source_debug_extension(NULL, 0);
  set_array_name(NULL);
  set_inner_classes(NULL);
  set_static_oop_field_count(0);
  set_nonstatic_field_size(0);
  set_is_marked_dependent(false);
  set_has_unloaded_dependent(false);
  set_init_state(InstanceKlass::allocated);
  set_init_thread(NULL);
  set_init_state(allocated);
  set_reference_type(rt);
  set_oop_map_cache(NULL);
  set_jni_ids(NULL);
  set_osr_nmethods_head(NULL);
  set_breakpoints(NULL);
  init_previous_versions();
  set_generic_signature_index(0);
  release_set_methods_jmethod_ids(NULL);
  set_annotations(NULL);
  set_jvmti_cached_class_field_map(NULL);
  set_initial_method_idnum(0);
  _dependencies = NULL;
  set_jvmti_cached_class_field_map(NULL);
  set_cached_class_file(NULL);
  set_initial_method_idnum(0);
  set_minor_version(0);
  set_major_version(0);
  NOT_PRODUCT(_verify_count = 0;)
  intptr_t* p = (intptr_t*)this;
  for (int index = InstanceKlass::header_size(); index < iksize; index++) {
    p[index] = NULL_WORD;
  }
  set_layout_helper(Klass::instance_layout_helper(0, true));
}
void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
                                       Array<Method*>* methods) {
  if (methods != NULL && methods != Universe::the_empty_method_array() &&
      !methods->is_shared()) {
    for (int i = 0; i < methods->length(); i++) {
      Method* method = methods->at(i);
      if (method == NULL) continue;  // maybe null if error processing
      assert (!method->on_stack(), "shouldn't be called with methods on stack");
      MetadataFactory::free_metadata(loader_data, method);
    }
    MetadataFactory::free_array<Method*>(loader_data, methods);
  }
}
void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data,
                                          Klass* super_klass,
                                          Array<Klass*>* local_interfaces,
                                          Array<Klass*>* transitive_interfaces) {
  Array<Klass*>* ti = transitive_interfaces;
  if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) {
    Array<Klass*>* sti = (super_klass == NULL) ? NULL :
                    InstanceKlass::cast(super_klass)->transitive_interfaces();
    if (ti != sti && ti != NULL && !ti->is_shared()) {
      MetadataFactory::free_array<Klass*>(loader_data, ti);
    }
  }
  if (local_interfaces != Universe::the_empty_klass_array() &&
      local_interfaces != NULL && !local_interfaces->is_shared()) {
    MetadataFactory::free_array<Klass*>(loader_data, local_interfaces);
  }
}
void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
  if (java_mirror() != NULL) {
    java_lang_Class::set_klass(java_mirror(), NULL);
  }
  loader_data->remove_class(this);
  assert(array_klasses() == NULL, "array classes shouldn't be created for this class yet");
  release_C_heap_structures();
  deallocate_methods(loader_data, methods());
  set_methods(NULL);
  if (method_ordering() != NULL &&
      method_ordering() != Universe::the_empty_int_array() &&
      !method_ordering()->is_shared()) {
    MetadataFactory::free_array<int>(loader_data, method_ordering());
  }
  set_method_ordering(NULL);
  if (default_methods() != NULL &&
      default_methods() != Universe::the_empty_method_array() &&
      !default_methods()->is_shared()) {
    MetadataFactory::free_array<Method*>(loader_data, default_methods());
  }
  set_default_methods(NULL);
  if (default_vtable_indices() != NULL &&
      !default_vtable_indices()->is_shared()) {
    MetadataFactory::free_array<int>(loader_data, default_vtable_indices());
  }
  set_default_vtable_indices(NULL);
  if (secondary_supers() != NULL &&
      secondary_supers() != Universe::the_empty_klass_array() &&
      secondary_supers() != transitive_interfaces() &&
      !secondary_supers()->is_shared()) {
    MetadataFactory::free_array<Klass*>(loader_data, secondary_supers());
  }
  set_secondary_supers(NULL);
  deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces());
  set_transitive_interfaces(NULL);
  set_local_interfaces(NULL);
  if (fields() != NULL && !fields()->is_shared()) {
    MetadataFactory::free_array<jushort>(loader_data, fields());
  }
  set_fields(NULL, 0);
  if (constants() != NULL) {
    assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
    if (!constants()->is_shared()) {
      MetadataFactory::free_metadata(loader_data, constants());
    }
    SystemDictionary::delete_resolution_error(constants());
    set_constants(NULL);
  }
  if (inner_classes() != NULL &&
      inner_classes() != Universe::the_empty_short_array() &&
      !inner_classes()->is_shared()) {
    MetadataFactory::free_array<jushort>(loader_data, inner_classes());
  }
  set_inner_classes(NULL);
  if (annotations() != NULL && !annotations()->is_shared()) {
    MetadataFactory::free_metadata(loader_data, annotations());
  }
  set_annotations(NULL);
}
bool InstanceKlass::should_be_initialized() const {
  return !is_initialized();
}
klassVtable* InstanceKlass::vtable() const {
  return new klassVtable(this, start_of_vtable(), vtable_length() / vtableEntry::size());
}
klassItable* InstanceKlass::itable() const {
  return new klassItable(instanceKlassHandle(this));
}
void InstanceKlass::eager_initialize(Thread *thread) {
  if (!EagerInitialization) return;
  if (this->is_not_initialized()) {
    if (this->class_initializer() != NULL) return;
    Klass* super = this->super();
    if (super == NULL) return;
    if (!InstanceKlass::cast(super)->is_initialized()) return;
    instanceKlassHandle this_oop(thread, this);
    eager_initialize_impl(this_oop);
  }
}
oop InstanceKlass::protection_domain() const {
  return java_lang_Class::protection_domain(java_mirror());
}
objArrayOop InstanceKlass::signers() const {
  return java_lang_Class::signers(java_mirror());
}
oop InstanceKlass::init_lock() const {
  oop lock = java_lang_Class::init_lock(java_mirror());
  OrderAccess::loadload();
  assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state
         "only fully initialized state can have a null lock");
  return lock;
}
void InstanceKlass::fence_and_clear_init_lock() {
  OrderAccess::storestore();
  java_lang_Class::set_init_lock(java_mirror(), NULL);
  assert(!is_not_initialized(), "class must be initialized now");
}
void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
  EXCEPTION_MARK;
  oop init_lock = this_oop->init_lock();
  ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
  if (!this_oop->is_not_initialized()) return;  // note: not equivalent to is_initialized()
  ClassState old_state = this_oop->init_state();
  link_class_impl(this_oop, true, THREAD);
  if (HAS_PENDING_EXCEPTION) {
    CLEAR_PENDING_EXCEPTION;
    if( old_state != this_oop->_init_state )
      this_oop->set_init_state (old_state);
  } else {
    this_oop->set_init_state (fully_initialized);
    this_oop->fence_and_clear_init_lock();
    if (TraceClassInitialization) {
      ResourceMark rm(THREAD);
      tty->print_cr("[Initialized %s without side effects]", this_oop->external_name());
    }
  }
}
void InstanceKlass::initialize(TRAPS) {
  if (this->should_be_initialized()) {
    HandleMark hm(THREAD);
    instanceKlassHandle this_oop(THREAD, this);
    initialize_impl(this_oop, CHECK);
  } else {
    assert(is_initialized(), "sanity check");
  }
}
bool InstanceKlass::verify_code(
    instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
  Verifier::Mode mode =
    throw_verifyerror ? Verifier::ThrowException : Verifier::NoException;
  return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), THREAD);
}
void InstanceKlass::unlink_class() {
  assert(is_linked(), "must be linked");
  _init_state = loaded;
}
void InstanceKlass::link_class(TRAPS) {
  assert(is_loaded(), "must be loaded");
  if (!is_linked()) {
    HandleMark hm(THREAD);
    instanceKlassHandle this_oop(THREAD, this);
    link_class_impl(this_oop, true, CHECK);
  }
}
bool InstanceKlass::link_class_or_fail(TRAPS) {
  assert(is_loaded(), "must be loaded");
  if (!is_linked()) {
    HandleMark hm(THREAD);
    instanceKlassHandle this_oop(THREAD, this);
    link_class_impl(this_oop, false, CHECK_false);
  }
  return is_linked();
}
bool InstanceKlass::link_class_impl(
    instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
  if (this_oop->is_in_error_state()) {
    ResourceMark rm(THREAD);
    THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
               this_oop->external_name(), false);
  }
  if (this_oop->is_linked()) {
    return true;
  }
  assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
  JavaThread* jt = (JavaThread*)THREAD;
  instanceKlassHandle super(THREAD, this_oop->super());
  if (super.not_null()) {
    if (super->is_interface()) {  // check if super class is an interface
      ResourceMark rm(THREAD);
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_IncompatibleClassChangeError(),
        "class %s has interface %s as super class",
        this_oop->external_name(),
        super->external_name()
      );
      return false;
    }
    link_class_impl(super, throw_verifyerror, CHECK_false);
  }
  Array<Klass*>* interfaces = this_oop->local_interfaces();
  int num_interfaces = interfaces->length();
  for (int index = 0; index < num_interfaces; index++) {
    HandleMark hm(THREAD);
    instanceKlassHandle ih(THREAD, interfaces->at(index));
    link_class_impl(ih, throw_verifyerror, CHECK_false);
  }
  if (this_oop->is_linked()) {
    return true;
  }
  PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(),
                             ClassLoader::perf_class_link_selftime(),
                             ClassLoader::perf_classes_linked(),
                             jt->get_thread_stat()->perf_recursion_counts_addr(),
                             jt->get_thread_stat()->perf_timers_addr(),
                             PerfClassTraceTime::CLASS_LINK);
  {
    oop init_lock = this_oop->init_lock();
    ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
    if (!this_oop->is_linked()) {
      if (!this_oop->is_rewritten()) {
        {
          PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
                                   ClassLoader::perf_class_verify_selftime(),
                                   ClassLoader::perf_classes_verified(),
                                   jt->get_thread_stat()->perf_recursion_counts_addr(),
                                   jt->get_thread_stat()->perf_timers_addr(),
                                   PerfClassTraceTime::CLASS_VERIFY);
          bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
          if (!verify_ok) {
            return false;
          }
        }
        if (this_oop->is_linked()) {
          return true;
        }
        this_oop->rewrite_class(CHECK_false);
      } else if (this_oop()->is_shared()) {
        ResourceMark rm(THREAD);
        char* message_buffer; // res-allocated by check_verification_dependencies
        Handle loader = this_oop()->class_loader();
        Handle pd     = this_oop()->protection_domain();
        bool verified = SystemDictionaryShared::check_verification_dependencies(this_oop(),
                        loader, pd, &message_buffer, THREAD);
        if (!verified) {
          THROW_MSG_(vmSymbols::java_lang_VerifyError(), message_buffer, false);
        }
      }
      this_oop->link_methods(CHECK_false);
      ClassLoaderData * loader_data = this_oop->class_loader_data();
      if (!(this_oop()->is_shared() &&
            loader_data->is_the_null_class_loader_data())) {
        ResourceMark rm(THREAD);
        this_oop->vtable()->initialize_vtable(true, CHECK_false);
        this_oop->itable()->initialize_itable(true, CHECK_false);
      }
#ifdef ASSERT
      else {
        ResourceMark rm(THREAD);
        this_oop->vtable()->verify(tty, true);
      }
#endif
      this_oop->set_init_state(linked);
      if (JvmtiExport::should_post_class_prepare()) {
        Thread *thread = THREAD;
        assert(thread->is_Java_thread(), "thread->is_Java_thread()");
        JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop());
      }
    }
  }
  return true;
}
void InstanceKlass::rewrite_class(TRAPS) {
  assert(is_loaded(), "must be loaded");
  instanceKlassHandle this_oop(THREAD, this);
  if (this_oop->is_rewritten()) {
    assert(this_oop()->is_shared(), "rewriting an unshared class?");
    return;
  }
  Rewriter::rewrite(this_oop, CHECK);
  this_oop->set_rewritten();
}
void InstanceKlass::link_methods(TRAPS) {
  int len = methods()->length();
  for (int i = len-1; i >= 0; i--) {
    methodHandle m(THREAD, methods()->at(i));
    m->link_method(m, CHECK);
#ifdef ASSERT
    if (StressMethodComparator) {
      ResourceMark rm(THREAD);
      static int nmc = 0;
      for (int j = i; j >= 0 && j >= i-4; j--) {
        if ((++nmc % 1000) == 0)  tty->print_cr("Have run MethodComparator %d times...", nmc);
        bool z = MethodComparator::methods_EMCP(m(),
                   methods()->at(j));
        if (j == i && !z) {
          tty->print("MethodComparator FAIL: "); m->print(); m->print_codes();
          assert(z, "method must compare equal to itself");
        }
      }
    }
#endif //ASSERT
  }
}
void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) {
  assert (this_k->has_default_methods(), "caller should have checked this");
  for (int i = 0; i < this_k->local_interfaces()->length(); ++i) {
    Klass* iface = this_k->local_interfaces()->at(i);
    InstanceKlass* ik = InstanceKlass::cast(iface);
    if (ik->has_default_methods()) {
      ik->initialize_super_interfaces(ik, CHECK);
    }
    if (ik->should_be_initialized() && ik->declares_default_methods()) {
      ik->initialize(CHECK);
    }
  }
}
void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
  this_oop->link_class(CHECK);
  DTRACE_CLASSINIT_PROBE(required, InstanceKlass::cast(this_oop()), -1);
  bool wait = false;
  {
    oop init_lock = this_oop->init_lock();
    ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
    Thread *self = THREAD; // it's passed the current thread
    while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
        wait = true;
      ol.waitUninterruptibly(CHECK);
    }
    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
      DTRACE_CLASSINIT_PROBE_WAIT(recursive, InstanceKlass::cast(this_oop()), -1,wait);
      return;
    }
    if (this_oop->is_initialized()) {
      DTRACE_CLASSINIT_PROBE_WAIT(concurrent, InstanceKlass::cast(this_oop()), -1,wait);
      return;
    }
    if (this_oop->is_in_error_state()) {
      DTRACE_CLASSINIT_PROBE_WAIT(erroneous, InstanceKlass::cast(this_oop()), -1,wait);
      ResourceMark rm(THREAD);
      const char* desc = "Could not initialize class ";
      const char* className = this_oop->external_name();
      size_t msglen = strlen(desc) + strlen(className) + 1;
      char* message = NEW_RESOURCE_ARRAY(char, msglen);
      if (NULL == message) {
        THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
      } else {
        jio_snprintf(message, msglen, "%s%s", desc, className);
        THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message);
      }
    }
    this_oop->set_init_state(being_initialized);
    this_oop->set_init_thread(self);
  }
  if (!this_oop->is_interface()) {
    Klass* super_klass = this_oop->super();
    if (super_klass != NULL && super_klass->should_be_initialized()) {
      super_klass->initialize(THREAD);
    }
    if (!HAS_PENDING_EXCEPTION && this_oop->has_default_methods()) {
      this_oop->initialize_super_interfaces(this_oop, THREAD);
    }
    if (HAS_PENDING_EXCEPTION) {
      Handle e(THREAD, PENDING_EXCEPTION);
      CLEAR_PENDING_EXCEPTION;
      {
        EXCEPTION_MARK;
        this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
        CLEAR_PENDING_EXCEPTION;
      }
      DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_oop()), -1,wait);
      THROW_OOP(e());
    }
  }
  {
    assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
    JavaThread* jt = (JavaThread*)THREAD;
    DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_oop()), -1,wait);
    PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
                             ClassLoader::perf_class_init_selftime(),
                             ClassLoader::perf_classes_inited(),
                             jt->get_thread_stat()->perf_recursion_counts_addr(),
                             jt->get_thread_stat()->perf_timers_addr(),
                             PerfClassTraceTime::CLASS_CLINIT);
    this_oop->call_class_initializer(THREAD);
  }
  if (!HAS_PENDING_EXCEPTION) {
    this_oop->set_initialization_state_and_notify(fully_initialized, CHECK);
    { ResourceMark rm(THREAD);
      debug_only(this_oop->vtable()->verify(tty, true);)
    }
  }
  else {
    Handle e(THREAD, PENDING_EXCEPTION);
    CLEAR_PENDING_EXCEPTION;
    JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
    {
      EXCEPTION_MARK;
      this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
      CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, class initialization error is thrown below
      JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
    }
    DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_oop()), -1,wait);
    if (e->is_a(SystemDictionary::Error_klass())) {
      THROW_OOP(e());
    } else {
      JavaCallArguments args(e);
      THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(),
                vmSymbols::throwable_void_signature(),
                &args);
    }
  }
  DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_oop()), -1,wait);
}
void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) {
  instanceKlassHandle kh(THREAD, this);
  set_initialization_state_and_notify_impl(kh, state, CHECK);
}
void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) {
  oop init_lock = this_oop->init_lock();
  if (init_lock != NULL) {
    ObjectLocker ol(init_lock, THREAD);
    this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
    this_oop->set_init_state(state);
    this_oop->fence_and_clear_init_lock();
    ol.notify_all(CHECK);
  } else {
    assert(init_lock != NULL, "The initialization state should never be set twice");
    this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
    this_oop->set_init_state(state);
  }
}
void InstanceKlass::add_implementor(Klass* k) {
  assert(Compile_lock->owned_by_self(), "");
  assert(is_interface(), "not interface");
  if (InstanceKlass::cast(k)->is_interface()) return;
  Klass* sk = InstanceKlass::cast(k)->super();
  if (sk != NULL && InstanceKlass::cast(sk)->implements_interface(this))
    return;
  Klass* ik = implementor();
  if (ik == NULL) {
    set_implementor(k);
  } else if (ik != this) {
    set_implementor(this);
  }
  for (int index = 0; index < local_interfaces()->length(); index++) {
    InstanceKlass::cast(local_interfaces()->at(index))->add_implementor(k);
  }
}
void InstanceKlass::init_implementor() {
  if (is_interface()) {
    set_implementor(NULL);
  }
}
void InstanceKlass::process_interfaces(Thread *thread) {
  Klass* this_as_klass_oop = this;
  for (int i = local_interfaces()->length() - 1; i >= 0; i--) {
    assert(local_interfaces()->at(i)->is_klass(), "must be a klass");
    InstanceKlass* interf = InstanceKlass::cast(local_interfaces()->at(i));
    assert(interf->is_interface(), "expected interface");
    interf->add_implementor(this_as_klass_oop);
  }
}
bool InstanceKlass::can_be_primary_super_slow() const {
  if (is_interface())
    return false;
  else
    return Klass::can_be_primary_super_slow();
}
GrowableArray<Klass*>* InstanceKlass::compute_secondary_supers(int num_extra_slots) {
  InstanceKlass* ik = InstanceKlass::cast(this);
  Array<Klass*>* interfaces = ik->transitive_interfaces();
  int num_secondaries = num_extra_slots + interfaces->length();
  if (num_secondaries == 0) {
    set_secondary_supers(Universe::the_empty_klass_array());
    return NULL;
  } else if (num_extra_slots == 0) {
    set_secondary_supers(interfaces);
    return NULL;
  } else {
    GrowableArray<Klass*>* secondaries = new GrowableArray<Klass*>(interfaces->length());
    for (int i = 0; i < interfaces->length(); i++) {
      secondaries->push(interfaces->at(i));
    }
    return secondaries;
  }
}
bool InstanceKlass::compute_is_subtype_of(Klass* k) {
  if (k->is_interface()) {
    return implements_interface(k);
  } else {
    return Klass::compute_is_subtype_of(k);
  }
}
bool InstanceKlass::implements_interface(Klass* k) const {
  if (this == k) return true;
  assert(k->is_interface(), "should be an interface class");
  for (int i = 0; i < transitive_interfaces()->length(); i++) {
    if (transitive_interfaces()->at(i) == k) {
      return true;
    }
  }
  return false;
}
bool InstanceKlass::is_same_or_direct_interface(Klass *k) const {
  if (this == k) return true;
  assert(k->is_interface(), "should be an interface class");
  for (int i = 0; i < local_interfaces()->length(); i++) {
    if (local_interfaces()->at(i) == k) {
      return true;
    }
  }
  return false;
}
objArrayOop InstanceKlass::allocate_objArray(int n, int length, TRAPS) {
  if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
  if (length > arrayOopDesc::max_array_length(T_OBJECT)) {
    report_java_out_of_memory("Requested array size exceeds VM limit");
    JvmtiExport::post_array_size_exhausted();
    THROW_OOP_0(Universe::out_of_memory_error_array_size());
  }
  int size = objArrayOopDesc::object_size(length);
  Klass* ak = array_klass(n, CHECK_NULL);
  KlassHandle h_ak (THREAD, ak);
  objArrayOop o =
    (objArrayOop)CollectedHeap::array_allocate(h_ak, size, length, CHECK_NULL);
  return o;
}
instanceOop InstanceKlass::register_finalizer(instanceOop i, TRAPS) {
  if (TraceFinalizerRegistration) {
    tty->print("Registered ");
    i->print_value_on(tty);
    tty->print_cr(" (" INTPTR_FORMAT ") as finalizable", (address)i);
  }
  instanceHandle h_i(THREAD, i);
  JavaValue result(T_VOID);
  JavaCallArguments args(h_i);
  methodHandle mh (THREAD, Universe::finalizer_register_method());
  JavaCalls::call(&result, mh, &args, CHECK_NULL);
  return h_i();
}
instanceOop InstanceKlass::allocate_instance(TRAPS) {
  bool has_finalizer_flag = has_finalizer(); // Query before possible GC
  int size = size_helper();  // Query before forming handle.
  KlassHandle h_k(THREAD, this);
  instanceOop i;
  i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
  if (has_finalizer_flag && !RegisterFinalizersAtInit) {
    i = register_finalizer(i, CHECK_NULL);
  }
  return i;
}
void InstanceKlass::check_valid_for_instantiation(bool throwError, TRAPS) {
  if (is_interface() || is_abstract()) {
    ResourceMark rm(THREAD);
    THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError()
              : vmSymbols::java_lang_InstantiationException(), external_name());
  }
  if (this == SystemDictionary::Class_klass()) {
    ResourceMark rm(THREAD);
    THROW_MSG(throwError ? vmSymbols::java_lang_IllegalAccessError()
              : vmSymbols::java_lang_IllegalAccessException(), external_name());
  }
}
Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) {
  instanceKlassHandle this_oop(THREAD, this);
  return array_klass_impl(this_oop, or_null, n, THREAD);
}
Klass* InstanceKlass::array_klass_impl(instanceKlassHandle this_oop, bool or_null, int n, TRAPS) {
  if (this_oop->array_klasses() == NULL) {
    if (or_null) return NULL;
    ResourceMark rm;
    JavaThread *jt = (JavaThread *)THREAD;
    {
      MutexLocker mc(Compile_lock, THREAD);   // for vtables
      MutexLocker ma(MultiArray_lock, THREAD);
      if (this_oop->array_klasses() == NULL) {
        Klass*    k = ObjArrayKlass::allocate_objArray_klass(this_oop->class_loader_data(), 1, this_oop, CHECK_NULL);
        this_oop->set_array_klasses(k);
      }
    }
  }
  ObjArrayKlass* oak = (ObjArrayKlass*)this_oop->array_klasses();
  if (or_null) {
    return oak->array_klass_or_null(n);
  }
  return oak->array_klass(n, THREAD);
}
Klass* InstanceKlass::array_klass_impl(bool or_null, TRAPS) {
  return array_klass_impl(or_null, 1, THREAD);
}
void InstanceKlass::call_class_initializer(TRAPS) {
  instanceKlassHandle ik (THREAD, this);
  call_class_initializer_impl(ik, THREAD);
}
static int call_class_initializer_impl_counter = 0;   // for debugging
Method* InstanceKlass::class_initializer() {
  Method* clinit = find_method(
      vmSymbols::class_initializer_name(), vmSymbols::void_method_signature());
  if (clinit != NULL && clinit->has_valid_initializer_flags()) {
    return clinit;
  }
  return NULL;
}
void InstanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) {
  if (ReplayCompiles &&
      (ReplaySuppressInitializers == 1 ||
       ReplaySuppressInitializers >= 2 && this_oop->class_loader() != NULL)) {
    return;
  }
  methodHandle h_method(THREAD, this_oop->class_initializer());
  assert(!this_oop->is_initialized(), "we cannot initialize twice");
  if (TraceClassInitialization) {
    tty->print("%d Initializing ", call_class_initializer_impl_counter++);
    this_oop->name()->print_value();
    tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", (address)this_oop());
  }
  if (h_method() != NULL) {
    JavaCallArguments args; // No arguments
    JavaValue result(T_VOID);
    JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args)
  }
}
void InstanceKlass::mask_for(methodHandle method, int bci,
  InterpreterOopMap* entry_for) {
  if (_oop_map_cache == NULL) {
    MutexLocker x(OopMapCacheAlloc_lock);
    if (_oop_map_cache == NULL) {
      OrderAccess::release_store_ptr(&_oop_map_cache, new OopMapCache());
    }
  }
  _oop_map_cache->lookup(method, bci, entry_for);
}
bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
  for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
    Symbol* f_name = fs.name();
    Symbol* f_sig  = fs.signature();
    if (f_name == name && f_sig == sig) {
      fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
      return true;
    }
  }
  return false;
}
Klass* InstanceKlass::find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
  const int n = local_interfaces()->length();
  for (int i = 0; i < n; i++) {
    Klass* intf1 = local_interfaces()->at(i);
    assert(intf1->is_interface(), "just checking type");
    if (InstanceKlass::cast(intf1)->find_local_field(name, sig, fd)) {
      assert(fd->is_static(), "interface field must be static");
      return intf1;
    }
    Klass* intf2 = InstanceKlass::cast(intf1)->find_interface_field(name, sig, fd);
    if (intf2 != NULL) return intf2;
  }
  return NULL;
}
Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
  if (find_local_field(name, sig, fd)) {
    return const_cast<InstanceKlass*>(this);
  }
  { Klass* intf = find_interface_field(name, sig, fd);
    if (intf != NULL) return intf;
  }
  { Klass* supr = super();
    if (supr != NULL) return InstanceKlass::cast(supr)->find_field(name, sig, fd);
  }
  return NULL;
}
Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const {
  if (find_local_field(name, sig, fd)) {
    if (fd->is_static() == is_static) return const_cast<InstanceKlass*>(this);
  }
  if (is_static) {
    Klass* intf = find_interface_field(name, sig, fd);
    if (intf != NULL) return intf;
  }
  { Klass* supr = super();
    if (supr != NULL) return InstanceKlass::cast(supr)->find_field(name, sig, is_static, fd);
  }
  return NULL;
}
bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
  for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
    if (fs.offset() == offset) {
      fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
      if (fd->is_static() == is_static) return true;
    }
  }
  return false;
}
bool InstanceKlass::find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
  Klass* klass = const_cast<InstanceKlass*>(this);
  while (klass != NULL) {
    if (InstanceKlass::cast(klass)->find_local_field_from_offset(offset, is_static, fd)) {
      return true;
    }
    klass = klass->super();
  }
  return false;
}
void InstanceKlass::methods_do(void f(Method* method)) {
  int len = methods()->length();
  for (int index = 0; index < len; index++) {
    Method* m = methods()->at(index);
    assert(m->is_method(), "must be method");
    f(m);
  }
}
void InstanceKlass::do_local_static_fields(FieldClosure* cl) {
  for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
    if (fs.access_flags().is_static()) {
      fieldDescriptor& fd = fs.field_descriptor();
      cl->do_field(&fd);
    }
  }
}
void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) {
  instanceKlassHandle h_this(THREAD, this);
  do_local_static_fields_impl(h_this, f, mirror, CHECK);
}
void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k,
                             void f(fieldDescriptor* fd, Handle mirror, TRAPS), Handle mirror, TRAPS) {
  for (JavaFieldStream fs(this_k()); !fs.done(); fs.next()) {
    if (fs.access_flags().is_static()) {
      fieldDescriptor& fd = fs.field_descriptor();
      f(&fd, mirror, CHECK);
    }
  }
}
static int compare_fields_by_offset(int* a, int* b) {
  return a[0] - b[0];
}
void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
  InstanceKlass* super = superklass();
  if (super != NULL) {
    super->do_nonstatic_fields(cl);
  }
  fieldDescriptor fd;
  int length = java_fields_count();
  int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
  int j = 0;
  for (int i = 0; i < length; i += 1) {
    fd.reinitialize(this, i);
    if (!fd.is_static()) {
      fields_sorted[j + 0] = fd.offset();
      fields_sorted[j + 1] = i;
      j += 2;
    }
  }
  if (j > 0) {
    length = j;
    qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
    for (int i = 0; i < length; i += 2) {
      fd.reinitialize(this, fields_sorted[i + 1]);
      assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
      cl->do_field(&fd);
    }
  }
  FREE_C_HEAP_ARRAY(int, fields_sorted, mtClass);
}
void InstanceKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) {
  if (array_klasses() != NULL)
    ArrayKlass::cast(array_klasses())->array_klasses_do(f, THREAD);
}
void InstanceKlass::array_klasses_do(void f(Klass* k)) {
  if (array_klasses() != NULL)
    ArrayKlass::cast(array_klasses())->array_klasses_do(f);
}
#ifdef ASSERT
static int linear_search(Array<Method*>* methods, Symbol* name, Symbol* signature) {
  int len = methods->length();
  for (int index = 0; index < len; index++) {
    Method* m = methods->at(index);
    assert(m->is_method(), "must be method");
    if (m->signature() == signature && m->name() == name) {
       return index;
    }
  }
  return -1;
}
#endif
static int binary_search(Array<Method*>* methods, Symbol* name) {
  int len = methods->length();
  int l = 0;
  int h = len - 1;
  while (l <= h) {
    int mid = (l + h) >> 1;
    Method* m = methods->at(mid);
    assert(m->is_method(), "must be method");
    int res = m->name()->fast_compare(name);
    if (res == 0) {
      return mid;
    } else if (res < 0) {
      l = mid + 1;
    } else {
      h = mid - 1;
    }
  }
  return -1;
}
Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
  return find_method_impl(name, signature, find_overpass, find_static, find_private);
}
Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature,
                                        OverpassLookupMode overpass_mode,
                                        StaticLookupMode static_mode,
                                        PrivateLookupMode private_mode) const {
  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
}
Method* InstanceKlass::find_instance_method(Array<Method*>* methods,
                                            Symbol* name,
                                            Symbol* signature,
                                            PrivateLookupMode private_mode) {
  Method* meth = InstanceKlass::find_method_impl(methods, name, signature,
                                                 find_overpass, skip_static, private_mode);
  assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics");
  return meth;
}
Method* InstanceKlass::find_instance_method(Symbol* name,
                                            Symbol* signature,
                                            PrivateLookupMode private_mode) {
  return InstanceKlass::find_instance_method(methods(), name, signature, private_mode);
}
Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature,
                                        OverpassLookupMode overpass_mode,
                                        StaticLookupMode static_mode,
                                        PrivateLookupMode private_mode) const {
  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
}
Method* InstanceKlass::find_local_method(Array<Method*>* methods,
                                        Symbol* name, Symbol* signature,
                                        OverpassLookupMode overpass_mode,
                                        StaticLookupMode static_mode,
                                        PrivateLookupMode private_mode) {
  return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode);
}
Method* InstanceKlass::find_method(
    Array<Method*>* methods, Symbol* name, Symbol* signature) {
  return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private);
}
Method* InstanceKlass::find_method_impl(
    Array<Method*>* methods, Symbol* name, Symbol* signature,
    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
    PrivateLookupMode private_mode) {
  int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode);
  return hit >= 0 ? methods->at(hit): NULL;
}
bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) {
    return  ((m->signature() == signature) &&
            (!skipping_overpass || !m->is_overpass()) &&
            (!skipping_static || !m->is_static()) &&
            (!skipping_private || !m->is_private()));
}
int InstanceKlass::find_method_index(
    Array<Method*>* methods, Symbol* name, Symbol* signature,
    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
    PrivateLookupMode private_mode) {
  bool skipping_overpass = (overpass_mode == skip_overpass);
  bool skipping_static = (static_mode == skip_static);
  bool skipping_private = (private_mode == skip_private);
  int hit = binary_search(methods, name);
  if (hit != -1) {
    Method* m = methods->at(hit);
    if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit;
    int i;
    for (i = hit - 1; i >= 0; --i) {
        Method* m = methods->at(i);
        assert(m->is_method(), "must be method");
        if (m->name() != name) break;
        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
    }
    for (i = hit + 1; i < methods->length(); ++i) {
        Method* m = methods->at(i);
        assert(m->is_method(), "must be method");
        if (m->name() != name) break;
        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
    }
#ifdef ASSERT
    int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
    assert(index == -1, err_msg("binary search should have found entry %d", index));
#endif
  }
  return -1;
}
int InstanceKlass::find_method_by_name(Symbol* name, int* end) {
  return find_method_by_name(methods(), name, end);
}
int InstanceKlass::find_method_by_name(
    Array<Method*>* methods, Symbol* name, int* end_ptr) {
  assert(end_ptr != NULL, "just checking");
  int start = binary_search(methods, name);
  int end = start + 1;
  if (start != -1) {
    while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start;
    while (end < methods->length() && (methods->at(end))->name() == name) ++end;
    return start;
  }
  return -1;
}
Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
  OverpassLookupMode overpass_local_mode = overpass_mode;
  Klass* klass = const_cast<InstanceKlass*>(this);
  while (klass != NULL) {
    Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static, find_private);
    if (method != NULL) {
      return method;
    }
    klass = InstanceKlass::cast(klass)->super();
    overpass_local_mode = skip_overpass;   // Always ignore overpass methods in superclasses
  }
  return NULL;
}
#ifdef ASSERT
bool InstanceKlass::has_redefined_this_or_super() const {
  const InstanceKlass* klass = this;
  while (klass != NULL) {
    if (klass->has_been_redefined()) {
      return true;
    }
    klass = InstanceKlass::cast(klass->super());
  }
  return false;
}
#endif
Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name,
                                                         Symbol* signature) const {
  Method* m = NULL;
  if (default_methods() != NULL) {
    m = find_method(default_methods(), name, signature);
  }
  if (m == NULL) {
    m = lookup_method_in_all_interfaces(name, signature, find_defaults);
  }
  return m;
}
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
                                                       Symbol* signature,
                                                       DefaultsLookupMode defaults_mode) const {
  Array<Klass*>* all_ifs = transitive_interfaces();
  int num_ifs = all_ifs->length();
  InstanceKlass *ik = NULL;
  for (int i = 0; i < num_ifs; i++) {
    ik = InstanceKlass::cast(all_ifs->at(i));
    Method* m = ik->lookup_method(name, signature);
    if (m != NULL && m->is_public() && !m->is_static() &&
        ((defaults_mode != skip_defaults) || !m->is_default_method())) {
      return m;
    }
  }
  return NULL;
}
JNIid* InstanceKlass::jni_id_for_impl(instanceKlassHandle this_oop, int offset) {
  MutexLocker ml(JfieldIdCreation_lock);
  JNIid* probe = this_oop->jni_ids() == NULL ? NULL : this_oop->jni_ids()->find(offset);
  if (probe == NULL) {
    probe = new JNIid(this_oop(), offset, this_oop->jni_ids());
    this_oop->set_jni_ids(probe);
  }
  return probe;
}
JNIid* InstanceKlass::jni_id_for(int offset) {
  JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset);
  if (probe == NULL) {
    probe = jni_id_for_impl(this, offset);
  }
  return probe;
}
u2 InstanceKlass::enclosing_method_data(int offset) {
  Array<jushort>* inner_class_list = inner_classes();
  if (inner_class_list == NULL) {
    return 0;
  }
  int length = inner_class_list->length();
  if (length % inner_class_next_offset == 0) {
    return 0;
  } else {
    int index = length - enclosing_method_attribute_size;
    assert(offset < enclosing_method_attribute_size, "invalid offset");
    return inner_class_list->at(index + offset);
  }
}
void InstanceKlass::set_enclosing_method_indices(u2 class_index,
                                                 u2 method_index) {
  Array<jushort>* inner_class_list = inner_classes();
  assert (inner_class_list != NULL, "_inner_classes list is not set up");
  int length = inner_class_list->length();
  if (length % inner_class_next_offset == enclosing_method_attribute_size) {
    int index = length - enclosing_method_attribute_size;
    inner_class_list->at_put(
      index + enclosing_method_class_index_offset, class_index);
    inner_class_list->at_put(
      index + enclosing_method_method_index_offset, method_index);
  }
}
jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle method_h) {
  size_t idnum = (size_t)method_h->method_idnum();
  jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
  size_t length = 0;
  jmethodID id = NULL;
  if (jmeths != NULL) {
    if (!ik_h->idnum_can_increment()) {
      get_jmethod_id_length_value(jmeths, idnum, &length, &id);
    } else {
      if (Threads::number_of_threads() == 0 ||
          SafepointSynchronize::is_at_safepoint()) {
        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
      } else {
        MutexLocker ml(JmethodIdCreation_lock);
        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
      }
    }
  }
  if (jmeths == NULL ||   // no cache yet
      length <= idnum ||  // cache is too short
      id == NULL) {       // cache doesn't contain entry
    jmethodID  to_dealloc_id     = NULL;
    jmethodID* to_dealloc_jmeths = NULL;
    jmethodID* new_jmeths = NULL;
    if (length <= idnum) {
      size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count());
      new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1, mtClass);
      memset(new_jmeths, 0, (size+1)*sizeof(jmethodID));
      new_jmeths[0] = (jmethodID)size;
    }
    jmethodID new_id = NULL;
    if (method_h->is_old() && !method_h->is_obsolete()) {
      Method* current_method = ik_h->method_with_idnum((int)idnum);
      assert(current_method != NULL, "old and but not obsolete, so should exist");
      new_id = Method::make_jmethod_id(ik_h->class_loader_data(), current_method);
    } else {
      new_id = Method::make_jmethod_id(ik_h->class_loader_data(), method_h());
    }
    if (Threads::number_of_threads() == 0 ||
        SafepointSynchronize::is_at_safepoint()) {
      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
                                          &to_dealloc_id, &to_dealloc_jmeths);
    } else {
      MutexLocker ml(JmethodIdCreation_lock);
      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
                                          &to_dealloc_id, &to_dealloc_jmeths);
    }
    if (to_dealloc_jmeths != NULL) {
      FreeHeap(to_dealloc_jmeths);
    }
    if (to_dealloc_id != NULL) {
      Method::destroy_jmethod_id(ik_h->class_loader_data(), to_dealloc_id);
    }
  }
  return id;
}
jmethodID InstanceKlass::get_jmethod_id_fetch_or_update(
            instanceKlassHandle ik_h, size_t idnum, jmethodID new_id,
            jmethodID* new_jmeths, jmethodID* to_dealloc_id_p,
            jmethodID** to_dealloc_jmeths_p) {
  assert(new_id != NULL, "sanity check");
  assert(to_dealloc_id_p != NULL, "sanity check");
  assert(to_dealloc_jmeths_p != NULL, "sanity check");
  assert(Threads::number_of_threads() == 0 ||
         SafepointSynchronize::is_at_safepoint() ||
         JmethodIdCreation_lock->owned_by_self(), "sanity check");
  jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
  jmethodID  id     = NULL;
  size_t     length = 0;
  if (jmeths == NULL ||                         // no cache yet
      (length = (size_t)jmeths[0]) <= idnum) {  // cache is too short
    if (jmeths != NULL) {
      for (size_t index = 0; index < length; index++) {
        new_jmeths[index+1] = jmeths[index+1];
      }
    }
    ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
  } else {
    id = jmeths[idnum+1];
  }
  if (id == NULL) {
    id = new_id;
    OrderAccess::release_store_ptr(&jmeths[idnum+1], id);
  } else {
  }
  return id;
}
void InstanceKlass::get_jmethod_id_length_value(jmethodID* cache,
       size_t idnum, size_t *length_p, jmethodID* id_p) {
  assert(cache != NULL, "sanity check");
  assert(length_p != NULL, "sanity check");
  assert(id_p != NULL, "sanity check");
  if (*length_p <= idnum) {  // cache is too short
  } else {
  }
}
jmethodID InstanceKlass::jmethod_id_or_null(Method* method) {
  size_t idnum = (size_t)method->method_idnum();
  jmethodID* jmeths = methods_jmethod_ids_acquire();
  size_t length;                                // length assigned as debugging crumb
  jmethodID id = NULL;
  if (jmeths != NULL &&                         // If there is a cache
      (length = (size_t)jmeths[0]) > idnum) {   // and if it is long enough,
    id = jmeths[idnum+1];                       // Look up the id (may be NULL)
  }
  return id;
}
int nmethodBucket::decrement() {
  return Atomic::add(-1, (volatile int *)&_count);
}
int InstanceKlass::mark_dependent_nmethods(DepChange& changes) {
  assert_locked_or_safepoint(CodeCache_lock);
  int found = 0;
  nmethodBucket* b = _dependencies;
  while (b != NULL) {
    nmethod* nm = b->get_nmethod();
    if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
      if (TraceDependencies) {
        ResourceMark rm;
        tty->print_cr("Marked for deoptimization");
        tty->print_cr("  context = %s", this->external_name());
        changes.print();
        nm->print();
        nm->print_dependencies();
      }
      nm->mark_for_deoptimization();
      found++;
    }
    b = b->next();
  }
  return found;
}
void InstanceKlass::clean_dependent_nmethods() {
  assert_locked_or_safepoint(CodeCache_lock);
  if (has_unloaded_dependent()) {
    nmethodBucket* b = _dependencies;
    nmethodBucket* last = NULL;
    while (b != NULL) {
      assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
      nmethodBucket* next = b->next();
      if (b->count() == 0) {
        if (last == NULL) {
          _dependencies = next;
        } else {
          last->set_next(next);
        }
        delete b;
      } else {
        last = b;
      }
      b = next;
    }
    set_has_unloaded_dependent(false);
  }
#ifdef ASSERT
  else {
    for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) {
      assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
      assert(b->count() != 0, "empty buckets need to be cleaned");
    }
  }
#endif
}
void InstanceKlass::add_dependent_nmethod(nmethod* nm) {
  assert_locked_or_safepoint(CodeCache_lock);
  nmethodBucket* b = _dependencies;
  nmethodBucket* last = NULL;
  while (b != NULL) {
    if (nm == b->get_nmethod()) {
      b->increment();
      return;
    }
    b = b->next();
  }
  _dependencies = new nmethodBucket(nm, _dependencies);
}
void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
  assert_locked_or_safepoint(CodeCache_lock);
  nmethodBucket* b = _dependencies;
  nmethodBucket* last = NULL;
  while (b != NULL) {
    if (nm == b->get_nmethod()) {
      int val = b->decrement();
      guarantee(val >= 0, err_msg("Underflow: %d", val));
      if (val == 0) {
        if (delete_immediately) {
          if (last == NULL) {
            _dependencies = b->next();
          } else {
            last->set_next(b->next());
          }
          delete b;
        } else {
          set_has_unloaded_dependent(true);
        }
      }
      return;
    }
    last = b;
    b = b->next();
  }
#ifdef ASSERT
  tty->print_cr("### %s can't find dependent nmethod:", this->external_name());
  nm->print();
#endif // ASSERT
  ShouldNotReachHere();
}
#ifndef PRODUCT
void InstanceKlass::print_dependent_nmethods(bool verbose) {
  nmethodBucket* b = _dependencies;
  int idx = 0;
  while (b != NULL) {
    nmethod* nm = b->get_nmethod();
    tty->print("[%d] count=%d { ", idx++, b->count());
    if (!verbose) {
      nm->print_on(tty, "nmethod");
      tty->print_cr(" } ");
    } else {
      nm->print();
      nm->print_dependencies();
      tty->print_cr("--- } ");
    }
    b = b->next();
  }
}
bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
  nmethodBucket* b = _dependencies;
  while (b != NULL) {
    if (nm == b->get_nmethod()) {
#ifdef ASSERT
      int count = b->count();
      assert(count >= 0, err_msg("count shouldn't be negative: %d", count));
#endif
      return true;
    }
    b = b->next();
  }
  return false;
}
#endif //PRODUCT
#ifdef ASSERT
template <class T> void assert_is_in(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in(o), "should be in heap");
  }
}
template <class T> void assert_is_in_closed_subset(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in_closed_subset(o),
           err_msg("should be in closed *p " INTPTR_FORMAT " " INTPTR_FORMAT, (address)p, (address)o));
  }
}
template <class T> void assert_is_in_reserved(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
  }
}
template <class T> void assert_nothing(T *p) {}
#else
template <class T> void assert_is_in(T *p) {}
template <class T> void assert_is_in_closed_subset(T *p) {}
template <class T> void assert_is_in_reserved(T *p) {}
template <class T> void assert_nothing(T *p) {}
#endif // ASSERT
#define InstanceKlass_SPECIALIZED_OOP_ITERATE( \
  T, start_p, count, do_oop,                \
  assert_fn)                                \
{                                           \
  T* p         = (T*)(start_p);             \
  T* const end = p + (count);               \
  while (p < end) {                         \
    (assert_fn)(p);                         \
    do_oop;                                 \
    ++p;                                    \
  }                                         \
}
#define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \
  T, start_p, count, do_oop,                \
  assert_fn)                                \
{                                           \
  T* const start = (T*)(start_p);           \
  T*       p     = start + (count);         \
  while (start < p) {                       \
    --p;                                    \
    (assert_fn)(p);                         \
    do_oop;                                 \
  }                                         \
}
#define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
  T, start_p, count, low, high,             \
  do_oop, assert_fn)                        \
{                                           \
  T* const l = (T*)(low);                   \
  T* const h = (T*)(high);                  \
  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
         mask_bits((intptr_t)h, sizeof(T)-1) == 0,   \
         "bounded region must be properly aligned"); \
  T* p       = (T*)(start_p);               \
  T* end     = p + (count);                 \
  if (p < l) p = l;                         \
  if (end > h) end = h;                     \
  while (p < end) {                         \
    (assert_fn)(p);                         \
    do_oop;                                 \
    ++p;                                    \
  }                                         \
}
#define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn)            \
{                                                                        \
     is nonstatic_oop_map_size == 1. */                                  \
  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
  OopMapBlock* const end_map = map + nonstatic_oop_map_count();          \
  if (UseCompressedOops) {                                               \
    while (map < end_map) {                                              \
      InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop,                   \
        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
        do_oop, assert_fn)                                               \
      ++map;                                                             \
    }                                                                    \
  } else {                                                               \
    while (map < end_map) {                                              \
      InstanceKlass_SPECIALIZED_OOP_ITERATE(oop,                         \
        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
        do_oop, assert_fn)                                               \
      ++map;                                                             \
    }                                                                    \
  }                                                                      \
}
#define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn)    \
{                                                                        \
  OopMapBlock* const start_map = start_of_nonstatic_oop_maps();          \
  OopMapBlock* map             = start_map + nonstatic_oop_map_count();  \
  if (UseCompressedOops) {                                               \
    while (start_map < map) {                                            \
      --map;                                                             \
      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop,           \
        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
        do_oop, assert_fn)                                               \
    }                                                                    \
  } else {                                                               \
    while (start_map < map) {                                            \
      --map;                                                             \
      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop,                 \
        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
        do_oop, assert_fn)                                               \
    }                                                                    \
  }                                                                      \
}
#define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop,    \
                                              assert_fn)                 \
{                                                                        \
     nonstatic_oop_map_size == 1, so we accept the                       \
     usually non-existent extra overhead of examining                    \
     all the maps. */                                                    \
  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
  OopMapBlock* const end_map = map + nonstatic_oop_map_count();          \
  if (UseCompressedOops) {                                               \
    while (map < end_map) {                                              \
      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,           \
        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
        low, high,                                                       \
        do_oop, assert_fn)                                               \
      ++map;                                                             \
    }                                                                    \
  } else {                                                               \
    while (map < end_map) {                                              \
      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,                 \
        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
        low, high,                                                       \
        do_oop, assert_fn)                                               \
      ++map;                                                             \
    }                                                                    \
  }                                                                      \
}
void InstanceKlass::oop_follow_contents(oop obj) {
  assert(obj != NULL, "can't follow the content of NULL object");
  MarkSweep::follow_klass(obj->klass());
  InstanceKlass_OOP_MAP_ITERATE( \
    obj, \
    MarkSweep::mark_and_push(p), \
    assert_is_in_closed_subset)
}
#if INCLUDE_ALL_GCS
void InstanceKlass::oop_follow_contents(ParCompactionManager* cm,
                                        oop obj) {
  assert(obj != NULL, "can't follow the content of NULL object");
  PSParallelCompact::follow_klass(cm, obj->klass());
  InstanceKlass_OOP_MAP_ITERATE( \
    obj, \
    PSParallelCompact::mark_and_push(cm, p), \
    assert_is_in)
}
#endif // INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
                                                                             \
int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
  if_do_metadata_checked(closure, nv_suffix) {                          \
    closure->do_klass##nv_suffix(obj->klass());                         \
  }                                                                     \
  InstanceKlass_OOP_MAP_ITERATE(                                        \
    obj,                                                                \
    SpecializationStats::                                               \
      record_do_oop_call##nv_suffix(SpecializationStats::ik);           \
    (closure)->do_oop##nv_suffix(p),                                    \
    assert_is_in_closed_subset)                                         \
  return size_helper();                                                 \
}
#if INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                \
int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj,                \
                                              OopClosureType* closure) {        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
                                                                                \
  assert_should_ignore_metadata(closure, nv_suffix);                            \
                                                                                \
  InstanceKlass_OOP_MAP_REVERSE_ITERATE(                                        \
    obj,                                                                        \
    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::ik);\
    (closure)->do_oop##nv_suffix(p),                                            \
    assert_is_in_closed_subset)                                                 \
   return size_helper();                                                        \
}
#endif // INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
                                                                        \
int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj,              \
                                                  OopClosureType* closure, \
                                                  MemRegion mr) {          \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
  if_do_metadata_checked(closure, nv_suffix) {                           \
    if (mr.contains(obj)) {                                              \
      closure->do_klass##nv_suffix(obj->klass());                        \
    }                                                                    \
  }                                                                      \
  InstanceKlass_BOUNDED_OOP_MAP_ITERATE(                                 \
    obj, mr.start(), mr.end(),                                           \
    (closure)->do_oop##nv_suffix(p),                                     \
    assert_is_in_closed_subset)                                          \
  return size_helper();                                                  \
}
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
#endif // INCLUDE_ALL_GCS
int InstanceKlass::oop_adjust_pointers(oop obj) {
  int size = size_helper();
  InstanceKlass_OOP_MAP_ITERATE( \
    obj, \
    MarkSweep::adjust_pointer(p), \
    assert_is_in)
  return size;
}
#if INCLUDE_ALL_GCS
void InstanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
  InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
    obj, \
    if (PSScavenge::should_scavenge(p)) { \
      pm->claim_or_forward_depth(p); \
    }, \
    assert_nothing )
}
int InstanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  int size = size_helper();
  InstanceKlass_OOP_MAP_ITERATE( \
    obj, \
    PSParallelCompact::adjust_pointer(p), \
    assert_is_in)
  return size;
}
#endif // INCLUDE_ALL_GCS
void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
  clean_implementors_list(is_alive);
  clean_method_data(is_alive);
  clean_dependent_nmethods();
}
void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
  assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
  if (is_interface()) {
    if (ClassUnloading) {
      Klass* impl = implementor();
      if (impl != NULL) {
        if (!impl->is_loader_alive(is_alive)) {
          Klass** klass = adr_implementor();
          assert(klass != NULL, "null klass");
          if (klass != NULL) {
          }
        }
      }
    }
  }
}
void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) {
  for (int m = 0; m < methods()->length(); m++) {
    MethodData* mdo = methods()->at(m)->method_data();
    if (mdo != NULL) {
      mdo->clean_method_data(is_alive);
    }
  }
}
static void remove_unshareable_in_class(Klass* k) {
  k->remove_unshareable_info();
}
void InstanceKlass::remove_unshareable_info() {
  Klass::remove_unshareable_info();
  if (is_linked()) {
    unlink_class();
  }
  init_implementor();
  constants()->remove_unshareable_info();
  for (int i = 0; i < methods()->length(); i++) {
    Method* m = methods()->at(i);
    m->remove_unshareable_info();
  }
  array_klasses_do(remove_unshareable_in_class);
}
static void restore_unshareable_in_class(Klass* k, TRAPS) {
  k->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
}
void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
  Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
  instanceKlassHandle ik(THREAD, this);
  Array<Method*>* methods = ik->methods();
  int num_methods = methods->length();
  for (int index2 = 0; index2 < num_methods; ++index2) {
    methodHandle m(THREAD, methods->at(index2));
    m->restore_unshareable_info(CHECK);
  }
  if (JvmtiExport::has_redefined_a_class()) {
    ResourceMark rm(THREAD);
    ik->vtable()->initialize_vtable(false, CHECK);
    ik->itable()->initialize_itable(false, CHECK);
  }
  ik->constants()->restore_unshareable_info(CHECK);
  ik->array_klasses_do(restore_unshareable_in_class, CHECK);
}
bool InstanceKlass::check_sharing_error_state() {
  assert(DumpSharedSpaces, "should only be called during dumping");
  bool old_state = is_in_error_state();
  if (!is_in_error_state()) {
    bool bad = false;
    for (InstanceKlass* sup = java_super(); sup; sup = sup->java_super()) {
      if (sup->is_in_error_state()) {
        bad = true;
        break;
      }
    }
    if (!bad) {
      Array<Klass*>* interfaces = transitive_interfaces();
      for (int i = 0; i < interfaces->length(); i++) {
        Klass* iface = interfaces->at(i);
        if (InstanceKlass::cast(iface)->is_in_error_state()) {
          bad = true;
          break;
        }
      }
    }
    if (bad) {
      set_in_error_state();
    }
  }
  return (old_state != is_in_error_state());
}
static void clear_all_breakpoints(Method* m) {
  m->clear_all_breakpoints();
}
void InstanceKlass::notify_unload_class(InstanceKlass* ik) {
  if (JvmtiExport::should_post_class_unload()) {
    JvmtiExport::post_class_unload(ik);
  }
  ClassLoadingService::notify_class_unloaded(ik);
#if INCLUDE_JFR
  assert(ik != NULL, "invariant");
  EventClassUnload event;
  event.set_unloadedClass(ik);
  event.set_definingClassLoader(ik->class_loader_data());
  event.commit();
#endif
}
void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) {
  ik->release_C_heap_structures();
  ik->constants()->release_C_heap_structures();
}
void InstanceKlass::release_C_heap_structures() {
  if (_oop_map_cache != NULL) {
    delete _oop_map_cache;
    _oop_map_cache = NULL;
  }
  JNIid::deallocate(jni_ids());
  set_jni_ids(NULL);
  jmethodID* jmeths = methods_jmethod_ids_acquire();
  if (jmeths != (jmethodID*)NULL) {
    release_set_methods_jmethod_ids(NULL);
    FreeHeap(jmeths);
  }
  {
    Mutex* lock_or_null = SafepointSynchronize::is_at_safepoint() ? NULL : MemberNameTable_lock;
    MutexLockerEx ml(lock_or_null, Mutex::_no_safepoint_check_flag);
    MemberNameTable* mnt = member_names();
    if (mnt != NULL) {
      delete mnt;
      set_member_names(NULL);
    }
  }
  nmethodBucket* b = _dependencies;
  _dependencies = NULL;
  while (b != NULL) {
    nmethodBucket* next = b->next();
    delete b;
    b = next;
  }
  if (breakpoints() != 0x0) {
    methods_do(clear_all_breakpoints);
    assert(breakpoints() == 0x0, "should have cleared breakpoints");
  }
  if (_cached_class_file != NULL) {
    os::free(_cached_class_file, mtClass);
    _cached_class_file = NULL;
  }
  if (_name != NULL) _name->decrement_refcount();
  if (_array_name != NULL)  _array_name->decrement_refcount();
  if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
  assert(_total_instanceKlass_count >= 1, "Sanity check");
  Atomic::dec(&_total_instanceKlass_count);
}
void InstanceKlass::set_source_debug_extension(char* array, int length) {
  if (array == NULL) {
    _source_debug_extension = NULL;
  } else {
    assert((length+1) > length, "Overflow checking");
    char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
    for (int i = 0; i < length; i++) {
      sde[i] = array[i];
    }
    sde[length] = '\0';
    _source_debug_extension = sde;
  }
}
address InstanceKlass::static_field_addr(int offset) {
  return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop<intptr_t>(java_mirror()));
}
const char* InstanceKlass::signature_name() const {
  int hash_len = 0;
  char hash_buf[40];
  if (is_anonymous()) {
    assert(EnableInvokeDynamic, "EnableInvokeDynamic was not set.");
    intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
    sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
    hash_len = (int)strlen(hash_buf);
  }
  const char* src = (const char*) (name()->as_C_string());
  const int src_length = (int)strlen(src);
  char* dest = NEW_RESOURCE_ARRAY(char, src_length + hash_len + 3);
  int dest_index = 0;
  dest[dest_index++] = 'L';
  for (int src_index = 0; src_index < src_length; ) {
    dest[dest_index++] = src[src_index++];
  }
  for (int hash_index = 0; hash_index < hash_len; ) {
    dest[dest_index++] = hash_buf[hash_index++];
  }
  dest[dest_index++] = ';';
  dest[dest_index] = '\0';
  return dest;
}
bool InstanceKlass::is_same_class_package(Klass* class2) {
  Klass* class1 = this;
  oop classloader1 = InstanceKlass::cast(class1)->class_loader();
  Symbol* classname1 = class1->name();
  if (class2->oop_is_objArray()) {
    class2 = ObjArrayKlass::cast(class2)->bottom_klass();
  }
  oop classloader2;
  if (class2->oop_is_instance()) {
    classloader2 = InstanceKlass::cast(class2)->class_loader();
  } else {
    assert(class2->oop_is_typeArray(), "should be type array");
    classloader2 = NULL;
  }
  Symbol* classname2 = class2->name();
  return InstanceKlass::is_same_class_package(classloader1, classname1,
                                              classloader2, classname2);
}
bool InstanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) {
  Klass* class1 = this;
  oop classloader1 = InstanceKlass::cast(class1)->class_loader();
  Symbol* classname1 = class1->name();
  return InstanceKlass::is_same_class_package(classloader1, classname1,
                                              classloader2, classname2);
}
bool InstanceKlass::is_same_class_package(oop class_loader1, Symbol* class_name1,
                                          oop class_loader2, Symbol* class_name2) {
  if (class_loader1 != class_loader2) {
    return false;
  } else if (class_name1 == class_name2) {
    return true;                // skip painful bytewise comparison
  } else {
    ResourceMark rm;
    const jbyte *name1 = class_name1->base();
    const jbyte *name2 = class_name2->base();
    const jbyte *last_slash1 = UTF8::strrchr(name1, class_name1->utf8_length(), '/');
    const jbyte *last_slash2 = UTF8::strrchr(name2, class_name2->utf8_length(), '/');
    if ((last_slash1 == NULL) || (last_slash2 == NULL)) {
      return last_slash1 == last_slash2;
    } else {
      if (*name1 == '[') {
        do {
          name1++;
        } while (*name1 == '[');
        if (*name1 != 'L') {
          return false;
        }
      }
      if (*name2 == '[') {
        do {
          name2++;
        } while (*name2 == '[');
        if (*name2 != 'L') {
          return false;
        }
      }
      int length1 = last_slash1 - name1;
      int length2 = last_slash2 - name2;
      return UTF8::equal(name1, length1, name2, length2);
    }
  }
}
bool InstanceKlass::is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS) {
   if (super_method->is_private()) {
     return false;
   }
   if ((super_method->is_protected()) ||
       (super_method->is_public())) {
     return true;
   }
   assert(super_method->is_package_private(), "must be package private");
   return(is_same_class_package(targetclassloader(), targetclassname));
}
Klass* InstanceKlass::compute_enclosing_class_impl(instanceKlassHandle self,
                                                     Symbol*& simple_name_result, TRAPS) {
  ...
}
bool InstanceKlass::is_same_package_member_impl(instanceKlassHandle class1,
                                                Klass* class2_oop, TRAPS) {
  if (class2_oop == class1())                       return true;
  if (!class2_oop->oop_is_instance())  return false;
  instanceKlassHandle class2(THREAD, class2_oop);
  if (!class1->is_same_class_package(class2->class_loader(), class2->name()))
    return false;
  instanceKlassHandle outer1 = class1;
  for (;;) {
    bool ignore_inner_is_member;
    Klass* next = outer1->compute_enclosing_class(&ignore_inner_is_member,
                                                    CHECK_false);
    if (next == NULL)  break;
    if (next == class2())  return true;
    outer1 = instanceKlassHandle(THREAD, next);
  }
  instanceKlassHandle outer2 = class2;
  for (;;) {
    bool ignore_inner_is_member;
    Klass* next = outer2->compute_enclosing_class(&ignore_inner_is_member,
                                                    CHECK_false);
    if (next == NULL)  break;
    if (next == class1())  return true;
    if (next == outer1())  return true;
    outer2 = instanceKlassHandle(THREAD, next);
  }
  return false;
}
jint InstanceKlass::compute_modifier_flags(TRAPS) const {
  jint access = access_flags().as_int();
  instanceKlassHandle ik(THREAD, this);
  InnerClassesIterator iter(ik);
  for (; !iter.done(); iter.next()) {
    int ioff = iter.inner_class_info_index();
    if (ioff == 0) continue;
    Symbol* inner_name = ik->constants()->klass_name_at(ioff);
    if ((ik->name() == inner_name)) {
      access = iter.inner_access_flags();
      break;
    }
  }
  return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS;
}
jint InstanceKlass::jvmti_class_status() const {
  jint result = 0;
  if (is_linked()) {
    result |= JVMTI_CLASS_STATUS_VERIFIED | JVMTI_CLASS_STATUS_PREPARED;
  }
  if (is_initialized()) {
    assert(is_linked(), "Class status is not consistent");
    result |= JVMTI_CLASS_STATUS_INITIALIZED;
  }
  if (is_in_error_state()) {
    result |= JVMTI_CLASS_STATUS_ERROR;
  }
  return result;
}
Method* InstanceKlass::method_at_itable(Klass* holder, int index, TRAPS) {
  itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable();
  int method_table_offset_in_words = ioe->offset()/wordSize;
  int nof_interfaces = (method_table_offset_in_words - itable_offset_in_words())
                       / itableOffsetEntry::size();
  for (int cnt = 0 ; ; cnt ++, ioe ++) {
    if (cnt >= nof_interfaces) {
      THROW_NULL(vmSymbols::java_lang_IncompatibleClassChangeError());
    }
    Klass* ik = ioe->interface_klass();
    if (ik == holder) break;
  }
  itableMethodEntry* ime = ioe->first_method_entry(this);
  Method* m = ime[index].method();
  if (m == NULL) {
    THROW_NULL(vmSymbols::java_lang_AbstractMethodError());
  }
  return m;
}
#if INCLUDE_JVMTI
void InstanceKlass::adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed) {
  if (default_methods() != NULL) {
    for (int index = 0; index < default_methods()->length(); index ++) {
      Method* old_method = default_methods()->at(index);
      if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
        continue; // skip uninteresting entries
      }
      assert(!old_method->is_deleted(), "default methods may not be deleted");
      Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
      assert(new_method != NULL, "method_with_idnum() should not be NULL");
      assert(old_method != new_method, "sanity check");
      default_methods()->at_put(index, new_method);
      if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
        if (!(*trace_name_printed)) {
          RC_TRACE_MESG(("adjust: klassname=%s default methods from name=%s",
                         external_name(),
                         old_method->method_holder()->external_name()));
        }
        RC_TRACE(0x00100000, ("default method update: %s(%s) ",
                              new_method->name()->as_C_string(),
                              new_method->signature()->as_C_string()));
      }
    }
  }
}
#endif // INCLUDE_JVMTI
void InstanceKlass::add_osr_nmethod(nmethod* n) {
#ifndef PRODUCT
  if (TieredCompilation) {
      nmethod * prev = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), n->comp_level(), true);
      assert(prev == NULL || !prev->is_in_use(),
      "redundunt OSR recompilation detected. memory leak in CodeCache!");
  }
#endif
  NEEDS_CLEANUP
  OsrList_lock->lock_without_safepoint_check();
  assert(n->is_osr_method(), "wrong kind of nmethod");
  n->set_osr_link(osr_nmethods_head());
  set_osr_nmethods_head(n);
  if (TieredCompilation) {
    Method* m = n->method();
    m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level()));
  }
  OsrList_lock->unlock();
  if (TieredCompilation) {
    for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) {
      nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true);
      if (inv != NULL && inv->is_in_use()) {
        inv->make_not_entrant();
      }
    }
  }
}
void InstanceKlass::remove_osr_nmethod(nmethod* n) {
  OsrList_lock->lock_without_safepoint_check();
  assert(n->is_osr_method(), "wrong kind of nmethod");
  nmethod* last = NULL;
  nmethod* cur  = osr_nmethods_head();
  int max_level = CompLevel_none;  // Find the max comp level excluding n
  Method* m = n->method();
  while(cur != NULL && cur != n) {
    if (TieredCompilation && m == cur->method()) {
      max_level = MAX2(max_level, cur->comp_level());
    }
    last = cur;
    cur = cur->osr_link();
  }
  nmethod* next = NULL;
  if (cur == n) {
    next = cur->osr_link();
    if (last == NULL) {
      set_osr_nmethods_head(next);
    } else {
      last->set_osr_link(next);
    }
  }
  n->set_osr_link(NULL);
  if (TieredCompilation) {
    cur = next;
    while (cur != NULL) {
      if (m == cur->method()) {
        max_level = MAX2(max_level, cur->comp_level());
      }
      cur = cur->osr_link();
    }
    m->set_highest_osr_comp_level(max_level);
  }
  OsrList_lock->unlock();
}
int InstanceKlass::mark_osr_nmethods(const Method* m) {
  MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
  nmethod* osr = osr_nmethods_head();
  int found = 0;
  while (osr != NULL) {
    assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
    if (osr->method() == m) {
      osr->mark_for_deoptimization();
      found++;
    }
    osr = osr->osr_link();
  }
  return found;
}
nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
  OsrList_lock->lock_without_safepoint_check();
  nmethod* osr = osr_nmethods_head();
  nmethod* best = NULL;
  while (osr != NULL) {
    assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
    if (osr->method() == m &&
        (bci == InvocationEntryBci || osr->osr_entry_bci() == bci)) {
      if (match_level) {
        if (osr->comp_level() == comp_level) {
          OsrList_lock->unlock();
          return osr;
        }
      } else {
        if (best == NULL || (osr->comp_level() > best->comp_level())) {
          if (osr->comp_level() == CompLevel_highest_tier) {
            OsrList_lock->unlock();
            return osr;
          }
          best = osr;
        }
      }
    }
    osr = osr->osr_link();
  }
  OsrList_lock->unlock();
  assert(match_level == false || best == NULL, "shouldn't pick up anything if match_level is set");
  if (best != NULL && best->comp_level() >= comp_level) {
    return best;
  }
  return NULL;
}
oop InstanceKlass::add_member_name(Handle mem_name, bool intern) {
  jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
  MutexLocker ml(MemberNameTable_lock);
  DEBUG_ONLY(No_Safepoint_Verifier nsv);
  Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name());
  if (method->is_obsolete()) {
    return NULL;
  } else if (method->is_old()) {
    java_lang_invoke_MemberName::set_vmtarget(mem_name(), method_with_idnum(method->method_idnum()));
  }
  if (_member_names == NULL) {
    _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
  }
  if (intern) {
    return _member_names->find_or_add_member_name(mem_name_wref);
  } else {
    return _member_names->add_member_name(mem_name_wref);
  }
}
#ifndef PRODUCT
#define BULLET  " - "
static const char* state_names[] = {
  "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
};
static void print_vtable(intptr_t* start, int len, outputStream* st) {
  for (int i = 0; i < len; i++) {
    intptr_t e = start[i];
    st->print("%d : " INTPTR_FORMAT, i, e);
    if (e != 0 && ((Metadata*)e)->is_metaspace_object()) {
      st->print(" ");
      ((Metadata*)e)->print_value_on(st);
    }
    st->cr();
  }
}
void InstanceKlass::print_on(outputStream* st) const {
  assert(is_klass(), "must be klass");
  Klass::print_on(st);
  st->print(BULLET"instance size:     %d", size_helper());                        st->cr();
  st->print(BULLET"klass size:        %d", size());                               st->cr();
  st->print(BULLET"access:            "); access_flags().print_on(st);            st->cr();
  st->print(BULLET"state:             "); st->print_cr("%s", state_names[_init_state]);
  st->print(BULLET"name:              "); name()->print_value_on(st);             st->cr();
  st->print(BULLET"super:             "); super()->print_value_on_maybe_null(st); st->cr();
  st->print(BULLET"sub:               ");
  Klass* sub = subklass();
  int n;
  for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) {
    if (n < MaxSubklassPrintSize) {
      sub->print_value_on(st);
      st->print("   ");
    }
  }
  if (n >= MaxSubklassPrintSize) st->print("(%d more klasses...)", n - MaxSubklassPrintSize);
  st->cr();
  if (is_interface()) {
    st->print_cr(BULLET"nof implementors:  %d", nof_implementors());
    if (nof_implementors() == 1) {
      st->print_cr(BULLET"implementor:    ");
      st->print("   ");
      implementor()->print_value_on(st);
      st->cr();
    }
  }
  st->print(BULLET"arrays:            "); array_klasses()->print_value_on_maybe_null(st); st->cr();
  st->print(BULLET"methods:           "); methods()->print_value_on(st);                  st->cr();
  if (Verbose || WizardMode) {
    Array<Method*>* method_array = methods();
    for (int i = 0; i < method_array->length(); i++) {
      st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
    }
  }
  st->print(BULLET"method ordering:   "); method_ordering()->print_value_on(st);      st->cr();
  st->print(BULLET"default_methods:   "); default_methods()->print_value_on(st);      st->cr();
  if (Verbose && default_methods() != NULL) {
    Array<Method*>* method_array = default_methods();
    for (int i = 0; i < method_array->length(); i++) {
      st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
    }
  }
  if (default_vtable_indices() != NULL) {
    st->print(BULLET"default vtable indices:   "); default_vtable_indices()->print_value_on(st);       st->cr();
  }
  st->print(BULLET"local interfaces:  "); local_interfaces()->print_value_on(st);      st->cr();
  st->print(BULLET"trans. interfaces: "); transitive_interfaces()->print_value_on(st); st->cr();
  st->print(BULLET"constants:         "); constants()->print_value_on(st);         st->cr();
  if (class_loader_data() != NULL) {
    st->print(BULLET"class loader data:  ");
    class_loader_data()->print_value_on(st);
    st->cr();
  }
  st->print(BULLET"host class:        "); host_klass()->print_value_on_maybe_null(st); st->cr();
  if (source_file_name() != NULL) {
    st->print(BULLET"source file:       ");
    source_file_name()->print_value_on(st);
    st->cr();
  }
  if (source_debug_extension() != NULL) {
    st->print(BULLET"source debug extension:       ");
    st->print("%s", source_debug_extension());
    st->cr();
  }
  st->print(BULLET"class annotations:       "); class_annotations()->print_value_on(st); st->cr();
  st->print(BULLET"class type annotations:  "); class_type_annotations()->print_value_on(st); st->cr();
  st->print(BULLET"field annotations:       "); fields_annotations()->print_value_on(st); st->cr();
  st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
  {
    bool have_pv = false;
    for (InstanceKlass* pv_node = _previous_versions;
         pv_node != NULL;
         pv_node = pv_node->previous_versions()) {
      if (!have_pv)
        st->print(BULLET"previous version:  ");
      have_pv = true;
      pv_node->constants()->print_value_on(st);
    }
    if (have_pv) st->cr();
  }
  if (generic_signature() != NULL) {
    st->print(BULLET"generic signature: ");
    generic_signature()->print_value_on(st);
    st->cr();
  }
  st->print(BULLET"inner classes:     "); inner_classes()->print_value_on(st);     st->cr();
  st->print(BULLET"java mirror:       "); java_mirror()->print_value_on(st);       st->cr();
  st->print(BULLET"vtable length      %d  (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable());  st->cr();
  if (vtable_length() > 0 && (Verbose || WizardMode))  print_vtable(start_of_vtable(), vtable_length(), st);
  st->print(BULLET"itable length      %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr();
  if (itable_length() > 0 && (Verbose || WizardMode))  print_vtable(start_of_itable(), itable_length(), st);
  st->print_cr(BULLET"---- static fields (%d words):", static_field_size());
  FieldPrinter print_static_field(st);
  ((InstanceKlass*)this)->do_local_static_fields(&print_static_field);
  st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size());
  FieldPrinter print_nonstatic_field(st);
  ((InstanceKlass*)this)->do_nonstatic_fields(&print_nonstatic_field);
  st->print(BULLET"non-static oop maps: ");
  OopMapBlock* map     = start_of_nonstatic_oop_maps();
  OopMapBlock* end_map = map + nonstatic_oop_map_count();
  while (map < end_map) {
    st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->count() - 1));
    map++;
  }
  st->cr();
}
#endif //PRODUCT
void InstanceKlass::print_value_on(outputStream* st) const {
  assert(is_klass(), "must be klass");
  if (Verbose || WizardMode)  access_flags().print_on(st);
  name()->print_value_on(st);
}
#ifndef PRODUCT
void FieldPrinter::do_field(fieldDescriptor* fd) {
  _st->print(BULLET);
   if (_obj == NULL) {
     fd->print_on(_st);
     _st->cr();
   } else {
     fd->print_on_for(_st, _obj);
     _st->cr();
   }
}
void InstanceKlass::oop_print_on(oop obj, outputStream* st) {
  Klass::oop_print_on(obj, st);
  if (this == SystemDictionary::String_klass()) {
    typeArrayOop value  = java_lang_String::value(obj);
    juint        offset = java_lang_String::offset(obj);
    juint        length = java_lang_String::length(obj);
    if (value != NULL &&
        value->is_typeArray() &&
        offset          <= (juint) value->length() &&
        offset + length <= (juint) value->length()) {
      st->print(BULLET"string: ");
      java_lang_String::print(obj, st);
      st->cr();
      if (!WizardMode)  return;  // that is enough
    }
  }
  st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj));
  FieldPrinter print_field(st, obj);
  do_nonstatic_fields(&print_field);
  if (this == SystemDictionary::Class_klass()) {
    st->print(BULLET"signature: ");
    java_lang_Class::print_signature(obj, st);
    st->cr();
    Klass* mirrored_klass = java_lang_Class::as_Klass(obj);
    st->print(BULLET"fake entry for mirror: ");
    mirrored_klass->print_value_on_maybe_null(st);
    st->cr();
    Klass* array_klass = java_lang_Class::array_klass(obj);
    st->print(BULLET"fake entry for array: ");
    array_klass->print_value_on_maybe_null(st);
    st->cr();
    st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
    st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
    Klass* real_klass = java_lang_Class::as_Klass(obj);
    if (real_klass != NULL && real_klass->oop_is_instance()) {
      InstanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
    }
  } else if (this == SystemDictionary::MethodType_klass()) {
    st->print(BULLET"signature: ");
    java_lang_invoke_MethodType::print_signature(obj, st);
    st->cr();
  }
}
#endif //PRODUCT
void InstanceKlass::oop_print_value_on(oop obj, outputStream* st) {
  st->print("a ");
  name()->print_value_on(st);
  obj->print_address_on(st);
  if (this == SystemDictionary::String_klass()
      && java_lang_String::value(obj) != NULL) {
    ResourceMark rm;
    int len = java_lang_String::length(obj);
    int plen = (len < 24 ? len : 12);
    char* str = java_lang_String::as_utf8_string(obj, 0, plen);
    st->print(" = \"%s\"", str);
    if (len > plen)
      st->print("...[%d]", len);
  } else if (this == SystemDictionary::Class_klass()) {
    Klass* k = java_lang_Class::as_Klass(obj);
    st->print(" = ");
    if (k != NULL) {
      k->print_value_on(st);
    } else {
      const char* tname = type2name(java_lang_Class::primitive_type(obj));
      st->print("%s", tname ? tname : "type?");
    }
  } else if (this == SystemDictionary::MethodType_klass()) {
    st->print(" = ");
    java_lang_invoke_MethodType::print_signature(obj, st);
  } else if (java_lang_boxing_object::is_instance(obj)) {
    st->print(" = ");
    java_lang_boxing_object::print(obj, st);
  } else if (this == SystemDictionary::LambdaForm_klass()) {
    oop vmentry = java_lang_invoke_LambdaForm::vmentry(obj);
    if (vmentry != NULL) {
      st->print(" => ");
      vmentry->print_value_on(st);
    }
  } else if (this == SystemDictionary::MemberName_klass()) {
    Metadata* vmtarget = java_lang_invoke_MemberName::vmtarget(obj);
    if (vmtarget != NULL) {
      st->print(" = ");
      vmtarget->print_value_on(st);
    } else {
      java_lang_invoke_MemberName::clazz(obj)->print_value_on(st);
      st->print(".");
      java_lang_invoke_MemberName::name(obj)->print_value_on(st);
    }
  }
}
const char* InstanceKlass::internal_name() const {
  return external_name();
}
#if INCLUDE_SERVICES
void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
  Klass::collect_statistics(sz);
  sz->_inst_size  = HeapWordSize * size_helper();
  sz->_vtab_bytes = HeapWordSize * align_object_offset(vtable_length());
  sz->_itab_bytes = HeapWordSize * align_object_offset(itable_length());
  sz->_nonstatic_oopmap_bytes = HeapWordSize *
        ((is_interface() || is_anonymous()) ?
         align_object_offset(nonstatic_oop_map_size()) :
         nonstatic_oop_map_size());
  int n = 0;
  n += (sz->_methods_array_bytes         = sz->count_array(methods()));
  n += (sz->_method_ordering_bytes       = sz->count_array(method_ordering()));
  n += (sz->_local_interfaces_bytes      = sz->count_array(local_interfaces()));
  n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
  n += (sz->_fields_bytes                = sz->count_array(fields()));
  n += (sz->_inner_classes_bytes         = sz->count_array(inner_classes()));
  sz->_ro_bytes += n;
  const ConstantPool* cp = constants();
  if (cp) {
    cp->collect_statistics(sz);
  }
  const Annotations* anno = annotations();
  if (anno) {
    anno->collect_statistics(sz);
  }
  const Array<Method*>* methods_array = methods();
  if (methods()) {
    for (int i = 0; i < methods_array->length(); i++) {
      Method* method = methods_array->at(i);
      if (method) {
        sz->_method_count ++;
        method->collect_statistics(sz);
      }
    }
  }
}
#endif // INCLUDE_SERVICES
class VerifyFieldClosure: public OopClosure {
 protected:
  template <class T> void do_oop_work(T* p) {
    oop obj = oopDesc::load_decode_heap_oop(p);
    if (!obj->is_oop_or_null()) {
      tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p, (address)obj);
      Universe::print();
      guarantee(false, "boom");
    }
  }
 public:
  virtual void do_oop(oop* p)       { VerifyFieldClosure::do_oop_work(p); }
  virtual void do_oop(narrowOop* p) { VerifyFieldClosure::do_oop_work(p); }
};
void InstanceKlass::verify_on(outputStream* st) {
#ifndef PRODUCT
  if (_verify_count == Universe::verify_count()) return;
  _verify_count = Universe::verify_count();
#endif
  Klass::verify_on(st);
  guarantee(class_loader_data()->contains_klass(this),
            "this class isn't found in class loader data");
  if (is_linked()) {
    ResourceMark rm;
    vtable()->verify(st);
  }
  if (subklass_oop() != NULL) {
    guarantee(subklass_oop()->is_klass(), "should be klass");
  }
  Klass* super = this->super();
  Klass* sib = next_sibling();
  if (sib != NULL) {
    if (sib == this) {
      fatal(err_msg("subclass points to itself " PTR_FORMAT, sib));
    }
    guarantee(sib->is_klass(), "should be klass");
    guarantee(sib->super() == super, "siblings should have same superklass");
  }
  Klass* im = implementor();
  if (im != NULL) {
    guarantee(is_interface(), "only interfaces should have implementor set");
    guarantee(im->is_klass(), "should be klass");
    guarantee(!im->is_interface() || im == this,
      "implementors cannot be interfaces");
  }
  if (local_interfaces()) {
    Array<Klass*>* local_interfaces = this->local_interfaces();
    for (int j = 0; j < local_interfaces->length(); j++) {
      Klass* e = local_interfaces->at(j);
      guarantee(e->is_klass() && e->is_interface(), "invalid local interface");
    }
  }
  if (transitive_interfaces() != NULL) {
    Array<Klass*>* transitive_interfaces = this->transitive_interfaces();
    for (int j = 0; j < transitive_interfaces->length(); j++) {
      Klass* e = transitive_interfaces->at(j);
      guarantee(e->is_klass() && e->is_interface(), "invalid transitive interface");
    }
  }
  if (methods() != NULL) {
    Array<Method*>* methods = this->methods();
    for (int j = 0; j < methods->length(); j++) {
      guarantee(methods->at(j)->is_method(), "non-method in methods array");
    }
    for (int j = 0; j < methods->length() - 1; j++) {
      Method* m1 = methods->at(j);
      Method* m2 = methods->at(j + 1);
      guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly");
    }
  }
  if (method_ordering() != NULL) {
    Array<int>* method_ordering = this->method_ordering();
    int length = method_ordering->length();
    if (JvmtiExport::can_maintain_original_method_order() ||
        ((UseSharedSpaces || DumpSharedSpaces) && length != 0)) {
      guarantee(length == methods()->length(), "invalid method ordering length");
      jlong sum = 0;
      for (int j = 0; j < length; j++) {
        int original_index = method_ordering->at(j);
        guarantee(original_index >= 0, "invalid method ordering index");
        guarantee(original_index < length, "invalid method ordering index");
        sum += original_index;
      }
      guarantee(sum == ((jlong)length*(length-1))/2, "invalid method ordering sum");
    } else {
      guarantee(length == 0, "invalid method ordering length");
    }
  }
  if (default_methods() != NULL) {
    Array<Method*>* methods = this->default_methods();
    for (int j = 0; j < methods->length(); j++) {
      guarantee(methods->at(j)->is_method(), "non-method in methods array");
    }
    for (int j = 0; j < methods->length() - 1; j++) {
      Method* m1 = methods->at(j);
      Method* m2 = methods->at(j + 1);
      guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly");
    }
  }
  if (jni_ids() != NULL) {
    jni_ids()->verify(this);
  }
  if (array_klasses() != NULL) {
    guarantee(array_klasses()->is_klass(), "should be klass");
  }
  if (constants() != NULL) {
    guarantee(constants()->is_constantPool(), "should be constant pool");
  }
  const Klass* host = host_klass();
  if (host != NULL) {
    guarantee(host->is_klass(), "should be klass");
  }
}
void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
  Klass::oop_verify_on(obj, st);
  VerifyFieldClosure blk;
  obj->oop_iterate_no_header(&blk);
}
JNIid::JNIid(Klass* holder, int offset, JNIid* next) {
  _holder = holder;
  _offset = offset;
  _next = next;
  debug_only(_is_static_field_id = false;)
}
JNIid* JNIid::find(int offset) {
  JNIid* current = this;
  while (current != NULL) {
    if (current->offset() == offset) return current;
    current = current->next();
  }
  return NULL;
}
void JNIid::deallocate(JNIid* current) {
  while (current != NULL) {
    JNIid* next = current->next();
    delete current;
    current = next;
  }
}
void JNIid::verify(Klass* holder) {
  int first_field_offset  = InstanceMirrorKlass::offset_of_static_fields();
  int end_field_offset;
  end_field_offset = first_field_offset + (InstanceKlass::cast(holder)->static_field_size() * wordSize);
  JNIid* current = this;
  while (current != NULL) {
    guarantee(current->holder() == holder, "Invalid klass in JNIid");
#ifdef ASSERT
    int o = current->offset();
    if (current->is_static_field_id()) {
      guarantee(o >= first_field_offset  && o < end_field_offset,  "Invalid static field offset in JNIid");
    }
#endif
    current = current->next();
  }
}
#ifdef ASSERT
void InstanceKlass::set_init_state(ClassState state) {
  bool good_state = is_shared() ? (_init_state <= state)
                                               : (_init_state < state);
  assert(good_state || state == allocated, "illegal state transition");
  assert(_init_thread == NULL, "should be cleared before state change");
  _init_state = (u1)state;
}
#endif
void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
  if (ik->previous_versions() != NULL) {
    int deleted_count = 0;    // leave debugging breadcrumbs
    int live_count = 0;
    ClassLoaderData* loader_data = ik->class_loader_data();
    assert(loader_data != NULL, "should never be null");
    RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));
    InstanceKlass* pv_node = ik->previous_versions();
    InstanceKlass* last = ik;
    int version = 0;
    for (; pv_node != NULL; ) {
      ConstantPool* pvcp = pv_node->constants();
      assert(pvcp != NULL, "cp ref was unexpectedly cleared");
      if (!pvcp->on_stack()) {
        pv_node = pv_node->previous_versions();
        last->link_previous_versions(pv_node);
        deleted_count++;
        version++;
        continue;
      } else {
        RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive",
                              pv_node));
        assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
        guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
        live_count++;
      }
      Array<Method*>* method_refs = pv_node->methods();
      if (method_refs != NULL) {
        RC_TRACE(0x00000200, ("purge: previous methods length=%d",
          method_refs->length()));
        for (int j = 0; j < method_refs->length(); j++) {
          Method* method = method_refs->at(j);
          if (!method->on_stack()) {
            if (method->is_running_emcp()) {
              method->set_running_emcp(false);
            }
          } else {
            assert (method->is_obsolete() || method->is_running_emcp(),
                    "emcp method cannot run after emcp bit is cleared");
            RC_TRACE(0x00000200,
              ("purge: %s(%s): prev method @%d in version @%d is alive",
              method->name()->as_C_string(),
              method->signature()->as_C_string(), j, version));
            if (method->method_data() != NULL) {
              method->method_data()->clean_weak_method_links();
            }
          }
        }
      }
      last = pv_node;
      pv_node = pv_node->previous_versions();
      version++;
    }
    RC_TRACE(0x00000200,
      ("purge: previous version stats: live=%d, deleted=%d", live_count,
      deleted_count));
  }
  Array<Method*>* methods = ik->methods();
  int num_methods = methods->length();
  for (int index2 = 0; index2 < num_methods; ++index2) {
    if (methods->at(index2)->method_data() != NULL) {
      methods->at(index2)->method_data()->clean_weak_method_links();
    }
  }
}
void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods,
                                                int emcp_method_count) {
  int obsolete_method_count = old_methods->length() - emcp_method_count;
  if (emcp_method_count != 0 && obsolete_method_count != 0 &&
      _previous_versions != NULL) {
    int local_count = 0;
    for (int i = 0; i < old_methods->length(); i++) {
      Method* old_method = old_methods->at(i);
      if (old_method->is_obsolete()) {
        Symbol* m_name = old_method->name();
        Symbol* m_signature = old_method->signature();
        int j = 0;
        for (InstanceKlass* prev_version = _previous_versions;
             prev_version != NULL;
             prev_version = prev_version->previous_versions(), j++) {
          Array<Method*>* method_refs = prev_version->methods();
          for (int k = 0; k < method_refs->length(); k++) {
            Method* method = method_refs->at(k);
            if (!method->is_obsolete() &&
                method->name() == m_name &&
                method->signature() == m_signature) {
              RC_TRACE(0x00000400,
                ("add: %s(%s): flush obsolete method @%d in version @%d",
                m_name->as_C_string(), m_signature->as_C_string(), k, j));
              method->set_is_obsolete();
              break;
            }
          }
        }
        if (++local_count >= obsolete_method_count) {
          break;
        }
      }
    }
  }
}
void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class,
                                         int emcp_method_count) {
  assert(Thread::current()->is_VM_thread(),
         "only VMThread can add previous versions");
  RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d",
    scratch_class->external_name(), emcp_method_count));
  purge_previous_versions(this);
  Array<Method*>* old_methods = scratch_class->methods();
  mark_newly_obsolete_methods(old_methods, emcp_method_count);
  ConstantPool* cp_ref = scratch_class->constants();
  if (!cp_ref->on_stack()) {
    RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running"));
    return;
  }
  if (emcp_method_count != 0) {
    for (int i = 0; i < old_methods->length(); i++) {
      Method* old_method = old_methods->at(i);
      if (!old_method->is_obsolete() && old_method->on_stack()) {
        old_method->set_running_emcp(true);
        RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT,
                              old_method->name_and_sig_as_C_string(), old_method));
      } else if (!old_method->is_obsolete()) {
        RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT,
                              old_method->name_and_sig_as_C_string(), old_method));
      }
    }
  }
  RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack"));
  assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
  scratch_class->link_previous_versions(previous_versions());
  link_previous_versions(scratch_class());
} // end add_previous_version()
Method* InstanceKlass::method_with_idnum(int idnum) {
  Method* m = NULL;
  if (idnum < methods()->length()) {
    m = methods()->at(idnum);
  }
  if (m == NULL || m->method_idnum() != idnum) {
    for (int index = 0; index < methods()->length(); ++index) {
      m = methods()->at(index);
      if (m->method_idnum() == idnum) {
        return m;
      }
    }
    return NULL;
  }
  return m;
}
Method* InstanceKlass::method_with_orig_idnum(int idnum) {
  if (idnum >= methods()->length()) {
    return NULL;
  }
  Method* m = methods()->at(idnum);
  if (m != NULL && m->orig_method_idnum() == idnum) {
    return m;
  }
  for (int index = 0; index < methods()->length(); ++index) {
    m = methods()->at(index);
    if (m->orig_method_idnum() == idnum) {
      return m;
    }
  }
  return NULL;
}
Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) {
  InstanceKlass* holder = get_klass_version(version);
  if (holder == NULL) {
    return NULL; // The version of klass is gone, no method is found
  }
  Method* method = holder->method_with_orig_idnum(idnum);
  return method;
}
jint InstanceKlass::get_cached_class_file_len() {
  return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
}
unsigned char * InstanceKlass::get_cached_class_file_bytes() {
  return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
}
C:\hotspot-69087d08d473\src\share\vm/oops/instanceKlass.hpp
#ifndef SHARE_VM_OOPS_INSTANCEKLASS_HPP
#define SHARE_VM_OOPS_INSTANCEKLASS_HPP
#include "classfile/classLoaderData.hpp"
#include "memory/referenceType.hpp"
#include "oops/annotations.hpp"
#include "oops/constMethod.hpp"
#include "oops/fieldInfo.hpp"
#include "oops/instanceOop.hpp"
#include "oops/klassVtable.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handles.hpp"
#include "runtime/os.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_JFR
#include "jfr/support/jfrKlassExtension.hpp"
#endif
class SuperTypeClosure;
class JNIid;
class jniIdMapBase;
class BreakpointInfo;
class fieldDescriptor;
class DepChange;
class nmethodBucket;
class JvmtiCachedClassFieldMap;
class MemberNameTable;
class FieldClosure: public StackObj {
public:
  virtual void do_field(fieldDescriptor* fd) = 0;
};
#ifndef PRODUCT
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
class OopMapBlock VALUE_OBJ_CLASS_SPEC {
 public:
  int offset() const          { return _offset; }
  void set_offset(int offset) { _offset = offset; }
  uint count() const         { return _count; }
  void set_count(uint count) { _count = count; }
  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;
 protected:
  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 InstanceKlass* 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,
                                          bool is_anonymous,
                                          TRAPS);
  InstanceKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
  enum ClassState {
    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)
    being_initialized,                  // currently running class initializer
    fully_initialized,                  // initialized (successfull final state)
    initialization_error                // error happened during initialization
  };
  static int number_of_instance_classes() { return _total_instanceKlass_count; }
 private:
  static volatile int _total_instanceKlass_count;
 protected:
  Annotations*    _annotations;
  Klass*          _array_klasses;
  ConstantPool* _constants;
  Array<jushort>* _inner_classes;
  char*           _source_debug_extension;
  Symbol*         _array_name;
  int             _nonstatic_field_size;
  int             _static_field_size;    // number words used by static fields (oop and non-oop) in this klass
  u2              _generic_signature_index;
  u2              _source_file_name_index;
  u2              _static_oop_field_count;// number of static oop fields in this klass
  u2              _java_fields_count;    // The number of declared Java fields
  int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
  bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
  bool            _is_being_redefined;   // used for locking redefinition
  bool            _has_unloaded_dependent;
  enum {
    _misc_rewritten                = 1 << 0, // methods rewritten.
    _misc_has_nonstatic_fields     = 1 << 1, // for sizing with UseCompressedOops
    _misc_should_verify_class      = 1 << 2, // allow caching of preverification
    _misc_is_anonymous             = 1 << 3, // has embedded _host_klass field
    _misc_is_contended             = 1 << 4, // marked with contended annotation
    _misc_has_default_methods      = 1 << 5, // class/superclass/implemented interfaces has default methods
    _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access)
    _misc_has_been_redefined       = 1 << 7  // class has been redefined
  };
  u2              _misc_flags;
  u2              _minor_version;        // minor version number of class file
  u2              _major_version;        // major version number of class file
  Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recursive initialization)
  int             _vtable_len;           // length of Java vtable (in words)
  int             _itable_len;           // length of Java itable (in words)
  OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
  MemberNameTable* _member_names;        // Member names
  JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
  jmethodID*      _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
  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 Method*
  InstanceKlass* _previous_versions;
  JvmtiCachedClassFileData* _cached_class_file;
  volatile u2     _idnum_allocated_count;         // JNI/JVMTI: increments with the addition of methods, old ids don't change
  u1              _init_state;                    // state of class
  u1              _reference_type;                // reference type
  JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map;  // JVMTI: used during heap iteration
  NOT_PRODUCT(int _verify_count;)  // to avoid redundant verifies
  Array<Method*>* _methods;
  Array<Method*>* _default_methods;
  Array<Klass*>* _local_interfaces;
  Array<Klass*>* _transitive_interfaces;
  Array<int>*     _method_ordering;
  Array<int>*     _default_vtable_indices;
  Array<u2>*      _fields;
  friend class SystemDictionary;
 public:
  bool has_nonstatic_fields() const        {
    return (_misc_flags & _misc_has_nonstatic_fields) != 0;
  }
  void set_has_nonstatic_fields(bool b)    {
    if (b) {
      _misc_flags |= _misc_has_nonstatic_fields;
    } else {
      _misc_flags &= ~_misc_has_nonstatic_fields;
    }
  }
  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; }
  void set_static_field_size(int size)     { _static_field_size = size; }
  int static_oop_field_count() const       { return (int)_static_oop_field_count; }
  void set_static_oop_field_count(u2 size) { _static_oop_field_count = size; }
  int  vtable_length() const               { return _vtable_len; }
  void set_vtable_length(int len)          { _vtable_len = len; }
  int  itable_length() const               { return _itable_len; }
  void set_itable_length(int len)          { _itable_len = len; }
  Klass* array_klasses() const             { return _array_klasses; }
  void set_array_klasses(Klass* k)         { _array_klasses = k; }
  Array<Method*>* methods() const          { return _methods; }
  void set_methods(Array<Method*>* a)      { _methods = a; }
  Method* method_with_idnum(int idnum);
  Method* method_with_orig_idnum(int idnum);
  Method* method_with_orig_idnum(int idnum, int version);
  Array<int>* method_ordering() const     { return _method_ordering; }
  void set_method_ordering(Array<int>* m) { _method_ordering = m; }
  void copy_method_ordering(intArray* m, TRAPS);
  Array<Method*>* default_methods() const  { return _default_methods; }
  void set_default_methods(Array<Method*>* a) { _default_methods = a; }
  Array<int>* default_vtable_indices() const { return _default_vtable_indices; }
  void set_default_vtable_indices(Array<int>* v) { _default_vtable_indices = v; }
  Array<int>* create_new_default_vtable_indices(int len, TRAPS);
  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;
  FieldInfo* field(int index) const { return FieldInfo::from_field_array(_fields, index); }
 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()); }
  int java_fields_count() const           { return (int)_java_fields_count; }
  Array<u2>* fields() const            { return _fields; }
  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;
  }
  Array<u2>* inner_classes() const       { return _inner_classes; }
  void set_inner_classes(Array<u2>* f)   { _inner_classes = f; }
  enum InnerClassAttributeOffset {
    inner_class_inner_class_info_offset = 0,
    inner_class_outer_class_info_offset = 1,
    inner_class_inner_name_offset = 2,
    inner_class_access_flags_offset = 3,
    inner_class_next_offset = 4
  };
  enum EnclosingMethodAttributeOffset {
    enclosing_method_class_index_offset = 0,
    enclosing_method_method_index_offset = 1,
    enclosing_method_attribute_size = 2
  };
  bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
  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);
  Klass* compute_enclosing_class(bool* inner_is_member, TRAPS) {
    instanceKlassHandle self(THREAD, this);
    return compute_enclosing_class_impl(self, inner_is_member, THREAD);
  }
  static Klass* compute_enclosing_class_impl(instanceKlassHandle self,
                                               bool* inner_is_member, TRAPS);
  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,
                                          Klass* class2, TRAPS);
  bool is_loaded() const                   { return _init_state >= loaded; }
  bool is_linked() const                   { return _init_state >= linked; }
  bool is_initialized() const              { return _init_state == fully_initialized; }
  bool is_not_initialized() const          { return _init_state <  being_initialized; }
  bool is_being_initialized() const        { return _init_state == being_initialized; }
  bool is_in_error_state() const           { return _init_state == initialization_error; }
  bool is_reentrant_initialization(Thread *thread)  { return thread == _init_thread; }
  ClassState  init_state()                 { return (ClassState)_init_state; }
  bool is_rewritten() const                { return (_misc_flags & _misc_rewritten) != 0; }
  bool should_verify_class() const         {
    return (_misc_flags & _misc_should_verify_class) != 0;
  }
  void set_should_verify_class(bool value) {
    if (value) {
      _misc_flags |= _misc_should_verify_class;
    } else {
      _misc_flags &= ~_misc_should_verify_class;
    }
  }
  bool is_marked_dependent() const         { return _is_marked_dependent; }
  void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
  bool has_unloaded_dependent() const         { return _has_unloaded_dependent; }
  void set_has_unloaded_dependent(bool value) { _has_unloaded_dependent = value; }
  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
  void unlink_class();
  void rewrite_class(TRAPS);
  void link_methods(TRAPS);
  Method* class_initializer();
  void eager_initialize(Thread *thread);
  ReferenceType reference_type() const     { return (ReferenceType)_reference_type; }
  void set_reference_type(ReferenceType t) {
    assert(t == (u1)t, "overflow");
    _reference_type = (u1)t;
  }
  static ByteSize reference_type_offset() { return in_ByteSize(offset_of(InstanceKlass, _reference_type)); }
  bool find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
  Klass* find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
  Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
  Klass* find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const;
  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;
  Method* find_method(Symbol* name, Symbol* signature) const;
  static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
  Method* find_instance_method(Symbol* name, Symbol* signature,
                               PrivateLookupMode private_mode);
  static Method* find_instance_method(Array<Method*>* methods,
                                      Symbol* name, Symbol* signature,
                                      PrivateLookupMode private_mode);
  Method* find_local_method(Symbol* name, Symbol* signature,
                           OverpassLookupMode overpass_mode,
                           StaticLookupMode static_mode,
                           PrivateLookupMode private_mode) const;
  static Method* find_local_method(Array<Method*>* methods,
                           Symbol* name, Symbol* signature,
                           OverpassLookupMode overpass_mode,
                           StaticLookupMode static_mode,
                           PrivateLookupMode private_mode);
  static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private);
  static int find_method_index(Array<Method*>* methods,
                               Symbol* name, Symbol* signature,
                               OverpassLookupMode overpass_mode,
                               StaticLookupMode static_mode,
                               PrivateLookupMode private_mode);
  Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
  Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, DefaultsLookupMode defaults_mode) const;
  Method* lookup_method_in_ordered_interfaces(Symbol* name, Symbol* signature) const;
  int find_method_by_name(Symbol* name, int* end);
  static int find_method_by_name(Array<Method*>* methods, Symbol* name, int* end);
  ConstantPool* constants() const        { return _constants; }
  void set_constants(ConstantPool* c)    { _constants = c; }
  oop protection_domain() const;
  objArrayOop signers() const;
  Klass* host_klass() const              {
    Klass** hk = (Klass**)adr_host_klass();
    if (hk == NULL) {
      assert(!is_anonymous(), "Anonymous classes have host klasses");
      return NULL;
    } else {
      assert(*hk != NULL, "host klass should always be set if the address is not null");
      assert(is_anonymous(), "Only anonymous classes have host klasses");
      return *hk;
    }
  }
  void set_host_klass(Klass* host)            {
    assert(is_anonymous(), "not anonymous");
    Klass** addr = (Klass**)adr_host_klass();
    assert(addr != NULL, "no reversed space");
    if (addr != NULL) {
    }
  }
  bool has_host_klass() const              {
    return adr_host_klass() != NULL;
  }
  bool is_anonymous() const                {
    return (_misc_flags & _misc_is_anonymous) != 0;
  }
  void set_is_anonymous(bool value)        {
    if (value) {
      _misc_flags |= _misc_is_anonymous;
    } else {
      _misc_flags &= ~_misc_is_anonymous;
    }
  }
  oop klass_holder() const {
    return is_anonymous() ? java_mirror() : class_loader();
  }
  bool is_contended() const                {
    return (_misc_flags & _misc_is_contended) != 0;
  }
  void set_is_contended(bool value)        {
    if (value) {
      _misc_flags |= _misc_is_contended;
    } else {
      _misc_flags &= ~_misc_is_contended;
    }
  }
  Symbol* source_file_name() const               {
    return (_source_file_name_index == 0) ?
      (Symbol*)NULL : _constants->symbol_at(_source_file_name_index);
  }
  u2 source_file_name_index() const              {
    return _source_file_name_index;
  }
  void set_source_file_name_index(u2 sourcefile_index) {
    _source_file_name_index = sourcefile_index;
  }
  u2 minor_version() const                 { return _minor_version; }
  void set_minor_version(u2 minor_version) { _minor_version = minor_version; }
  u2 major_version() const                 { return _major_version; }
  void set_major_version(u2 major_version) { _major_version = major_version; }
  char* source_debug_extension() const     { return _source_debug_extension; }
  void set_source_debug_extension(char* array, int length);
  Symbol* array_name()                     { return _array_name; }
  void set_array_name(Symbol* name)        { assert(_array_name == NULL  || name == NULL, "name already created"); _array_name = name; }
  static int nonstatic_oop_map_size(unsigned int oop_map_count) {
    return oop_map_count * OopMapBlock::size_in_words();
  }
  unsigned int nonstatic_oop_map_count() const {
    return _nonstatic_oop_map_size / OopMapBlock::size_in_words();
  }
  int nonstatic_oop_map_size() const { return _nonstatic_oop_map_size; }
  void set_nonstatic_oop_map_size(int words) {
    _nonstatic_oop_map_size = words;
  }
  bool is_being_redefined() const          { return _is_being_redefined; }
  void set_is_being_redefined(bool value)  { _is_being_redefined = value; }
  void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
  InstanceKlass* previous_versions() const { return _previous_versions; }
  bool has_been_redefined() const {
    return (_misc_flags & _misc_has_been_redefined) != 0;
  }
  void set_has_been_redefined() {
    _misc_flags |= _misc_has_been_redefined;
  }
  void init_previous_versions() {
    _previous_versions = NULL;
  }
  InstanceKlass* get_klass_version(int version) {
    for (InstanceKlass* ik = this; ik != NULL; ik = ik->previous_versions()) {
      if (ik->constants()->version() == version) {
        return ik;
      }
    }
    return NULL;
  }
  static void purge_previous_versions(InstanceKlass* ik);
  void set_cached_class_file(JvmtiCachedClassFileData *data) {
    _cached_class_file = data;
  }
  JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
  jint get_cached_class_file_len();
  unsigned char * get_cached_class_file_bytes();
  void set_jvmti_cached_class_field_map(JvmtiCachedClassFieldMap* descriptor) {
    _jvmti_cached_class_field_map = descriptor;
  }
  JvmtiCachedClassFieldMap* jvmti_cached_class_field_map() const {
    return _jvmti_cached_class_field_map;
  }
  bool has_default_methods() const {
    return (_misc_flags & _misc_has_default_methods) != 0;
  }
  void set_has_default_methods(bool b) {
    if (b) {
      _misc_flags |= _misc_has_default_methods;
    } else {
      _misc_flags &= ~_misc_has_default_methods;
    }
  }
  bool declares_default_methods() const {
    return (_misc_flags & _misc_declares_default_methods) != 0;
  }
  void set_declares_default_methods(bool b) {
    if (b) {
      _misc_flags |= _misc_declares_default_methods;
    } else {
      _misc_flags &= ~_misc_declares_default_methods;
    }
  }
  inline u2 next_method_idnum();
  void set_initial_method_idnum(u2 value)             { _idnum_allocated_count = value; }
  Symbol* generic_signature() const                   {
    return (_generic_signature_index == 0) ?
      (Symbol*)NULL : _constants->symbol_at(_generic_signature_index);
  }
  u2 generic_signature_index() const                  {
    return _generic_signature_index;
  }
  void set_generic_signature_index(u2 sig_index)      {
    _generic_signature_index = sig_index;
  }
  u2 enclosing_method_data(int offset);
  u2 enclosing_method_class_index() {
    return enclosing_method_data(enclosing_method_class_index_offset);
  }
  u2 enclosing_method_method_index() {
    return enclosing_method_data(enclosing_method_method_index_offset);
  }
  void set_enclosing_method_indices(u2 class_index,
                                    u2 method_index);
  static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
                     methodHandle method_h);
  static jmethodID get_jmethod_id_fetch_or_update(instanceKlassHandle ik_h,
                     size_t idnum, jmethodID new_id, jmethodID* new_jmeths,
                     jmethodID* to_dealloc_id_p,
                     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(Method* method);
  Annotations* annotations() const          { return _annotations; }
  void set_annotations(Annotations* anno)   { _annotations = anno; }
  AnnotationArray* class_annotations() const {
    return (_annotations != NULL) ? _annotations->class_annotations() : NULL;
  }
  Array<AnnotationArray*>* fields_annotations() const {
    return (_annotations != NULL) ? _annotations->fields_annotations() : NULL;
  }
  AnnotationArray* class_type_annotations() const {
    return (_annotations != NULL) ? _annotations->class_type_annotations() : NULL;
  }
  Array<AnnotationArray*>* fields_type_annotations() const {
    return (_annotations != NULL) ? _annotations->fields_type_annotations() : NULL;
  }
  instanceOop allocate_instance(TRAPS);
  instanceHandle allocate_instance_handle(TRAPS)      { return instanceHandle(THREAD, allocate_instance(THREAD)); }
  objArrayOop allocate_objArray(int n, int length, TRAPS);
  static instanceOop register_finalizer(instanceOop i, TRAPS);
  virtual void check_valid_for_instantiation(bool throwError, TRAPS);
  void call_class_initializer(TRAPS);
  void set_initialization_state_and_notify(ClassState state, TRAPS);
  OopMapCache* oop_map_cache()               { return _oop_map_cache; }
  void set_oop_map_cache(OopMapCache *cache) { _oop_map_cache = cache; }
  void mask_for(methodHandle method, int bci, InterpreterOopMap* entry);
  JNIid* jni_ids()                               { return _jni_ids; }
  void set_jni_ids(JNIid* ids)                   { _jni_ids = ids; }
  JNIid* jni_id_for(int offset);
  int mark_dependent_nmethods(DepChange& changes);
  void add_dependent_nmethod(nmethod* nm);
  void remove_dependent_nmethod(nmethod* nm, bool delete_immediately);
  nmethod* osr_nmethods_head() const         { return _osr_nmethods_head; };
  void set_osr_nmethods_head(nmethod* h)     { _osr_nmethods_head = h; };
  void add_osr_nmethod(nmethod* n);
  void remove_osr_nmethod(nmethod* n);
  int mark_osr_nmethods(const Method* m);
  nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
  BreakpointInfo* breakpoints() const       { return _breakpoints; };
  void set_breakpoints(BreakpointInfo* bps) { _breakpoints = bps; };
  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)); }
  bool implements_interface(Klass* k) const;
  bool is_same_or_direct_interface(Klass* k) const;
#ifdef ASSERT
  bool has_redefined_this_or_super() const;
#endif
  Klass* implementor() const
  {
    Klass** k = adr_implementor();
    if (k == NULL) {
      return NULL;
    } else {
      return *k;
    }
  }
  void set_implementor(Klass* k) {
    assert(is_interface(), "not interface");
    Klass** addr = adr_implementor();
    assert(addr != NULL, "null addr");
    if (addr != NULL) {
    }
  }
  int  nof_implementors() const       {
    Klass* k = implementor();
    if (k == NULL) {
      return 0;
    } else if (k != this) {
      return 1;
    } else {
      return 2;
    }
  }
  void add_implementor(Klass* k);  // k is a new class that implements this interface
  void init_implementor();           // initialize
  void process_interfaces(Thread *thread);
  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;
  int oop_size(oop obj)  const             { return size_helper(); }
  bool oop_is_instance_slow() const        { return true; }
  void do_local_static_fields(FieldClosure* cl);
  void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
  void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
  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);
  bool super_types_do(SuperTypeClosure* blk);
  static InstanceKlass* cast(Klass* k) {
    assert(k == NULL || k->is_klass(), "must be");
    assert(k == NULL || k->oop_is_instance(), "cast to InstanceKlass");
    return (InstanceKlass*) k;
  }
  InstanceKlass* java_super() const {
    return (super() == NULL) ? NULL : cast(super());
  }
  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());
  }
#if INCLUDE_SERVICES
  virtual void collect_statistics(KlassSizeStats *sz) const;
#endif
  static int vtable_start_offset()    { return header_size(); }
  static int vtable_length_offset()   { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; }
  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*)this; }
  intptr_t* end_of_itable() const          { return start_of_itable() + itable_length(); }
  address static_field_addr(int offset);
  OopMapBlock* start_of_nonstatic_oop_maps() const {
    return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
  }
  Klass** end_of_nonstatic_oop_maps() const {
    return (Klass**)(start_of_nonstatic_oop_maps() +
                     nonstatic_oop_map_count());
  }
  Klass** adr_implementor() const {
    if (is_interface()) {
      return (Klass**)end_of_nonstatic_oop_maps();
    } else {
      return NULL;
    }
  };
  Klass** adr_host_klass() const {
    if (is_anonymous()) {
      Klass** adr_impl = adr_implementor();
      if (adr_impl != NULL) {
        return adr_impl + 1;
      } else {
        return end_of_nonstatic_oop_maps();
      }
    } else {
      return NULL;
    }
  }
  int size_helper() const {
    return layout_helper_to_size_helper(layout_helper());
  }
  bool can_be_fastpath_allocated() const {
    return !layout_helper_needs_slow_path(layout_helper());
  }
  klassVtable* vtable() const;        // return new klassVtable wrapper
  inline Method* method_at_vtable(int index);
  klassItable* itable() const;        // return new klassItable wrapper
  Method* method_at_itable(Klass* holder, int index, TRAPS);
#if INCLUDE_JVMTI
  void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
#endif // INCLUDE_JVMTI
  void oop_follow_contents(oop obj);
  int  oop_adjust_pointers(oop obj);
  void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
  void clean_implementors_list(BoolObjectClosure* is_alive);
  void clean_method_data(BoolObjectClosure* is_alive);
  void clean_dependent_nmethods();
  void deallocate_contents(ClassLoaderData* loader_data);
  static void deallocate_methods(ClassLoaderData* loader_data,
                                 Array<Method*>* methods);
  void static deallocate_interfaces(ClassLoaderData* loader_data,
                                    Klass* super_klass,
                                    Array<Klass*>* local_interfaces,
                                    Array<Klass*>* transitive_interfaces);
  bool on_stack() const { return _constants->on_stack(); }
  static void notify_unload_class(InstanceKlass* ik);
  static void release_C_heap_structures(InstanceKlass* ik);
  PARALLEL_GC_DECLS
  const char* signature_name() const;
  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate_v(obj, blk);
  }
  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
    return oop_oop_iterate_v_m(obj, blk, mr);
  }
#define InstanceKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)      \
  int  oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);           \
  int  oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk,        \
                                      MemRegion mr);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DECL)
#if INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
  int  oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
#endif // INCLUDE_ALL_GCS
  u2 idnum_allocated_count() const      { return _idnum_allocated_count; }
public:
  void set_in_error_state() {
    assert(DumpSharedSpaces, "only call this when dumping archive");
    _init_state = initialization_error;
  }
  bool check_sharing_error_state();
private:
#ifdef ASSERT
  void set_init_state(ClassState state);
#else
  void set_init_state(ClassState state) { _init_state = (u1)state; }
#endif
  void set_rewritten()                  { _misc_flags |= _misc_rewritten; }
  void set_init_thread(Thread *thread)  { _init_thread = thread; }
  bool idnum_can_increment() const      { return has_been_redefined(); }
  jmethodID* methods_jmethod_ids_acquire() const
         { return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids); }
  void release_set_methods_jmethod_ids(jmethodID* jmeths)
         { OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); }
public:
  oop init_lock() const;
private:
  void fence_and_clear_init_lock();
  static bool link_class_impl                           (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
  static bool verify_code                               (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
  static void initialize_impl                           (instanceKlassHandle this_oop, TRAPS);
  static void initialize_super_interfaces               (instanceKlassHandle this_oop, TRAPS);
  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 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, Handle, TRAPS), Handle, TRAPS);
  static JNIid* jni_id_for_impl                         (instanceKlassHandle this_oop, int offset);
  Klass* array_klass_impl(bool or_null, int n, TRAPS);
  Klass* array_klass_impl(bool or_null, TRAPS);
  Method* find_method_impl(Symbol* name, Symbol* signature,
                           OverpassLookupMode overpass_mode,
                           StaticLookupMode static_mode,
                           PrivateLookupMode private_mode) const;
  static Method* find_method_impl(Array<Method*>* methods,
                                  Symbol* name, Symbol* signature,
                                  OverpassLookupMode overpass_mode,
                                  StaticLookupMode static_mode,
                                  PrivateLookupMode private_mode);
  void release_C_heap_structures();
  void link_previous_versions(InstanceKlass* pv) { _previous_versions = pv; }
  void mark_newly_obsolete_methods(Array<Method*>* old_methods, int emcp_method_count);
public:
  virtual void remove_unshareable_info();
  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
  jint compute_modifier_flags(TRAPS) const;
  MemberNameTable* member_names() { return _member_names; }
  void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
  oop add_member_name(Handle member_name, bool intern);
public:
  jint jvmti_class_status() const;
 public:
#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;
  void verify_on(outputStream* st);
  void oop_verify_on(oop obj, outputStream* st);
};
inline Method* InstanceKlass::method_at_vtable(int index)  {
#ifndef PRODUCT
  assert(index >= 0, "valid vtable index");
  if (DebugVtables) {
    verify_vtable_index(index);
  }
#endif
  vtableEntry* ve = (vtableEntry*)start_of_vtable();
  return ve[index].method();
}
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++;
  }
}
class JNIid: public CHeapObj<mtClass> {
  friend class VMStructs;
 private:
  Klass*             _holder;
  JNIid*             _next;
  int                _offset;
#ifdef ASSERT
  bool               _is_static_field_id;
#endif
 public:
  Klass* holder() const           { return _holder; }
  int offset() const              { return _offset; }
  JNIid* next()                   { return _next; }
  JNIid(Klass* holder, int offset, JNIid* next);
  JNIid* find(int offset);
  bool find_local_field(fieldDescriptor* fd) {
    return InstanceKlass::cast(holder())->find_local_field_from_offset(offset(), true, fd);
  }
  static void deallocate(JNIid* id);
#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(Klass* holder);
};
class nmethodBucket: public CHeapObj<mtClass> {
  friend class VMStructs;
 private:
  nmethod*       _nmethod;
  int            _count;
  nmethodBucket* _next;
 public:
  nmethodBucket(nmethod* nmethod, nmethodBucket* next) {
    _nmethod = nmethod;
    _next = next;
    _count = 1;
  }
  int count()                             { return _count; }
  int increment()                         { _count += 1; return _count; }
  int decrement();
  nmethodBucket* next()                   { return _next; }
  void set_next(nmethodBucket* b)         { _next = b; }
  nmethod* get_nmethod()                  { return _nmethod; }
};
class InnerClassesIterator : public StackObj {
 private:
  Array<jushort>* _inner_classes;
  int _length;
  int _idx;
 public:
  InnerClassesIterator(instanceKlassHandle k) {
    _inner_classes = k->inner_classes();
    if (k->inner_classes() != NULL) {
      _length = _inner_classes->length();
      assert((_length % InstanceKlass::inner_class_next_offset == 0 ||
              _length % InstanceKlass::inner_class_next_offset == InstanceKlass::enclosing_method_attribute_size),
             "just checking");
      if (_length % InstanceKlass::inner_class_next_offset == InstanceKlass::enclosing_method_attribute_size) {
        _length -= InstanceKlass::enclosing_method_attribute_size;
      }
    } else {
      _length = 0;
    }
    _idx = 0;
  }
  int length() const {
    return _length;
  }
  void next() {
    _idx += InstanceKlass::inner_class_next_offset;
  }
  bool done() const {
    return (_idx >= _length);
  }
  u2 inner_class_info_index() const {
    return _inner_classes->at(
               _idx + InstanceKlass::inner_class_inner_class_info_offset);
  }
  void set_inner_class_info_index(u2 index) {
    _inner_classes->at_put(
               _idx + InstanceKlass::inner_class_inner_class_info_offset, index);
  }
  u2 outer_class_info_index() const {
    return _inner_classes->at(
               _idx + InstanceKlass::inner_class_outer_class_info_offset);
  }
  void set_outer_class_info_index(u2 index) {
    _inner_classes->at_put(
               _idx + InstanceKlass::inner_class_outer_class_info_offset, index);
  }
  u2 inner_name_index() const {
    return _inner_classes->at(
               _idx + InstanceKlass::inner_class_inner_name_offset);
  }
  void set_inner_name_index(u2 index) {
    _inner_classes->at_put(
               _idx + InstanceKlass::inner_class_inner_name_offset, index);
  }
  u2 inner_access_flags() const {
    return _inner_classes->at(
               _idx + InstanceKlass::inner_class_access_flags_offset);
  }
};
#endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/instanceMirrorKlass.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/oopFactory.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/instanceOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::_offset_of_static_fields = 0;
#ifdef ASSERT
template <class T> void assert_is_in(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in(o), "should be in heap");
  }
}
template <class T> void assert_is_in_closed_subset(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in_closed_subset(o), "should be in closed");
  }
}
template <class T> void assert_is_in_reserved(T *p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
  }
}
template <class T> void assert_nothing(T *p) {}
#else
template <class T> void assert_is_in(T *p) {}
template <class T> void assert_is_in_closed_subset(T *p) {}
template <class T> void assert_is_in_reserved(T *p) {}
template <class T> void assert_nothing(T *p) {}
#endif // ASSERT
#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
  T, start_p, count, do_oop,                         \
  assert_fn)                                         \
{                                                    \
  T* p         = (T*)(start_p);                      \
  T* const end = p + (count);                        \
  while (p < end) {                                  \
    (assert_fn)(p);                                  \
    do_oop;                                          \
    ++p;                                             \
  }                                                  \
}
#define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
  T, start_p, count, low, high,                              \
  do_oop, assert_fn)                                         \
{                                                            \
  T* const l = (T*)(low);                                    \
  T* const h = (T*)(high);                                   \
  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&         \
         mask_bits((intptr_t)h, sizeof(T)-1) == 0,           \
         "bounded region must be properly aligned");         \
  T* p       = (T*)(start_p);                                \
  T* end     = p + (count);                                  \
  if (p < l) p = l;                                          \
  if (end > h) end = h;                                      \
  while (p < end) {                                          \
    (assert_fn)(p);                                          \
    do_oop;                                                  \
    ++p;                                                     \
  }                                                          \
}
#define InstanceMirrorKlass_OOP_ITERATE(start_p, count,    \
                                  do_oop, assert_fn)       \
{                                                          \
  if (UseCompressedOops) {                                 \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
      start_p, count,                                      \
      do_oop, assert_fn)                                   \
  } else {                                                 \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop,       \
      start_p, count,                                      \
      do_oop, assert_fn)                                   \
  }                                                        \
}
#define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
                                          do_oop, assert_fn)               \
{                                                                          \
  if (UseCompressedOops) {                                                 \
    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,         \
      start_p, count,                                                      \
      low, high,                                                           \
      do_oop, assert_fn)                                                   \
  } else {                                                                 \
    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,               \
      start_p, count,                                                      \
      low, high,                                                           \
      do_oop, assert_fn)                                                   \
  }                                                                        \
}
void InstanceMirrorKlass::oop_follow_contents(oop obj) {
  InstanceKlass::oop_follow_contents(obj);
  Klass* klass = java_lang_Class::as_Klass(obj);
  if (klass != NULL) {
    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
      MarkSweep::follow_class_loader(klass->class_loader_data());
    } else {
      MarkSweep::follow_klass(klass);
    }
  } else {
    assert(java_lang_Class::is_primitive(obj), "Sanity check");
  }
  InstanceMirrorKlass_OOP_ITERATE(                                                    \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
    MarkSweep::mark_and_push(p),                                                      \
    assert_is_in_closed_subset)
}
#if INCLUDE_ALL_GCS
void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
                                              oop obj) {
  InstanceKlass::oop_follow_contents(cm, obj);
  Klass* klass = java_lang_Class::as_Klass(obj);
  if (klass != NULL) {
    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
      PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
    } else {
      PSParallelCompact::follow_klass(cm, klass);
    }
  } else {
    assert(java_lang_Class::is_primitive(obj), "Sanity check");
  }
  InstanceMirrorKlass_OOP_ITERATE(                                                    \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
    PSParallelCompact::mark_and_push(cm, p),                                          \
    assert_is_in)
}
#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::oop_adjust_pointers(oop obj) {
  int size = oop_size(obj);
  InstanceKlass::oop_adjust_pointers(obj);
  InstanceMirrorKlass_OOP_ITERATE(                                                    \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
    MarkSweep::adjust_pointer(p),                                                     \
    assert_nothing)
  return size;
}
#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix)                \
  InstanceMirrorKlass_OOP_ITERATE(                                                    \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
      (closure)->do_oop##nv_suffix(p),                                                \
    assert_is_in_closed_subset)                                                       \
  return oop_size(obj);                                                               \
#define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr)         \
  InstanceMirrorKlass_BOUNDED_OOP_ITERATE(                                            \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
    mr.start(), mr.end(),                                                             \
      (closure)->do_oop##nv_suffix(p),                                                \
    assert_is_in_closed_subset)                                                       \
  return oop_size(obj);                                                               \
#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
                                                                                      \
int InstanceMirrorKlass::                                                             \
oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                      \
  InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
                                                                                      \
  if_do_metadata_checked(closure, nv_suffix) {                                        \
    Klass* klass = java_lang_Class::as_Klass(obj);                                    \
    if (klass != NULL) {                                                              \
      closure->do_klass##nv_suffix(klass);                                            \
    }                                                                                 \
  }                                                                                   \
                                                                                      \
  if (UseCompressedOops) {                                                            \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
  } else {                                                                            \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
  }                                                                                   \
}
#if INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                      \
int InstanceMirrorKlass::                                                             \
oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {              \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                      \
  InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
                                                                                      \
  if (UseCompressedOops) {                                                            \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
  } else {                                                                            \
    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
  }                                                                                   \
}
#endif // INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
                                                                                      \
int InstanceMirrorKlass::                                                             \
oop_oop_iterate##nv_suffix##_m(oop obj,                                               \
                               OopClosureType* closure,                               \
                               MemRegion mr) {                                        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
                                                                                      \
  InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
                                                                                      \
  if_do_metadata_checked(closure, nv_suffix) {                                        \
    if (mr.contains(obj)) {                                                           \
      Klass* klass = java_lang_Class::as_Klass(obj);                                  \
      if (klass != NULL) {                                                            \
        closure->do_klass##nv_suffix(klass);                                          \
      }                                                                               \
    }                                                                                 \
  }                                                                                   \
                                                                                      \
  if (UseCompressedOops) {                                                            \
    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr);    \
  } else {                                                                            \
    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr);          \
  }                                                                                   \
}
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
#if INCLUDE_ALL_GCS
void InstanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
  InstanceKlass::oop_push_contents(pm, obj);
  InstanceMirrorKlass_OOP_ITERATE(                                            \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
    if (PSScavenge::should_scavenge(p)) {                                     \
      pm->claim_or_forward_depth(p);                                          \
    },                                                                        \
    assert_nothing )
}
int InstanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  int size = oop_size(obj);
  InstanceKlass::oop_update_pointers(cm, obj);
  InstanceMirrorKlass_OOP_ITERATE(                                            \
    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
    PSParallelCompact::adjust_pointer(p),                                     \
    assert_nothing)
  return size;
}
#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::instance_size(KlassHandle k) {
  if (k() != NULL && k->oop_is_instance()) {
    return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
  }
  return size_helper();
}
instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
  int size = instance_size(k);
  KlassHandle h_k(THREAD, this);
  instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
  java_lang_Class::set_oop_size(i, size);
  return i;
}
int InstanceMirrorKlass::oop_size(oop obj) const {
  return java_lang_Class::oop_size(obj);
}
int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
  Klass* k = java_lang_Class::as_Klass(obj);
  if (k != NULL && k->oop_is_instance()) {
    return InstanceKlass::cast(k)->static_oop_field_count();
  }
  return 0;
}
C:\hotspot-69087d08d473\src\share\vm/oops/instanceMirrorKlass.hpp
#ifndef SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
#define SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
#include "classfile/systemDictionary.hpp"
#include "oops/instanceKlass.hpp"
#include "runtime/handles.hpp"
#include "utilities/macros.hpp"
class InstanceMirrorKlass: public InstanceKlass {
  friend class VMStructs;
  friend class InstanceKlass;
 private:
  static int _offset_of_static_fields;
  InstanceMirrorKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags,  bool is_anonymous)
    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
 public:
  InstanceMirrorKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
  bool oop_is_instanceMirror() const             { return true; }
  static InstanceMirrorKlass* cast(Klass* k) {
    assert(k->oop_is_instanceMirror(), "cast to InstanceMirrorKlass");
    return (InstanceMirrorKlass*) k;
  }
  virtual int oop_size(oop obj) const;
  static HeapWord* start_of_static_fields(oop obj) {
    return (HeapWord*)(cast_from_oop<intptr_t>(obj) + offset_of_static_fields());
  }
  static void init_offset_of_static_fields() {
    assert(_offset_of_static_fields == 0, "once");
    _offset_of_static_fields = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->size_helper() << LogHeapWordSize;
  }
  static int offset_of_static_fields() {
    return _offset_of_static_fields;
  }
  int compute_static_oop_field_count(oop obj);
  int instance_size(KlassHandle k);
  instanceOop allocate_instance(KlassHandle k, TRAPS);
  int  oop_adjust_pointers(oop obj);
  void oop_follow_contents(oop obj);
  PARALLEL_GC_DECLS
  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate_v(obj, blk);
  }
  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
    return oop_oop_iterate_v_m(obj, blk, mr);
  }
#define InstanceMirrorKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)           \
  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                       \
  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
#if INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
#endif // INCLUDE_ALL_GCS
};
#endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/instanceOop.cpp
#include "precompiled.hpp"
#include "oops/instanceOop.hpp"
C:\hotspot-69087d08d473\src\share\vm/oops/instanceOop.hpp
#ifndef SHARE_VM_OOPS_INSTANCEOOP_HPP
#define SHARE_VM_OOPS_INSTANCEOOP_HPP
#include "oops/oop.hpp"
class instanceOopDesc : public oopDesc {
 public:
  static int header_size() { return sizeof(instanceOopDesc)/HeapWordSize; }
  static int base_offset_in_bytes() {
    return (UseCompressedOops && UseCompressedClassPointers) ?
             klass_gap_offset_in_bytes() :
             sizeof(instanceOopDesc);
  }
  static bool contains_field_offset(int offset, int nonstatic_field_size) {
    int base_in_bytes = base_offset_in_bytes();
    return (offset >= base_in_bytes &&
            (offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
  }
};
#endif // SHARE_VM_OOPS_INSTANCEOOP_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/instanceRefKlass.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#endif // INCLUDE_ALL_GCS
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
template <class T>
void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
    }
  )
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
    if (!referent->is_gc_marked() &&
        MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
      ref->InstanceKlass::oop_follow_contents(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
        }
      )
      return;
    } else {
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (void *)obj);
        }
      )
      MarkSweep::mark_and_push(referent_addr);
    }
  }
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      MarkSweep::mark_and_push(discovered_addr);
    }
  } else {
#ifdef ASSERT
    oop next = oopDesc::load_decode_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
                   (oopDesc*)obj));
#endif
  }
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    }
  )
  MarkSweep::mark_and_push(next_addr);
  ref->InstanceKlass::oop_follow_contents(obj);
}
void InstanceRefKlass::oop_follow_contents(oop obj) {
  if (UseCompressedOops) {
    specialized_oop_follow_contents<narrowOop>(this, obj);
  } else {
    specialized_oop_follow_contents<oop>(this, obj);
  }
}
#if INCLUDE_ALL_GCS
template <class T>
void specialized_oop_follow_contents(InstanceRefKlass* ref,
                                     ParCompactionManager* cm,
                                     oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
    }
  )
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
        PSParallelCompact::ref_processor()->
          discover_reference(obj, ref->reference_type())) {
      ref->InstanceKlass::oop_follow_contents(cm, obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
        }
      )
      return;
    } else {
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (void *)obj);
        }
      )
      PSParallelCompact::mark_and_push(cm, referent_addr);
    }
  }
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      PSParallelCompact::mark_and_push(cm, discovered_addr);
    }
  } else {
#ifdef ASSERT
    T next = oopDesc::load_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
                   (oopDesc*)obj));
#endif
  }
  PSParallelCompact::mark_and_push(cm, next_addr);
  ref->InstanceKlass::oop_follow_contents(cm, obj);
}
void InstanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
                                           oop obj) {
  if (UseCompressedOops) {
    specialized_oop_follow_contents<narrowOop>(this, cm, obj);
  } else {
    specialized_oop_follow_contents<oop>(this, cm, obj);
  }
}
#endif // INCLUDE_ALL_GCS
#ifdef ASSERT
template <class T> void trace_reference_gc(const char *s, oop obj,
                                           T* referent_addr,
                                           T* next_addr,
                                           T* discovered_addr) {
  if(TraceReferenceGC && PrintGCDetails) {
    gclog_or_tty->print_cr("%s obj " INTPTR_FORMAT, s, (address)obj);
    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
         INTPTR_FORMAT, referent_addr,
         referent_addr ?
           (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL);
    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
         INTPTR_FORMAT, next_addr,
         next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL);
    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
         INTPTR_FORMAT, discovered_addr,
         discovered_addr ?
           (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL);
  }
}
#endif
template <class T> void specialized_oop_adjust_pointers(InstanceRefKlass *ref, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  MarkSweep::adjust_pointer(referent_addr);
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  MarkSweep::adjust_pointer(next_addr);
  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
  MarkSweep::adjust_pointer(discovered_addr);
  debug_only(trace_reference_gc("InstanceRefKlass::oop_adjust_pointers", obj,
                                referent_addr, next_addr, discovered_addr);)
}
int InstanceRefKlass::oop_adjust_pointers(oop obj) {
  int size = size_helper();
  InstanceKlass::oop_adjust_pointers(obj);
  if (UseCompressedOops) {
    specialized_oop_adjust_pointers<narrowOop>(this, obj);
  } else {
    specialized_oop_adjust_pointers<oop>(this, obj);
  }
  return size;
}
#define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);             \
  if (closure->apply_to_weak_ref_discovered_field()) {                          \
    closure->do_oop##nv_suffix(disc_addr);                                      \
  }                                                                             \
                                                                                \
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
  T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
  ReferenceProcessor* rp = closure->_ref_processor;                             \
  if (!oopDesc::is_null(heap_oop)) {                                            \
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
        rp->discover_reference(obj, reference_type())) {                        \
      return size;                                                              \
    } else if (contains(referent_addr)) {                                       \
      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
      closure->do_oop##nv_suffix(referent_addr);                                \
    }                                                                           \
  }                                                                             \
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {               \
    T next_oop  = oopDesc::load_heap_oop(next_addr);                            \
    if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {                   \
      debug_only(                                                               \
        if(TraceReferenceGC && PrintGCDetails) {                                \
          gclog_or_tty->print_cr("   Process discovered as normal "             \
                                 INTPTR_FORMAT, disc_addr);                     \
        }                                                                       \
      )                                                                         \
      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
      closure->do_oop##nv_suffix(disc_addr);                                    \
    }                                                                           \
  } else {                                                                      \
    debug_only(                                                                 \
      T next_oop = oopDesc::load_heap_oop(next_addr);                           \
      T disc_oop = oopDesc::load_heap_oop(disc_addr);                           \
      assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),          \
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \
                   "discovered field", (oopDesc*)obj));                                   \
    )                                                                           \
  }                                                                             \
  if (contains(next_addr)) {                                                    \
    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
    closure->do_oop##nv_suffix(next_addr);                                      \
  }                                                                             \
  return size;                                                                  \
template <class T> bool contains(T *t) { return true; }
#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
                                                                                \
int InstanceRefKlass::                                                          \
oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
  int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
}
#if INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                \
int InstanceRefKlass::                                                          \
oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
  int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
}
#endif // INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
                                                                                \
int InstanceRefKlass::                                                          \
oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
                               OopClosureType* closure,                         \
                               MemRegion mr) {                                  \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
  int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr.contains);      \
  }                                                                             \
}
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
#if INCLUDE_ALL_GCS
template <class T>
void specialized_oop_push_contents(InstanceRefKlass *ref,
                                   PSPromotionManager* pm, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  if (PSScavenge::should_scavenge(referent_addr)) {
    ReferenceProcessor* rp = PSScavenge::reference_processor();
    if (rp->discover_reference(obj, ref->reference_type())) {
      ref->InstanceKlass::oop_push_contents(pm, obj);
      return;
    } else {
      pm->claim_or_forward_depth(referent_addr);
    }
  }
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      if (PSScavenge::should_scavenge(discovered_addr)) {
        pm->claim_or_forward_depth(discovered_addr);
      }
    }
  } else {
#ifdef ASSERT
    oop next = oopDesc::load_decode_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
                   (oopDesc*)obj));
#endif
  }
  if (PSScavenge::should_scavenge(next_addr)) {
    pm->claim_or_forward_depth(next_addr);
  }
  ref->InstanceKlass::oop_push_contents(pm, obj);
}
void InstanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
  if (UseCompressedOops) {
    specialized_oop_push_contents<narrowOop>(this, pm, obj);
  } else {
    specialized_oop_push_contents<oop>(this, pm, obj);
  }
}
template <class T>
void specialized_oop_update_pointers(InstanceRefKlass *ref,
                                    ParCompactionManager* cm, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  PSParallelCompact::adjust_pointer(referent_addr);
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  PSParallelCompact::adjust_pointer(next_addr);
  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
  PSParallelCompact::adjust_pointer(discovered_addr);
  debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
                                referent_addr, next_addr, discovered_addr);)
}
int InstanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  InstanceKlass::oop_update_pointers(cm, obj);
  if (UseCompressedOops) {
    specialized_oop_update_pointers<narrowOop>(this, cm, obj);
  } else {
    specialized_oop_update_pointers<oop>(this, cm, obj);
  }
  return size_helper();
}
#endif // INCLUDE_ALL_GCS
void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
  InstanceKlass* ik = InstanceKlass::cast(k);
  debug_only(static bool first_time = true);
  assert(k == SystemDictionary::Reference_klass() && first_time,
         "Invalid update of maps");
  debug_only(first_time = false);
  assert(ik->nonstatic_oop_map_count() == 1, "just checking");
  OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
  debug_only(int offset = java_lang_ref_Reference::referent_offset);
  debug_only(unsigned int count = ((java_lang_ref_Reference::discovered_offset -
    java_lang_ref_Reference::referent_offset)/heapOopSize) + 1);
  if (UseSharedSpaces) {
    assert(map->offset() == java_lang_ref_Reference::queue_offset &&
           map->count() == 1, "just checking");
  } else {
    assert(map->offset() == offset && map->count() == count,
           "just checking");
    map->set_offset(java_lang_ref_Reference::queue_offset);
    map->set_count(1);
  }
}
void InstanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
  InstanceKlass::oop_verify_on(obj, st);
  oop referent = java_lang_ref_Reference::referent(obj);
  GenCollectedHeap* gch = NULL;
  if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap)
    gch = GenCollectedHeap::heap();
  if (referent != NULL) {
    guarantee(referent->is_oop(), "referent field heap failed");
  }
  oop next = java_lang_ref_Reference::next(obj);
  if (next != NULL) {
    guarantee(next->is_oop(), "next field verify failed");
    guarantee(next->is_instanceRef(), "next field verify failed");
  }
}
bool InstanceRefKlass::owns_pending_list_lock(JavaThread* thread) {
  if (java_lang_ref_Reference::pending_list_lock() == NULL) return false;
  Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock());
  return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock);
}
void InstanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
  HandleMark hm;
  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
  ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD);
  assert(ObjectSynchronizer::current_thread_holds_lock(
           JavaThread::current(), h_lock),
         "Locking should have succeeded");
  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
}
void InstanceRefKlass::release_and_notify_pending_list_lock(
  BasicLock *pending_list_basic_lock) {
  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
  HandleMark hm;
  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
  assert(ObjectSynchronizer::current_thread_holds_lock(
           JavaThread::current(), h_lock),
         "Lock should be held");
  if (java_lang_ref_Reference::pending_list() != NULL) {
    ObjectSynchronizer::notifyall(h_lock, THREAD);
  }
  ObjectSynchronizer::fast_exit(h_lock(), pending_list_basic_lock, THREAD);
  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
}
C:\hotspot-69087d08d473\src\share\vm/oops/instanceRefKlass.hpp
#ifndef SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
#define SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
#include "oops/instanceKlass.hpp"
#include "utilities/macros.hpp"
class InstanceRefKlass: public InstanceKlass {
  friend class InstanceKlass;
  InstanceRefKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags, bool is_anonymous)
    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
 public:
  InstanceRefKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
  bool oop_is_instanceRef() const             { return true; }
  static InstanceRefKlass* cast(Klass* k) {
    assert(k->oop_is_instanceRef(), "cast to InstanceRefKlass");
    return (InstanceRefKlass*) k;
  }
  int  oop_adjust_pointers(oop obj);
  void oop_follow_contents(oop obj);
  PARALLEL_GC_DECLS
  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate_v(obj, blk);
  }
  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
    return oop_oop_iterate_v_m(obj, blk, mr);
  }
#define InstanceRefKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                         \
  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
#if INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
#endif // INCLUDE_ALL_GCS
  static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock);
  static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock);
  static bool owns_pending_list_lock(JavaThread* thread);
  static void update_nonstatic_oop_maps(Klass* k);
 public:
  void oop_verify_on(oop obj, outputStream* st);
};
#endif // SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/klass.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "utilities/stack.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#endif // INCLUDE_ALL_GCS
#if INCLUDE_JFR
#include "jfr/support/jfrTraceIdExtension.hpp"
#endif
bool Klass::is_cloneable() const {
  return _access_flags.is_cloneable() ||
         is_subtype_of(SystemDictionary::Cloneable_klass());
}
void Klass::set_is_cloneable() {
  if (oop_is_instance() && InstanceKlass::cast(this)->reference_type() != REF_NONE) {
  } else {
    _access_flags.set_is_cloneable();
  }
}
void Klass::set_name(Symbol* n) {
  _name = n;
  if (_name != NULL) _name->increment_refcount();
}
bool Klass::is_subclass_of(const Klass* k) const {
  if (this == k) return true;
  Klass* t = const_cast<Klass*>(this)->super();
  while (t != NULL) {
    if (t == k) return true;
    t = t->super();
  }
  return false;
}
bool Klass::search_secondary_supers(Klass* k) const {
  if (this == k)
    return true;
  int cnt = secondary_supers()->length();
  for (int i = 0; i < cnt; i++) {
    if (secondary_supers()->at(i) == k) {
      ((Klass*)this)->set_secondary_super_cache(k);
      return true;
    }
  }
  return false;
}
Klass *Klass::up_cast_abstract() {
  Klass *r = this;
  while( r->is_abstract() ) {   // Receiver is abstract?
    Klass *s = r->subklass();   // Check for exactly 1 subklass
    if( !s || s->next_sibling() ) // Oops; wrong count; give up
      return this;              // Return 'this' as a no-progress flag
    r = s;                    // Loop till find concrete class
  }
  return r;                   // Return the 1 concrete class
}
Klass *Klass::LCA( Klass *k2 ) {
  Klass *k1 = this;
  while( 1 ) {
    if( k1->is_subtype_of(k2) ) return k2;
    if( k2->is_subtype_of(k1) ) return k1;
    k1 = k1->super();
    k2 = k2->super();
  }
}
void Klass::check_valid_for_instantiation(bool throwError, TRAPS) {
  ResourceMark rm(THREAD);
  THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError()
            : vmSymbols::java_lang_InstantiationException(), external_name());
}
void Klass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
  THROW(vmSymbols::java_lang_ArrayStoreException());
}
void Klass::initialize(TRAPS) {
  ShouldNotReachHere();
}
bool Klass::compute_is_subtype_of(Klass* k) {
  assert(k->is_klass(), "argument must be a class");
  return is_subclass_of(k);
}
Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
#ifdef ASSERT
  tty->print_cr("Error: find_field called on a klass oop."
                " Likely error: reflection method does not correctly"
                " wrap return value in a mirror object.");
#endif
  ShouldNotReachHere();
  return NULL;
}
Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
#ifdef ASSERT
  tty->print_cr("Error: uncached_lookup_method called on a klass oop."
                " Likely error: reflection method does not correctly"
                " wrap return value in a mirror object.");
#endif
  ShouldNotReachHere();
  return NULL;
}
void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() {
  return Metaspace::allocate(loader_data, word_size, /*read_only*/false,
                             MetaspaceObj::ClassType, THREAD);
}
Klass::Klass() {
  Klass* k = this;
  set_super(NULL);
  for (juint i = 0; i < Klass::primary_super_limit(); i++) {
    _primary_supers[i] = NULL;
  }
  set_secondary_supers(NULL);
  set_secondary_super_cache(NULL);
  _primary_supers[0] = k;
  set_super_check_offset(in_bytes(primary_supers_offset()));
  _java_mirror = NULL;
  set_modifier_flags(0);
  set_layout_helper(Klass::_lh_neutral_value);
  set_name(NULL);
  AccessFlags af;
  af.set_flags(0);
  set_access_flags(af);
  set_subklass(NULL);
  set_next_sibling(NULL);
  set_next_link(NULL);
  set_prototype_header(markOopDesc::prototype());
  set_biased_lock_revocation_count(0);
  set_last_biased_lock_bulk_revocation_time(0);
  clear_modified_oops();
  clear_accumulated_modified_oops();
  _shared_class_path_index = -1;
}
jint Klass::array_layout_helper(BasicType etype) {
  assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype");
  int  hsize = arrayOopDesc::base_offset_in_bytes(etype);
  int  esize = type2aelembytes(etype);
  bool isobj = (etype == T_OBJECT);
  int  tag   =  isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value;
  int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize));
  assert(lh < (int)_lh_neutral_value, "must look like an array layout");
  assert(layout_helper_is_array(lh), "correct kind");
  assert(layout_helper_is_objArray(lh) == isobj, "correct kind");
  assert(layout_helper_is_typeArray(lh) == !isobj, "correct kind");
  assert(layout_helper_header_size(lh) == hsize, "correct decode");
  assert(layout_helper_element_type(lh) == etype, "correct decode");
  assert(1 << layout_helper_log2_element_size(lh) == esize, "correct decode");
  return lh;
}
bool Klass::can_be_primary_super_slow() const {
  if (super() == NULL)
    return true;
  else if (super()->super_depth() >= primary_super_limit()-1)
    return false;
  else
    return true;
}
void Klass::initialize_supers(Klass* k, TRAPS) {
  if (FastSuperclassLimit == 0) {
    set_super(k);
    return;
  }
  if (k == NULL) {
    set_super(NULL);
    _primary_supers[0] = this;
    assert(super_depth() == 0, "Object must already be initialized properly");
  } else if (k != super() || k == SystemDictionary::Object_klass()) {
    assert(super() == NULL || super() == SystemDictionary::Object_klass(),
           "initialize this only once to a non-trivial value");
    set_super(k);
    Klass* sup = k;
    int sup_depth = sup->super_depth();
    juint my_depth  = MIN2(sup_depth + 1, (int)primary_super_limit());
    if (!can_be_primary_super_slow())
      my_depth = primary_super_limit();
    for (juint i = 0; i < my_depth; i++) {
      _primary_supers[i] = sup->_primary_supers[i];
    }
    Klass* *super_check_cell;
    if (my_depth < primary_super_limit()) {
      _primary_supers[my_depth] = this;
      super_check_cell = &_primary_supers[my_depth];
    } else {
      super_check_cell = &_secondary_super_cache;
    }
    set_super_check_offset((address)super_check_cell - (address) this);
#ifdef ASSERT
    {
      juint j = super_depth();
      assert(j == my_depth, "computed accessor gets right answer");
      Klass* t = this;
      while (!t->can_be_primary_super()) {
        t = t->super();
        j = t->super_depth();
      }
      for (juint j1 = j+1; j1 < primary_super_limit(); j1++) {
        assert(primary_super_of_depth(j1) == NULL, "super list padding");
      }
      while (t != NULL) {
        assert(primary_super_of_depth(j) == t, "super list initialization");
        t = t->super();
        --j;
      }
      assert(j == (juint)-1, "correct depth count");
    }
#endif
  }
  if (secondary_supers() == NULL) {
    KlassHandle this_kh (THREAD, this);
    int extras = 0;
    Klass* p;
    for (p = super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) {
      ++extras;
    }
    ResourceMark rm(THREAD);  // need to reclaim GrowableArrays allocated below
    GrowableArray<Klass*>* secondaries = compute_secondary_supers(extras);
    if (secondaries == NULL) {
      return;
    }
    GrowableArray<Klass*>* primaries = new GrowableArray<Klass*>(extras);
    for (p = this_kh->super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) {
      int i;                    // Scan for overflow primaries being duplicates of 2nd'arys
      for( i = 0; i < secondaries->length(); i++ ) {
        if( secondaries->at(i) == p )
          break;
      }
      if( i < secondaries->length() )
        continue;               // It's a dup, don't put it in
      primaries->push(p);
    }
    int new_length = primaries->length() + secondaries->length();
    Array<Klass*>* s2 = MetadataFactory::new_array<Klass*>(
                                       class_loader_data(), new_length, CHECK);
    int fill_p = primaries->length();
    for (int j = 0; j < fill_p; j++) {
      s2->at_put(j, primaries->pop());  // add primaries in reverse order.
    }
    for( int j = 0; j < secondaries->length(); j++ ) {
      s2->at_put(j+fill_p, secondaries->at(j));  // add secondaries on the end.
    }
  #ifdef ASSERT
    for (int j = 0; j < s2->length(); j++) {
      assert(s2->at(j) != NULL, "correct bootstrapping order");
    }
  #endif
    this_kh->set_secondary_supers(s2);
  }
}
GrowableArray<Klass*>* Klass::compute_secondary_supers(int num_extra_slots) {
  assert(num_extra_slots == 0, "override for complex klasses");
  set_secondary_supers(Universe::the_empty_klass_array());
  return NULL;
}
Klass* Klass::subklass() const {
  return _subklass == NULL ? NULL : _subklass;
}
InstanceKlass* Klass::superklass() const {
  assert(super() == NULL || super()->oop_is_instance(), "must be instance klass");
  return _super == NULL ? NULL : InstanceKlass::cast(_super);
}
Klass* Klass::next_sibling() const {
  return _next_sibling == NULL ? NULL : _next_sibling;
}
void Klass::set_subklass(Klass* s) {
  assert(s != this, "sanity check");
  _subklass = s;
}
void Klass::set_next_sibling(Klass* s) {
  assert(s != this, "sanity check");
  _next_sibling = s;
}
void Klass::append_to_sibling_list() {
  debug_only(verify();)
  InstanceKlass* super = superklass();
  if (super == NULL) return;        // special case: class Object
  assert((!super->is_interface()    // interfaces cannot be supers
          && (super->superklass() == NULL || !is_interface())),
         "an interface can only be a subklass of Object");
  Klass* prev_first_subklass = super->subklass_oop();
  if (prev_first_subklass != NULL) {
    set_next_sibling(prev_first_subklass);
  }
  super->set_subklass(this);
  debug_only(verify();)
}
bool Klass::is_loader_alive(BoolObjectClosure* is_alive) {
#ifdef ASSERT
  oop loader = class_loader();
  bool loader_alive = (loader == NULL) || is_alive->do_object_b(loader);
#endif // ASSERT
  bool mirror_alive = is_alive->do_object_b(java_mirror());
  assert(!mirror_alive || loader_alive, "loader must be alive if the mirror is"
                        " but not the other way around with anonymous classes");
  return mirror_alive;
}
void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses) {
  if (!ClassUnloading) {
    return;
  }
  Klass* root = SystemDictionary::Object_klass();
  Stack<Klass*, mtGC> stack;
  stack.push(root);
  while (!stack.is_empty()) {
    Klass* current = stack.pop();
    assert(current->is_loader_alive(is_alive), "just checking, this should be live");
    Klass* sub = current->subklass_oop();
    while (sub != NULL && !sub->is_loader_alive(is_alive)) {
#ifndef PRODUCT
      if (TraceClassUnloading && WizardMode) {
        ResourceMark rm;
        tty->print_cr("[Unlinking class (subclass) %s]", sub->external_name());
      }
#endif
      sub = sub->next_sibling_oop();
    }
    current->set_subklass(sub);
    if (sub != NULL) {
      stack.push(sub);
    }
    Klass* sibling = current->next_sibling_oop();
    while (sibling != NULL && !sibling->is_loader_alive(is_alive)) {
      if (TraceClassUnloading && WizardMode) {
        ResourceMark rm;
        tty->print_cr("[Unlinking class (sibling) %s]", sibling->external_name());
      }
      sibling = sibling->next_sibling_oop();
    }
    current->set_next_sibling(sibling);
    if (sibling != NULL) {
      stack.push(sibling);
    }
    if (clean_alive_klasses && current->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(current);
      ik->clean_weak_instanceklass_links(is_alive);
      while ((ik = ik->previous_versions()) != NULL) {
        ik->clean_weak_instanceklass_links(is_alive);
      }
    }
  }
}
void Klass::klass_update_barrier_set(oop v) {
  record_modified_oops();
}
void Klass::klass_update_barrier_set_pre(oop* p, oop v) {
#if INCLUDE_ALL_GCS
  if (UseG1GC) {
    oop obj = *p;
    if (obj != NULL) {
      G1SATBCardTableModRefBS::enqueue(obj);
    }
  }
#endif
}
void Klass::klass_oop_store(oop* p, oop v) {
  assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
  assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
  if (always_do_update_barrier) {
    klass_oop_store((volatile oop*)p, v);
  } else {
    klass_update_barrier_set_pre(p, v);
    klass_update_barrier_set(v);
  }
}
void Klass::klass_oop_store(volatile oop* p, oop v) {
  assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
  assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
  klass_update_barrier_set_pre((oop*)p, v); // Cast away volatile.
  OrderAccess::release_store_ptr(p, v);
  klass_update_barrier_set(v);
}
void Klass::oops_do(OopClosure* cl) {
  cl->do_oop(&_java_mirror);
}
void Klass::remove_unshareable_info() {
  assert (DumpSharedSpaces, "only called for DumpSharedSpaces");
  JFR_ONLY(REMOVE_ID(this);)
  set_subklass(NULL);
  set_next_sibling(NULL);
  set_java_mirror(NULL);
  set_next_link(NULL);
  set_class_loader_data(NULL);
}
void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
  JFR_ONLY(RESTORE_ID(this);)
  if (class_loader_data() == NULL) {
    set_class_loader_data(loader_data);
    loader_data->add_class(this);
  }
  if (java_mirror() == NULL) {
    java_lang_Class::create_mirror(this, class_loader(), protection_domain, CHECK);
  }
}
Klass* Klass::array_klass_or_null(int rank) {
  EXCEPTION_MARK;
  return array_klass_impl(true, rank, THREAD);
}
Klass* Klass::array_klass_or_null() {
  EXCEPTION_MARK;
  return array_klass_impl(true, THREAD);
}
Klass* Klass::array_klass_impl(bool or_null, int rank, TRAPS) {
  fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
  return NULL;
}
Klass* Klass::array_klass_impl(bool or_null, TRAPS) {
  fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
  return NULL;
}
oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
const char* Klass::external_name() const {
  if (oop_is_instance()) {
    InstanceKlass* ik = (InstanceKlass*) this;
    if (ik->is_anonymous()) {
      assert(EnableInvokeDynamic, "");
      intptr_t hash = 0;
      if (ik->java_mirror() != NULL) {
        hash = ik->java_mirror()->identity_hash();
      }
      char     hash_buf[40];
      sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
      size_t   hash_len = strlen(hash_buf);
      size_t result_len = name()->utf8_length();
      char*  result     = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
      name()->as_klass_external_name(result, (int) result_len + 1);
      assert(strlen(result) == result_len, "");
      strcpy(result + result_len, hash_buf);
      assert(strlen(result) == result_len + hash_len, "");
      return result;
    }
  }
  if (name() == NULL)  return "<unknown>";
  return name()->as_klass_external_name();
}
const char* Klass::signature_name() const {
  if (name() == NULL)  return "<unknown>";
  return name()->as_C_string();
}
jint Klass::compute_modifier_flags(TRAPS) const {
  return 0;
}
int Klass::atomic_incr_biased_lock_revocation_count() {
  return (int) Atomic::add(1, &_biased_lock_revocation_count);
}
jint Klass::jvmti_class_status() const {
  return 0;
}
void Klass::print_on(outputStream* st) const {
  ResourceMark rm;
  st->print("%s", internal_name());
  print_address_on(st);
  st->cr();
}
void Klass::oop_print_on(oop obj, outputStream* st) {
  ResourceMark rm;
  st->print_cr("%s ", internal_name());
  obj->print_address_on(st);
  if (WizardMode) {
     obj->mark()->print_on(st);
  }
  st->print(" - klass: ");
  obj->klass()->print_value_on(st);
  st->cr();
}
void Klass::oop_print_value_on(oop obj, outputStream* st) {
  ResourceMark rm;              // Cannot print in debug mode without this
  st->print("%s", internal_name());
  obj->print_address_on(st);
}
#if INCLUDE_SERVICES
void Klass::collect_statistics(KlassSizeStats *sz) const {
  sz->_klass_bytes = sz->count(this);
  sz->_mirror_bytes = sz->count(java_mirror());
  sz->_secondary_supers_bytes = sz->count_array(secondary_supers());
  sz->_ro_bytes += sz->_secondary_supers_bytes;
  sz->_rw_bytes += sz->_klass_bytes + sz->_mirror_bytes;
}
#endif // INCLUDE_SERVICES
void Klass::verify_on(outputStream* st) {
  assert(Metaspace::contains((address)this), "Should be");
  guarantee(this->is_klass(),"should be klass");
  if (super() != NULL) {
    guarantee(super()->is_klass(), "should be klass");
  }
  if (secondary_super_cache() != NULL) {
    Klass* ko = secondary_super_cache();
    guarantee(ko->is_klass(), "should be klass");
  }
  for ( uint i = 0; i < primary_super_limit(); i++ ) {
    Klass* ko = _primary_supers[i];
    if (ko != NULL) {
      guarantee(ko->is_klass(), "should be klass");
    }
  }
  if (java_mirror() != NULL) {
    guarantee(java_mirror()->is_oop(), "should be instance");
  }
}
void Klass::oop_verify_on(oop obj, outputStream* st) {
  guarantee(obj->is_oop(),  "should be oop");
  guarantee(obj->klass()->is_klass(), "klass field is not a klass");
}
#ifndef PRODUCT
bool Klass::verify_vtable_index(int i) {
  if (oop_is_instance()) {
    int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size();
    assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
  } else {
    assert(oop_is_array(), "Must be");
    int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size();
    assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
  }
  return true;
}
bool Klass::verify_itable_index(int i) {
  assert(oop_is_instance(), "");
  int method_count = klassItable::method_count_for_interface(this);
  assert(i >= 0 && i < method_count, "index out of bounds");
  return true;
}
#endif
#ifndef PRODUCT
class TestKlass {
 public:
  static void test_oop_is_instanceClassLoader() {
    assert(SystemDictionary::ClassLoader_klass()->oop_is_instanceClassLoader(), "assert");
    assert(!SystemDictionary::String_klass()->oop_is_instanceClassLoader(), "assert");
  }
};
void TestKlass_test() {
  TestKlass::test_oop_is_instanceClassLoader();
}
#endif
C:\hotspot-69087d08d473\src\share\vm/oops/klass.hpp
#ifndef SHARE_VM_OOPS_KLASS_HPP
#define SHARE_VM_OOPS_KLASS_HPP
#include "memory/genOopClosures.hpp"
#include "memory/iterator.hpp"
#include "memory/memRegion.hpp"
#include "memory/specialized_oop_closures.hpp"
#include "oops/klassPS.hpp"
#include "oops/metadata.hpp"
#include "oops/oop.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
#include "gc_implementation/g1/g1OopClosures.hpp"
#include "gc_implementation/parNew/parOopClosures.hpp"
#endif // INCLUDE_ALL_GCS
#if INCLUDE_JFR
#include "jfr/support/jfrTraceIdExtension.hpp"
#endif
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:
  enum { _primary_super_limit = 8 };
  jint        _layout_helper;
  juint       _super_check_offset;
  Symbol*     _name;
  Klass*      _secondary_super_cache;
  Array<Klass*>* _secondary_supers;
  Klass*      _primary_supers[_primary_super_limit];
  oop       _java_mirror;
  Klass*      _super;
  Klass*      _subklass;
  Klass*      _next_sibling;
  Klass*      _next_link;
  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.
  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;
  JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
  jbyte _modified_oops;             // Card Table Equivalent (YC/CMS support)
  jbyte _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
private:
  jshort _shared_class_path_index;
  friend class SharedClassUtil;
protected:
  Klass();
  void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
 public:
  enum DefaultsLookupMode { find_defaults, skip_defaults };
  enum OverpassLookupMode { find_overpass, skip_overpass };
  enum StaticLookupMode   { find_static,   skip_static };
  enum PrivateLookupMode  { find_private,  skip_private };
  bool is_klass() const volatile { return true; }
  Klass* super() const               { return _super; }
  void set_super(Klass* k)           { _super = k; }
  void initialize_supers(Klass* k, TRAPS);
  void initialize_supers_impl1(Klass* k);
  void initialize_supers_impl2(Klass* k);
  virtual GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots);
  virtual Klass* java_super() const  { return NULL; }
  juint    super_check_offset() const  { return _super_check_offset; }
  void set_super_check_offset(juint o) { _super_check_offset = o; }
  Klass* secondary_super_cache() const     { return _secondary_super_cache; }
  void set_secondary_super_cache(Klass* k) { _secondary_super_cache = k; }
  Array<Klass*>* secondary_supers() const { return _secondary_supers; }
  void set_secondary_supers(Array<Klass*>* k) { _secondary_supers = k; }
  Klass* primary_super_of_depth(juint i) const {
    assert(i < primary_super_limit(), "oob");
    Klass* super = _primary_supers[i];
    assert(super == NULL || super->super_depth() == i, "correct display");
    return super;
  }
  bool can_be_primary_super() const {
    const juint secondary_offset = in_bytes(secondary_super_cache_offset());
    return super_check_offset() != secondary_offset;
  }
  virtual bool can_be_primary_super_slow() const;
  juint super_depth() const {
    if (!can_be_primary_super()) {
      return primary_super_limit();
    } else {
      juint d = (super_check_offset() - in_bytes(primary_supers_offset())) / sizeof(Klass*);
      assert(d < primary_super_limit(), "oob");
      assert(_primary_supers[d] == this, "proper init");
      return d;
    }
  }
  void klass_oop_store(oop* p, oop v);
  void klass_oop_store(volatile oop* p, oop v);
  oop java_mirror() const              { return _java_mirror; }
  void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); }
  jint modifier_flags() const          { return _modifier_flags; }
  void set_modifier_flags(jint flags)  { _modifier_flags = flags; }
  int layout_helper() const            { return _layout_helper; }
  void set_layout_helper(int lh)       { _layout_helper = lh; }
  InstanceKlass* superklass() const;
  Klass* subklass() const;
  Klass* next_sibling() const;
  void append_to_sibling_list();           // add newly created receiver to superklass' subklass list
  void set_next_link(Klass* k) { _next_link = k; }
  Klass* next_link() const { return _next_link; }   // The next klass defined by the class loader.
  ClassLoaderData* class_loader_data() const               { return _class_loader_data; }
  void set_class_loader_data(ClassLoaderData* loader_data) {  _class_loader_data = loader_data; }
  void record_modified_oops()            { _modified_oops = 1; }
  void clear_modified_oops()             { _modified_oops = 0; }
  bool has_modified_oops()               { return _modified_oops == 1; }
  void accumulate_modified_oops()        { if (has_modified_oops()) _accumulated_modified_oops = 1; }
  void clear_accumulated_modified_oops() { _accumulated_modified_oops = 0; }
  bool has_accumulated_modified_oops()   { return _accumulated_modified_oops == 1; }
  int shared_classpath_index() const   {
    return _shared_class_path_index;
  };
  void set_shared_classpath_index(int index) {
    _shared_class_path_index = index;
  };
 protected:                                // internal accessors
  Klass* subklass_oop() const            { return _subklass; }
  Klass* next_sibling_oop() const        { return _next_sibling; }
  void     set_subklass(Klass* s);
  void     set_next_sibling(Klass* s);
 public:
  static ByteSize super_offset()                 { return in_ByteSize(offset_of(Klass, _super)); }
  static ByteSize super_check_offset_offset()    { return in_ByteSize(offset_of(Klass, _super_check_offset)); }
  static ByteSize primary_supers_offset()        { return in_ByteSize(offset_of(Klass, _primary_supers)); }
  static ByteSize secondary_super_cache_offset() { return in_ByteSize(offset_of(Klass, _secondary_super_cache)); }
  static ByteSize secondary_supers_offset()      { return in_ByteSize(offset_of(Klass, _secondary_supers)); }
  static ByteSize java_mirror_offset()           { return in_ByteSize(offset_of(Klass, _java_mirror)); }
  static ByteSize modifier_flags_offset()        { return in_ByteSize(offset_of(Klass, _modifier_flags)); }
  static ByteSize layout_helper_offset()         { return in_ByteSize(offset_of(Klass, _layout_helper)); }
  static ByteSize access_flags_offset()          { return in_ByteSize(offset_of(Klass, _access_flags)); }
  enum {
    _lh_neutral_value           = 0,  // neutral non-array non-instance value
    _lh_instance_slow_path_bit  = 0x01,
    _lh_log2_element_size_shift = BitsPerByte*0,
    _lh_log2_element_size_mask  = BitsPerLong-1,
    _lh_element_type_shift      = BitsPerByte*1,
    _lh_element_type_mask       = right_n_bits(BitsPerByte),  // shifted mask
    _lh_header_size_shift       = BitsPerByte*2,
    _lh_header_size_mask        = right_n_bits(BitsPerByte),  // shifted mask
    _lh_array_tag_bits          = 2,
    _lh_array_tag_shift         = BitsPerInt - _lh_array_tag_bits,
    _lh_array_tag_obj_value     = ~0x01   // 0x80000000 >> 30
  };
  static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00,  // 0xC0000000 >> 30
  static int layout_helper_size_in_bytes(jint lh) {
    assert(lh > (jint)_lh_neutral_value, "must be instance");
    return (int) lh & ~_lh_instance_slow_path_bit;
  }
  static bool layout_helper_needs_slow_path(jint lh) {
    assert(lh > (jint)_lh_neutral_value, "must be instance");
    return (lh & _lh_instance_slow_path_bit) != 0;
  }
  static bool layout_helper_is_instance(jint lh) {
    return (jint)lh > (jint)_lh_neutral_value;
  }
  static bool layout_helper_is_array(jint lh) {
    return (jint)lh < (jint)_lh_neutral_value;
  }
  static bool layout_helper_is_typeArray(jint lh) {
    return (juint)lh >= (juint)(_lh_array_tag_type_value << _lh_array_tag_shift);
  }
  static bool layout_helper_is_objArray(jint lh) {
    return (jint)lh < (jint)(_lh_array_tag_type_value << _lh_array_tag_shift);
  }
  static int layout_helper_header_size(jint lh) {
    assert(lh < (jint)_lh_neutral_value, "must be array");
    int hsize = (lh >> _lh_header_size_shift) & _lh_header_size_mask;
    assert(hsize > 0 && hsize < (int)sizeof(oopDesc)*3, "sanity");
    return hsize;
  }
  static BasicType layout_helper_element_type(jint lh) {
    assert(lh < (jint)_lh_neutral_value, "must be array");
    int btvalue = (lh >> _lh_element_type_shift) & _lh_element_type_mask;
    assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity");
    return (BasicType) btvalue;
  }
  static int layout_helper_boolean_diffbit() {
    jint zlh = array_layout_helper(T_BOOLEAN);
    jint blh = array_layout_helper(T_BYTE);
    assert(zlh != blh, "array layout helpers must differ");
    int diffbit = 1;
    while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) {
      diffbit <<= 1;
      assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE");
    }
    return diffbit;
  }
  static int layout_helper_log2_element_size(jint lh) {
    assert(lh < (jint)_lh_neutral_value, "must be array");
    int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
    assert(l2esz <= LogBitsPerLong,
        err_msg("sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh));
    return l2esz;
  }
  static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
    return (tag        << _lh_array_tag_shift)
      |    (hsize      << _lh_header_size_shift)
      |    ((int)etype << _lh_element_type_shift)
      |    (log2_esize << _lh_log2_element_size_shift);
  }
  static jint instance_layout_helper(jint size, bool slow_path_flag) {
    return (size << LogHeapWordSize)
      |    (slow_path_flag ? _lh_instance_slow_path_bit : 0);
  }
  static int layout_helper_to_size_helper(jint lh) {
    assert(lh > (jint)_lh_neutral_value, "must be instance");
    return lh >> LogHeapWordSize;
  }
  static jint array_layout_helper(BasicType etype);
#ifdef PRODUCT
  static juint primary_super_limit()         { return _primary_super_limit; }
#else
  static juint primary_super_limit() {
    assert(FastSuperclassLimit <= _primary_super_limit, "parameter oob");
    return FastSuperclassLimit;
  }
#endif
  virtual klassVtable* vtable() const        { return NULL; }
  virtual int vtable_length() const          { return 0; }
  bool is_subclass_of(const Klass* k) const;
  bool is_subtype_of(Klass* k) const {
    juint    off = k->super_check_offset();
    Klass* sup = *(Klass**)( (address)this + off );
    const juint secondary_offset = in_bytes(secondary_super_cache_offset());
    if (sup == k) {
      return true;
    } else if (off != secondary_offset) {
      return false;
    } else {
      return search_secondary_supers(k);
    }
  }
  bool search_secondary_supers(Klass* k) const;
  Klass *LCA( Klass *k );
  virtual void check_valid_for_instantiation(bool throwError, TRAPS);
  virtual void  copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
  virtual bool should_be_initialized() const    { return false; }
  virtual void initialize(TRAPS);
  friend class MethodLookupCache;
  virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
  virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
 public:
  Method* lookup_method(Symbol* name, Symbol* signature) const {
    return uncached_lookup_method(name, signature, find_overpass);
  }
  Klass* array_klass(int rank, TRAPS)         {  return array_klass_impl(false, rank, THREAD); }
  Klass* array_klass(TRAPS)                   {  return array_klass_impl(false, THREAD); }
  Klass* array_klass_or_null(int rank);
  Klass* array_klass_or_null();
  virtual oop protection_domain() const = 0;
  oop class_loader() const;
  virtual oop klass_holder() const      { return class_loader(); }
 protected:
  virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
  virtual Klass* array_klass_impl(bool or_null, TRAPS);
 public:
  virtual void remove_unshareable_info();
  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
 protected:
  virtual bool compute_is_subtype_of(Klass* k);
 public:
  virtual bool is_leaf_class() const { fatal("not a class"); return false; }
 public:
  virtual int oop_size(oop obj) const = 0;
  virtual int size() const = 0;
#if INCLUDE_SERVICES
  virtual void collect_statistics(KlassSizeStats *sz) const;
#endif
  const char* external_name() const;
  virtual const char* signature_name() const;
  virtual void oop_follow_contents(oop obj) = 0;
  virtual int  oop_adjust_pointers(oop obj) = 0;
  PARALLEL_GC_DECLS_PV
 protected:
  virtual bool oop_is_instance_slow()       const { return false; }
  virtual bool oop_is_array_slow()          const { return false; }
  virtual bool oop_is_objArray_slow()       const { return false; }
  virtual bool oop_is_typeArray_slow()      const { return false; }
 public:
  virtual bool oop_is_instanceClassLoader() const { return false; }
  virtual bool oop_is_instanceMirror()      const { return false; }
  virtual bool oop_is_instanceRef()         const { return false; }
  #ifndef ASSERT
  #define assert_same_query(xval, xcheck) xval
  #else
 private:
  static bool assert_same_query(bool xval, bool xslow) {
    assert(xval == xslow, "slow and fast queries agree");
    return xval;
  }
 public:
  #endif
  inline  bool oop_is_instance()            const { return assert_same_query(
                                                    layout_helper_is_instance(layout_helper()),
                                                    oop_is_instance_slow()); }
  inline  bool oop_is_array()               const { return assert_same_query(
                                                    layout_helper_is_array(layout_helper()),
                                                    oop_is_array_slow()); }
  inline  bool oop_is_objArray()            const { return assert_same_query(
                                                    layout_helper_is_objArray(layout_helper()),
                                                    oop_is_objArray_slow()); }
  inline  bool oop_is_typeArray()           const { return assert_same_query(
                                                    layout_helper_is_typeArray(layout_helper()),
                                                    oop_is_typeArray_slow()); }
  #undef assert_same_query
  AccessFlags access_flags() const         { return _access_flags;  }
  void set_access_flags(AccessFlags flags) { _access_flags = flags; }
  bool is_public() const                { return _access_flags.is_public(); }
  bool is_final() const                 { return _access_flags.is_final(); }
  bool is_interface() const             { return _access_flags.is_interface(); }
  bool is_abstract() const              { return _access_flags.is_abstract(); }
  bool is_super() const                 { return _access_flags.is_super(); }
  bool is_synthetic() const             { return _access_flags.is_synthetic(); }
  void set_is_synthetic()               { _access_flags.set_is_synthetic(); }
  bool has_finalizer() const            { return _access_flags.has_finalizer(); }
  bool has_final_method() const         { return _access_flags.has_final_method(); }
  void set_has_finalizer()              { _access_flags.set_has_finalizer(); }
  void set_has_final_method()           { _access_flags.set_has_final_method(); }
  bool is_cloneable() const;
  void set_is_cloneable();
  bool has_vanilla_constructor() const  { return _access_flags.has_vanilla_constructor(); }
  void set_has_vanilla_constructor()    { _access_flags.set_has_vanilla_constructor(); }
  bool has_miranda_methods () const     { return access_flags().has_miranda_methods(); }
  void set_has_miranda_methods()        { _access_flags.set_has_miranda_methods(); }
  markOop prototype_header() const      { return _prototype_header; }
  inline void set_prototype_header(markOop header);
  static ByteSize prototype_header_offset() { return in_ByteSize(offset_of(Klass, _prototype_header)); }
  int  biased_lock_revocation_count() const { return (int) _biased_lock_revocation_count; }
  int atomic_incr_biased_lock_revocation_count();
  void set_biased_lock_revocation_count(int val) { _biased_lock_revocation_count = (jint) val; }
  jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; }
  void  set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; }
  JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
  virtual void oops_do(OopClosure* cl);
  bool is_loader_alive(BoolObjectClosure* is_alive);
  static void clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses = true);
  static void clean_subklass_tree(BoolObjectClosure* is_alive) {
    clean_weak_klass_links(is_alive, false /* clean_alive_klasses */);
  }
  virtual int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) = 0;
  virtual int oop_oop_iterate_v(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate(obj, blk);
  }
#if INCLUDE_ALL_GCS
  virtual int oop_oop_iterate_backwards_v(oop obj, ExtendedOopClosure* blk) {
    return oop_oop_iterate_v(obj, blk);
  }
#endif // INCLUDE_ALL_GCS
  virtual int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) = 0;
  virtual int oop_oop_iterate_v_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
    return oop_oop_iterate_m(obj, blk, mr);
  }
#define Klass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
  virtual int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk) {     \
    return oop_oop_iterate(obj, blk);                                        \
  }                                                                          \
                                                                             \
     (I don't see why the _m should be required, but without it the Solaris  \
     C++ gives warning messages about overridings of the "oop_oop_iterate"   \
     defined above "hiding" this virtual function.  (DLD, 6/20/00)) */       \
  virtual int oop_oop_iterate##nv_suffix##_m(oop obj,                        \
                                             OopClosureType* blk,            \
                                             MemRegion mr) {                 \
    return oop_oop_iterate_m(obj, blk, mr);                                  \
  }
  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
#if INCLUDE_ALL_GCS
#define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
  virtual int oop_oop_iterate_backwards##nv_suffix(oop obj,                  \
                                                   OopClosureType* blk) {    \
    return oop_oop_iterate_backwards_v(obj, blk);                            \
  }
  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
#endif // INCLUDE_ALL_GCS
  virtual void array_klasses_do(void f(Klass* k)) {}
  Klass *up_cast_abstract();
  Symbol* name() const                   { return _name; }
  void set_name(Symbol* n);
 public:
  virtual jint compute_modifier_flags(TRAPS) const;
  virtual jint jvmti_class_status() const;
  virtual void print_on(outputStream* st) const;
  virtual void oop_print_value_on(oop obj, outputStream* st);
  virtual void oop_print_on      (oop obj, outputStream* st);
  virtual const char* internal_name() const = 0;
  virtual void verify_on(outputStream* st);
  void verify() { verify_on(tty); }
#ifndef PRODUCT
  bool verify_vtable_index(int index);
  bool verify_itable_index(int index);
#endif
  virtual void oop_verify_on(oop obj, outputStream* st);
  static bool is_null(narrowKlass obj);
  static bool is_null(Klass* obj);
  static narrowKlass encode_klass_not_null(Klass* v);
  static narrowKlass encode_klass(Klass* v);
  static Klass* decode_klass_not_null(narrowKlass v);
  static Klass* decode_klass(narrowKlass v);
 private:
  void klass_update_barrier_set(oop v);
  void klass_update_barrier_set_pre(oop* p, oop v);
};
#endif // SHARE_VM_OOPS_KLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/klass.inline.hpp
#ifndef SHARE_VM_OOPS_KLASS_INLINE_HPP
#define SHARE_VM_OOPS_KLASS_INLINE_HPP
#include "memory/universe.hpp"
#include "oops/klass.hpp"
#include "oops/markOop.hpp"
inline void Klass::set_prototype_header(markOop header) {
  assert(!header->has_bias_pattern() || oop_is_instance(), "biased locking currently only supported for Java instances");
  _prototype_header = header;
}
inline bool Klass::is_null(Klass* obj)  { return obj == NULL; }
inline bool Klass::is_null(narrowKlass obj) { return obj == 0; }
inline bool check_klass_alignment(Klass* obj) {
  return (intptr_t)obj % KlassAlignmentInBytes == 0;
}
inline narrowKlass Klass::encode_klass_not_null(Klass* v) {
  assert(!is_null(v), "klass value can never be zero");
  assert(check_klass_alignment(v), "Address not aligned");
  int    shift = Universe::narrow_klass_shift();
  uint64_t pd = (uint64_t)(pointer_delta((void*)v, Universe::narrow_klass_base(), 1));
  assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
  uint64_t result = pd >> shift;
  assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
  assert(decode_klass(result) == v, "reversibility");
  return (narrowKlass)result;
}
inline narrowKlass Klass::encode_klass(Klass* v) {
  return is_null(v) ? (narrowKlass)0 : encode_klass_not_null(v);
}
inline Klass* Klass::decode_klass_not_null(narrowKlass v) {
  assert(!is_null(v), "narrow klass value can never be zero");
  int    shift = Universe::narrow_klass_shift();
  Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift));
  assert(check_klass_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result)));
  return result;
}
inline Klass* Klass::decode_klass(narrowKlass v) {
  return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
}
#endif // SHARE_VM_OOPS_KLASS_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/klassPS.hpp
#ifndef SHARE_VM_OOPS_KLASSPS_HPP
#define SHARE_VM_OOPS_KLASSPS_HPP
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#define PARALLEL_GC_DECLS \
  virtual void oop_push_contents(PSPromotionManager* pm, oop obj);          \
                                                                            \
   The 2-arg version of oop_update_pointers is for objects that are         \
   known not to cross chunk boundaries.  The 4-arg version is for           \
   objects that do (or may) cross chunk boundaries; it updates only those   \
   oops that are in the region [beg_addr, end_addr).  */                    \
  virtual void oop_follow_contents(ParCompactionManager* cm, oop obj);      \
  virtual int  oop_update_pointers(ParCompactionManager* cm, oop obj);
#define PARALLEL_GC_DECLS_PV \
  virtual void oop_push_contents(PSPromotionManager* pm, oop obj) = 0;      \
  virtual void oop_follow_contents(ParCompactionManager* cm, oop obj) = 0;  \
  virtual int  oop_update_pointers(ParCompactionManager* cm, oop obj) = 0;
#else  // INCLUDE_ALL_GCS
#define PARALLEL_GC_DECLS
#define PARALLEL_GC_DECLS_PV
#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_OOPS_KLASSPS_HPP
C:\hotspot-69087d08d473\src\share\vm/oops/klassVtable.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "memory/gcLocker.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klassVtable.hpp"
#include "oops/method.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/copy.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值