src/share/vm/memory/heapInspection.hpp

Print this page

        

@@ -186,29 +186,50 @@
   KlassInfoEntry* _next;
   Klass*          _klass;
   long            _instance_count;
   size_t          _instance_words;
   long            _index;
+  long            _super_index;
+  GrowableArray<KlassInfoEntry*>* _subclasses;
 
  public:
   KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
-    _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1)
+    _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1),
+    _super_index(-1), _subclasses(NULL)
   {}
+  ~KlassInfoEntry();
   KlassInfoEntry* next() const   { return _next; }
   bool is_equal(const Klass* k)  { return k == _klass; }
   Klass* klass()  const      { return _klass; }
   long count()    const      { return _instance_count; }
   void set_count(long ct)    { _instance_count = ct; }
   size_t words()  const      { return _instance_words; }
   void set_words(size_t wds) { _instance_words = wds; }
   void set_index(long index) { _index = index; }
   long index()    const      { return _index; }
+  void set_super_index(long index) { _super_index = index; }
+  long super_index() const   { return _super_index; }
+  GrowableArray<KlassInfoEntry*>* subclasses() const { return _subclasses; }
+  void add_subclass(KlassInfoEntry* cie);
   int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
   void print_on(outputStream* st) const;
   const char* name() const;
 };
 
+inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie) {
+  if (_subclasses == NULL) {
+    _subclasses = new  (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(4, true);
+  }
+  _subclasses->append(cie);
+}
+
+inline KlassInfoEntry::~KlassInfoEntry() {
+  if (_subclasses != NULL) {
+    delete _subclasses;
+  }
+}
+
 class KlassInfoClosure : public StackObj {
  public:
   // Called for each KlassInfoEntry.
   virtual void do_cinfo(KlassInfoEntry* cie) = 0;
 };

@@ -246,18 +267,30 @@
     AllClassesFinder(KlassInfoTable* table) : _table(table) {}
     virtual void do_klass(Klass* k);
   };
 
  public:
-  KlassInfoTable(bool need_class_stats);
+  KlassInfoTable(bool add_all_classes);
   ~KlassInfoTable();
   bool record_instance(const oop obj);
   void iterate(KlassInfoClosure* cic);
   bool allocation_failed() { return _buckets == NULL; }
   size_t size_of_instances_in_words() const;
 
   friend class KlassInfoHisto;
+  friend class KlassHierarchy;
+};
+
+class KlassHierarchy : public StackObj {
+ public:
+  KlassHierarchy(KlassInfoTable* cit, const char* title);
+  ~KlassHierarchy();
+  static void print_class_hierarchy(outputStream* st);
+
+private:
+  static void print_class(outputStream* st, KlassInfoEntry* cie,
+                          Stack <KlassInfoEntry*, mtClass> *super_stack);
 };
 
 class KlassInfoHisto : public StackObj {
  private:
   static const int _histo_initial_size = 1000;