< 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   Symbol* name() { return _name;}
 737   Symbol* signature() { return _signature; }
 738   int offset() { return _offset; }
 739   int index() { return _index; }
 740   InstanceKlass* holder() { return _holder; }
 741   AccessFlags access_flags() { return _access_flags; }
 742 };
 743 
 744 static int compare_offset(FieldDesc* f1, FieldDesc* f2) {
 745    return f1->offset() > f2->offset() ? 1 : -1;
 746 }
 747 
 748 static void print_field(outputStream* st, int level, int offset, FieldDesc& fd, bool flattenable, bool flattened ) {
 749   char* flattened_msg = (char*)"";
 750   if (flattenable) {
 751     flattened_msg = flattened ? (char*)"and flattened" : (char*)"not flattened";
 752   }
 753   st->print_cr("  @ %d %*s \"%s\" %s %s %s",
 754       offset, level * 3, "",
 755       fd.name()->as_C_string(),
 756       fd.signature()->as_C_string(),
 757       flattenable ? " // flattenable" : "",
 758       flattened_msg);
 759 }
 760 
 761 static void print_flattened_field(outputStream* st, int level, int offset, InstanceKlass* klass) {
 762   assert(klass->is_value(), "Only value classes can be flattened");
 763   ValueKlass* vklass = ValueKlass::cast(klass);
 764   GrowableArray<FieldDesc>* fields = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FieldDesc>(100, true);
 765   for (FieldStream fd(klass, false, false); !fd.eos(); fd.next()) {
 766     if (!fd.access_flags().is_static()) {
 767       fields->append(FieldDesc(fd.field_descriptor()));
 768     }
 769   }
 770   fields->sort(compare_offset);
 771   for(int i = 0; i < fields->length(); i++) {
 772     FieldDesc fd = fields->at(i);
 773     int offset2 = offset + fd.offset() - vklass->first_field_offset();
 774     print_field(st, level, offset2, fd,
 775         fd.access_flags().is_flattenable(), fd.holder()->field_is_flattened(fd.index()));
 776     if (fd.holder()->field_is_flattened(fd.index())) {
 777       print_flattened_field(st, level + 1, offset2 ,
 778           InstanceKlass::cast(fd.holder()->get_value_field_klass(fd.index())));
 779     }
 780   }
 781 }
 782 
 783 void PrintClassLayout::print_class_layout(outputStream* st, char* class_name) {
 784   KlassInfoTable cit(true);
 785   if (cit.allocation_failed()) {
 786     st->print_cr("ERROR: Ran out of C-heap; hierarchy not generated");
 787     return;
 788   }
 789 
 790   Thread* THREAD = Thread::current();
 791 
 792   Symbol* classname = SymbolTable::probe(class_name, strlen(class_name));
 793 
 794   GrowableArray<Klass*>* klasses = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(100, true);
 795 
 796   FindClassByNameClosure fbnc(klasses, classname);
 797   cit.iterate(&fbnc);
 798 
 799   for(int i = 0; i < klasses->length(); i++) {
 800     Klass* klass = klasses->at(i);
 801     if (!klass->is_instance_klass()) continue;  // Skip
 802     InstanceKlass* ik = InstanceKlass::cast(klass);
 803     int tab = 1;
 804     st->print_cr("Class %s [@%s]:", klass->name()->as_C_string(),
 805         klass->class_loader_data()->name()->as_C_string());
 806     ResourceMark rm;
 807     GrowableArray<FieldDesc>* fields = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FieldDesc>(100, true);
 808     for (FieldStream fd(ik, false, false); !fd.eos(); fd.next()) {
 809       if (!fd.access_flags().is_static()) {
 810         fields->append(FieldDesc(fd.field_descriptor()));
 811       }
 812     }
 813     fields->sort(compare_offset);
 814     for(int i = 0; i < fields->length(); i++) {
 815       FieldDesc fd = fields->at(i);
 816       print_field(st, 0, fd.offset(), fd, fd.access_flags().is_flattenable(), fd.holder()->field_is_flattened(fd.index()));
 817       if (fd.holder()->field_is_flattened(fd.index())) {
 818         print_flattened_field(st, 1, fd.offset(),
 819             InstanceKlass::cast(fd.holder()->get_value_field_klass(fd.index())));
 820       }
 821     }
 822   }
 823   st->cr();
 824 }
 825 
 826 class RecordInstanceClosure : public ObjectClosure {
 827  private:
 828   KlassInfoTable* _cit;
 829   size_t _missed_count;
 830   BoolObjectClosure* _filter;
 831  public:
 832   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 833     _cit(cit), _missed_count(0), _filter(filter) {}
 834 
 835   void do_object(oop obj) {
 836     if (should_visit(obj)) {
 837       if (!_cit->record_instance(obj)) {
 838         _missed_count++;
 839       }
 840     }
 841   }
 842 
 843   size_t missed_count() { return _missed_count; }
 844 
 845  private:


< prev index next >