< prev index next >

src/hotspot/share/memory/heapInspection.cpp

Print this page




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/classLoaderData.inline.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/moduleEntry.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "memory/heapInspection.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "memory/universe.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/reflectionAccessorImplKlassHelper.hpp"

  36 #include "runtime/os.hpp"

  37 #include "utilities/globalDefinitions.hpp"
  38 #include "utilities/macros.hpp"
  39 #include "utilities/stack.inline.hpp"
  40 
  41 // HeapInspection
  42 
  43 int KlassSizeStats::count(oop x) {
  44   return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
  45 }
  46 
  47 int KlassSizeStats::count_array(objArrayOop x) {
  48   return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
  49 }
  50 
  51 inline KlassInfoEntry::~KlassInfoEntry() {
  52   if (_subclasses != NULL) {
  53     delete _subclasses;
  54   }
  55 }
  56 


 673   if (print_stats) {
 674     print_class_stats(st, csv_format, columns);
 675   } else {
 676     st->print_cr(" num     #instances         #bytes  class name (module)");
 677     st->print_cr("-------------------------------------------------------");
 678     print_elements(st);
 679   }
 680 }
 681 
 682 class HistoClosure : public KlassInfoClosure {
 683  private:
 684   KlassInfoHisto* _cih;
 685  public:
 686   HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
 687 
 688   void do_cinfo(KlassInfoEntry* cie) {
 689     _cih->add(cie);
 690   }
 691 };
 692 




































































































































 693 class RecordInstanceClosure : public ObjectClosure {
 694  private:
 695   KlassInfoTable* _cit;
 696   size_t _missed_count;
 697   BoolObjectClosure* _filter;
 698  public:
 699   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 700     _cit(cit), _missed_count(0), _filter(filter) {}
 701 
 702   void do_object(oop obj) {
 703     if (should_visit(obj)) {
 704       if (!_cit->record_instance(obj)) {
 705         _missed_count++;
 706       }
 707     }
 708   }
 709 
 710   size_t missed_count() { return _missed_count; }
 711 
 712  private:




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/classLoaderData.inline.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/moduleEntry.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "memory/heapInspection.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "memory/universe.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/reflectionAccessorImplKlassHelper.hpp"
  36 #include "oops/valueKlass.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/fieldDescriptor.inline.hpp"
  39 #include "utilities/globalDefinitions.hpp"
  40 #include "utilities/macros.hpp"
  41 #include "utilities/stack.inline.hpp"
  42 
  43 // HeapInspection
  44 
  45 int KlassSizeStats::count(oop x) {
  46   return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
  47 }
  48 
  49 int KlassSizeStats::count_array(objArrayOop x) {
  50   return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
  51 }
  52 
  53 inline KlassInfoEntry::~KlassInfoEntry() {
  54   if (_subclasses != NULL) {
  55     delete _subclasses;
  56   }
  57 }
  58 


 675   if (print_stats) {
 676     print_class_stats(st, csv_format, columns);
 677   } else {
 678     st->print_cr(" num     #instances         #bytes  class name (module)");
 679     st->print_cr("-------------------------------------------------------");
 680     print_elements(st);
 681   }
 682 }
 683 
 684 class HistoClosure : public KlassInfoClosure {
 685  private:
 686   KlassInfoHisto* _cih;
 687  public:
 688   HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
 689 
 690   void do_cinfo(KlassInfoEntry* cie) {
 691     _cih->add(cie);
 692   }
 693 };
 694 
 695 
 696 class FindClassByNameClosure : public KlassInfoClosure {
 697  private:
 698   GrowableArray<Klass*>* _klasses;
 699   Symbol* _classname;
 700  public:
 701   FindClassByNameClosure(GrowableArray<Klass*>* klasses, Symbol* classname) :
 702     _klasses(klasses), _classname(classname) { }
 703 
 704   void do_cinfo(KlassInfoEntry* cie) {
 705     if (cie->klass()->name() == _classname) {
 706       _klasses->append(cie->klass());
 707     }
 708   }
 709 };
 710 
 711 class FieldDesc {
 712 private:
 713   Symbol* _name;
 714   Symbol* _signature;
 715   int _offset;
 716   int _index;
 717   InstanceKlass* _holder;
 718   AccessFlags _access_flags;
 719  public:
 720   FieldDesc() {
 721     _name = NULL;
 722     _signature = NULL;
 723     _offset = -1;
 724     _index = -1;
 725     _holder = NULL;
 726     _access_flags = AccessFlags();
 727   }
 728   FieldDesc(fieldDescriptor& fd) {
 729     _name = fd.name();
 730     _signature = fd.signature();
 731     _offset = fd.offset();
 732     _index = fd.index();
 733     _holder = fd.field_holder();
 734     _access_flags = fd.access_flags();
 735   }
 736   const Symbol* name() { return _name;}
 737   const Symbol* signature() { return _signature; }
 738   const int offset() { return _offset; }
 739   const int index() { return _index; }
 740   const InstanceKlass* holder() { return _holder; }
 741   const AccessFlags& access_flags() { return _access_flags; }
 742   const bool is_flattenable() { return _access_flags.is_flattenable(); }
 743 };
 744 
 745 static int compare_offset(FieldDesc* f1, FieldDesc* f2) {
 746    return f1->offset() > f2->offset() ? 1 : -1;
 747 }
 748 
 749 static void print_field(outputStream* st, int level, int offset, FieldDesc& fd, bool flattenable, bool flattened ) {
 750   const char* flattened_msg = "";
 751   if (flattenable) {
 752     flattened_msg = flattened ? "and flattened" : "not flattened";
 753   }
 754   st->print_cr("  @ %d %*s \"%s\" %s %s %s",
 755       offset, level * 3, "",
 756       fd.name()->as_C_string(),
 757       fd.signature()->as_C_string(),
 758       flattenable ? " // flattenable" : "",
 759       flattened_msg);
 760 }
 761 
 762 static void print_flattened_field(outputStream* st, int level, int offset, InstanceKlass* klass) {
 763   assert(klass->is_value(), "Only value classes can be flattened");
 764   ValueKlass* vklass = ValueKlass::cast(klass);
 765   GrowableArray<FieldDesc>* fields = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FieldDesc>(100, true);
 766   for (FieldStream fd(klass, false, false); !fd.eos(); fd.next()) {
 767     if (!fd.access_flags().is_static()) {
 768       fields->append(FieldDesc(fd.field_descriptor()));
 769     }
 770   }
 771   fields->sort(compare_offset);
 772   for(int i = 0; i < fields->length(); i++) {
 773     FieldDesc fd = fields->at(i);
 774     int offset2 = offset + fd.offset() - vklass->first_field_offset();
 775     print_field(st, level, offset2, fd,
 776         fd.is_flattenable(), fd.holder()->field_is_flattened(fd.index()));
 777     if (fd.holder()->field_is_flattened(fd.index())) {
 778       print_flattened_field(st, level + 1, offset2 ,
 779           InstanceKlass::cast(fd.holder()->get_value_field_klass(fd.index())));
 780     }
 781   }
 782 }
 783 
 784 void PrintClassLayout::print_class_layout(outputStream* st, char* class_name) {
 785   KlassInfoTable cit(true);
 786   if (cit.allocation_failed()) {
 787     st->print_cr("ERROR: Ran out of C-heap; hierarchy not generated");
 788     return;
 789   }
 790 
 791   Thread* THREAD = Thread::current();
 792 
 793   Symbol* classname = SymbolTable::probe(class_name, strlen(class_name));
 794 
 795   GrowableArray<Klass*>* klasses = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(100, true);
 796 
 797   FindClassByNameClosure fbnc(klasses, classname);
 798   cit.iterate(&fbnc);
 799 
 800   for(int i = 0; i < klasses->length(); i++) {
 801     Klass* klass = klasses->at(i);
 802     if (!klass->is_instance_klass()) continue;  // Skip
 803     InstanceKlass* ik = InstanceKlass::cast(klass);
 804     int tab = 1;
 805     st->print_cr("Class %s [@%s]:", klass->name()->as_C_string(),
 806         klass->class_loader_data()->name()->as_C_string());
 807     ResourceMark rm;
 808     GrowableArray<FieldDesc>* fields = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FieldDesc>(100, true);
 809     for (FieldStream fd(ik, false, false); !fd.eos(); fd.next()) {
 810       if (!fd.access_flags().is_static()) {
 811         fields->append(FieldDesc(fd.field_descriptor()));
 812       }
 813     }
 814     fields->sort(compare_offset);
 815     for(int i = 0; i < fields->length(); i++) {
 816       FieldDesc fd = fields->at(i);
 817       print_field(st, 0, fd.offset(), fd, fd.is_flattenable(), fd.holder()->field_is_flattened(fd.index()));
 818       if (fd.holder()->field_is_flattened(fd.index())) {
 819         print_flattened_field(st, 1, fd.offset(),
 820             InstanceKlass::cast(fd.holder()->get_value_field_klass(fd.index())));
 821       }
 822     }
 823   }
 824   st->cr();
 825 }
 826 
 827 class RecordInstanceClosure : public ObjectClosure {
 828  private:
 829   KlassInfoTable* _cit;
 830   size_t _missed_count;
 831   BoolObjectClosure* _filter;
 832  public:
 833   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 834     _cit(cit), _missed_count(0), _filter(filter) {}
 835 
 836   void do_object(oop obj) {
 837     if (should_visit(obj)) {
 838       if (!_cit->record_instance(obj)) {
 839         _missed_count++;
 840       }
 841     }
 842   }
 843 
 844   size_t missed_count() { return _missed_count; }
 845 
 846  private:


< prev index next >