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: |