Mercurial > hg > truffle
comparison src/share/vm/services/heapDumper.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | d8ce2825b193 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
606 static hprofTag sig2tag(Symbol* sig); | 606 static hprofTag sig2tag(Symbol* sig); |
607 // returns hprof tag for the given basic type | 607 // returns hprof tag for the given basic type |
608 static hprofTag type2tag(BasicType type); | 608 static hprofTag type2tag(BasicType type); |
609 | 609 |
610 // returns the size of the instance of the given class | 610 // returns the size of the instance of the given class |
611 static u4 instance_size(klassOop k); | 611 static u4 instance_size(Klass* k); |
612 | 612 |
613 // dump a jfloat | 613 // dump a jfloat |
614 static void dump_float(DumpWriter* writer, jfloat f); | 614 static void dump_float(DumpWriter* writer, jfloat f); |
615 // dump a jdouble | 615 // dump a jdouble |
616 static void dump_double(DumpWriter* writer, jdouble d); | 616 static void dump_double(DumpWriter* writer, jdouble d); |
617 // dumps the raw value of the given field | 617 // dumps the raw value of the given field |
618 static void dump_field_value(DumpWriter* writer, char type, address addr); | 618 static void dump_field_value(DumpWriter* writer, char type, address addr); |
619 // dumps static fields of the given class | 619 // dumps static fields of the given class |
620 static void dump_static_fields(DumpWriter* writer, klassOop k); | 620 static void dump_static_fields(DumpWriter* writer, Klass* k); |
621 // dump the raw values of the instance fields of the given object | 621 // dump the raw values of the instance fields of the given object |
622 static void dump_instance_fields(DumpWriter* writer, oop o); | 622 static void dump_instance_fields(DumpWriter* writer, oop o); |
623 // dumps the definition of the instance fields for a given class | 623 // dumps the definition of the instance fields for a given class |
624 static void dump_instance_field_descriptors(DumpWriter* writer, klassOop k); | 624 static void dump_instance_field_descriptors(DumpWriter* writer, Klass* k); |
625 // creates HPROF_GC_INSTANCE_DUMP record for the given object | 625 // creates HPROF_GC_INSTANCE_DUMP record for the given object |
626 static void dump_instance(DumpWriter* writer, oop o); | 626 static void dump_instance(DumpWriter* writer, oop o); |
627 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its | 627 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its |
628 // array classes | 628 // array classes |
629 static void dump_class_and_array_classes(DumpWriter* writer, klassOop k); | 629 static void dump_class_and_array_classes(DumpWriter* writer, Klass* k); |
630 // creates HPROF_GC_CLASS_DUMP record for a given primitive array | 630 // creates HPROF_GC_CLASS_DUMP record for a given primitive array |
631 // class (and each multi-dimensional array class too) | 631 // class (and each multi-dimensional array class too) |
632 static void dump_basic_type_array_class(DumpWriter* writer, klassOop k); | 632 static void dump_basic_type_array_class(DumpWriter* writer, Klass* k); |
633 | 633 |
634 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array | 634 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array |
635 static void dump_object_array(DumpWriter* writer, objArrayOop array); | 635 static void dump_object_array(DumpWriter* writer, objArrayOop array); |
636 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array | 636 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array |
637 static void dump_prim_array(DumpWriter* writer, typeArrayOop array); | 637 static void dump_prim_array(DumpWriter* writer, typeArrayOop array); |
638 // create HPROF_FRAME record for the given method and bci | 638 // create HPROF_FRAME record for the given method and bci |
639 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, methodOop m, int bci); | 639 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci); |
640 }; | 640 }; |
641 | 641 |
642 // write a header of the given type | 642 // write a header of the given type |
643 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) { | 643 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) { |
644 writer->write_u1((u1)tag); | 644 writer->write_u1((u1)tag); |
717 } else { | 717 } else { |
718 o = oopDesc::load_decode_heap_oop((oop*)addr); | 718 o = oopDesc::load_decode_heap_oop((oop*)addr); |
719 } | 719 } |
720 | 720 |
721 // reflection and sun.misc.Unsafe classes may have a reference to a | 721 // reflection and sun.misc.Unsafe classes may have a reference to a |
722 // klassOop so filter it out. | 722 // Klass* so filter it out. |
723 if (o != NULL && o->is_klass()) { | 723 assert(o->is_oop_or_null(), "should always be an oop"); |
724 o = NULL; | |
725 } | |
726 | |
727 // FIXME: When sharing is enabled we don't emit field references to objects | |
728 // in shared spaces. We can remove this once we write records for the classes | |
729 // and strings that are shared. | |
730 if (o != NULL && o->is_shared()) { | |
731 o = NULL; | |
732 } | |
733 writer->write_objectID(o); | 724 writer->write_objectID(o); |
734 break; | 725 break; |
735 } | 726 } |
736 case JVM_SIGNATURE_BYTE : { | 727 case JVM_SIGNATURE_BYTE : { |
737 jbyte* b = (jbyte*)addr; | 728 jbyte* b = (jbyte*)addr; |
776 default : ShouldNotReachHere(); | 767 default : ShouldNotReachHere(); |
777 } | 768 } |
778 } | 769 } |
779 | 770 |
780 // returns the size of the instance of the given class | 771 // returns the size of the instance of the given class |
781 u4 DumperSupport::instance_size(klassOop k) { | 772 u4 DumperSupport::instance_size(Klass* k) { |
782 HandleMark hm; | 773 HandleMark hm; |
783 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); | 774 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); |
784 | 775 |
785 int size = 0; | 776 int size = 0; |
786 | 777 |
809 } | 800 } |
810 return (u4)size; | 801 return (u4)size; |
811 } | 802 } |
812 | 803 |
813 // dumps static fields of the given class | 804 // dumps static fields of the given class |
814 void DumperSupport::dump_static_fields(DumpWriter* writer, klassOop k) { | 805 void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) { |
815 HandleMark hm; | 806 HandleMark hm; |
816 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); | 807 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); |
817 | 808 |
818 // pass 1 - count the static fields | 809 // pass 1 - count the static fields |
819 u2 field_count = 0; | 810 u2 field_count = 0; |
854 } | 845 } |
855 } | 846 } |
856 } | 847 } |
857 | 848 |
858 // dumps the definition of the instance fields for a given class | 849 // dumps the definition of the instance fields for a given class |
859 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, klassOop k) { | 850 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) { |
860 HandleMark hm; | 851 HandleMark hm; |
861 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); | 852 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); |
862 | 853 |
863 // pass 1 - count the instance fields | 854 // pass 1 - count the instance fields |
864 u2 field_count = 0; | 855 u2 field_count = 0; |
879 } | 870 } |
880 } | 871 } |
881 | 872 |
882 // creates HPROF_GC_INSTANCE_DUMP record for the given object | 873 // creates HPROF_GC_INSTANCE_DUMP record for the given object |
883 void DumperSupport::dump_instance(DumpWriter* writer, oop o) { | 874 void DumperSupport::dump_instance(DumpWriter* writer, oop o) { |
884 klassOop k = o->klass(); | 875 Klass* k = o->klass(); |
885 | 876 |
886 writer->write_u1(HPROF_GC_INSTANCE_DUMP); | 877 writer->write_u1(HPROF_GC_INSTANCE_DUMP); |
887 writer->write_objectID(o); | 878 writer->write_objectID(o); |
888 writer->write_u4(STACK_TRACE_ID); | 879 writer->write_u4(STACK_TRACE_ID); |
889 | 880 |
897 dump_instance_fields(writer, o); | 888 dump_instance_fields(writer, o); |
898 } | 889 } |
899 | 890 |
900 // creates HPROF_GC_CLASS_DUMP record for the given class and each of | 891 // creates HPROF_GC_CLASS_DUMP record for the given class and each of |
901 // its array classes | 892 // its array classes |
902 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, klassOop k) { | 893 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) { |
903 Klass* klass = Klass::cast(k); | 894 Klass* klass = Klass::cast(k); |
904 assert(klass->oop_is_instance(), "not an instanceKlass"); | 895 assert(klass->oop_is_instance(), "not an InstanceKlass"); |
905 instanceKlass* ik = (instanceKlass*)klass; | 896 InstanceKlass* ik = (InstanceKlass*)klass; |
906 | 897 |
907 writer->write_u1(HPROF_GC_CLASS_DUMP); | 898 writer->write_u1(HPROF_GC_CLASS_DUMP); |
908 | 899 |
909 // class ID | 900 // class ID |
910 writer->write_classID(ik); | 901 writer->write_classID(ik); |
911 writer->write_u4(STACK_TRACE_ID); | 902 writer->write_u4(STACK_TRACE_ID); |
912 | 903 |
913 // super class ID | 904 // super class ID |
914 klassOop java_super = ik->java_super(); | 905 Klass* java_super = ik->java_super(); |
915 if (java_super == NULL) { | 906 if (java_super == NULL) { |
916 writer->write_objectID(NULL); | 907 writer->write_objectID(oop(NULL)); |
917 } else { | 908 } else { |
918 writer->write_classID(Klass::cast(java_super)); | 909 writer->write_classID(Klass::cast(java_super)); |
919 } | 910 } |
920 | 911 |
921 writer->write_objectID(ik->class_loader()); | 912 writer->write_objectID(ik->class_loader()); |
922 writer->write_objectID(ik->signers()); | 913 writer->write_objectID(ik->signers()); |
923 writer->write_objectID(ik->protection_domain()); | 914 writer->write_objectID(ik->protection_domain()); |
924 | 915 |
925 // reserved | 916 // reserved |
926 writer->write_objectID(NULL); | 917 writer->write_objectID(oop(NULL)); |
927 writer->write_objectID(NULL); | 918 writer->write_objectID(oop(NULL)); |
928 | 919 |
929 // instance size | 920 // instance size |
930 writer->write_u4(DumperSupport::instance_size(k)); | 921 writer->write_u4(DumperSupport::instance_size(k)); |
931 | 922 |
932 // size of constant pool - ignored by HAT 1.1 | 923 // size of constant pool - ignored by HAT 1.1 |
955 | 946 |
956 writer->write_objectID(ik->class_loader()); | 947 writer->write_objectID(ik->class_loader()); |
957 writer->write_objectID(ik->signers()); | 948 writer->write_objectID(ik->signers()); |
958 writer->write_objectID(ik->protection_domain()); | 949 writer->write_objectID(ik->protection_domain()); |
959 | 950 |
960 writer->write_objectID(NULL); // reserved | 951 writer->write_objectID(oop(NULL)); // reserved |
961 writer->write_objectID(NULL); | 952 writer->write_objectID(oop(NULL)); |
962 writer->write_u4(0); // instance size | 953 writer->write_u4(0); // instance size |
963 writer->write_u2(0); // constant pool | 954 writer->write_u2(0); // constant pool |
964 writer->write_u2(0); // static fields | 955 writer->write_u2(0); // static fields |
965 writer->write_u2(0); // instance fields | 956 writer->write_u2(0); // instance fields |
966 | 957 |
969 } | 960 } |
970 } | 961 } |
971 | 962 |
972 // creates HPROF_GC_CLASS_DUMP record for a given primitive array | 963 // creates HPROF_GC_CLASS_DUMP record for a given primitive array |
973 // class (and each multi-dimensional array class too) | 964 // class (and each multi-dimensional array class too) |
974 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, klassOop k) { | 965 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) { |
975 // array classes | 966 // array classes |
976 while (k != NULL) { | 967 while (k != NULL) { |
977 Klass* klass = Klass::cast(k); | 968 Klass* klass = Klass::cast(k); |
978 | 969 |
979 writer->write_u1(HPROF_GC_CLASS_DUMP); | 970 writer->write_u1(HPROF_GC_CLASS_DUMP); |
980 writer->write_classID(klass); | 971 writer->write_classID(klass); |
981 writer->write_u4(STACK_TRACE_ID); | 972 writer->write_u4(STACK_TRACE_ID); |
982 | 973 |
983 // super class of array classes is java.lang.Object | 974 // super class of array classes is java.lang.Object |
984 klassOop java_super = klass->java_super(); | 975 Klass* java_super = klass->java_super(); |
985 assert(java_super != NULL, "checking"); | 976 assert(java_super != NULL, "checking"); |
986 writer->write_classID(Klass::cast(java_super)); | 977 writer->write_classID(Klass::cast(java_super)); |
987 | 978 |
988 writer->write_objectID(NULL); // loader | 979 writer->write_objectID(oop(NULL)); // loader |
989 writer->write_objectID(NULL); // signers | 980 writer->write_objectID(oop(NULL)); // signers |
990 writer->write_objectID(NULL); // protection domain | 981 writer->write_objectID(oop(NULL)); // protection domain |
991 | 982 |
992 writer->write_objectID(NULL); // reserved | 983 writer->write_objectID(oop(NULL)); // reserved |
993 writer->write_objectID(NULL); | 984 writer->write_objectID(oop(NULL)); |
994 writer->write_u4(0); // instance size | 985 writer->write_u4(0); // instance size |
995 writer->write_u2(0); // constant pool | 986 writer->write_u2(0); // constant pool |
996 writer->write_u2(0); // static fields | 987 writer->write_u2(0); // static fields |
997 writer->write_u2(0); // instance fields | 988 writer->write_u2(0); // instance fields |
998 | 989 |
1001 } | 992 } |
1002 } | 993 } |
1003 | 994 |
1004 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array | 995 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array |
1005 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) { | 996 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) { |
1006 | |
1007 // filter this | |
1008 if (array->klass() == Universe::systemObjArrayKlassObj()) return; | |
1009 | 997 |
1010 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP); | 998 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP); |
1011 writer->write_objectID(array); | 999 writer->write_objectID(array); |
1012 writer->write_u4(STACK_TRACE_ID); | 1000 writer->write_u4(STACK_TRACE_ID); |
1013 writer->write_u4((u4)array->length()); | 1001 writer->write_u4((u4)array->length()); |
1109 } | 1097 } |
1110 default : ShouldNotReachHere(); | 1098 default : ShouldNotReachHere(); |
1111 } | 1099 } |
1112 } | 1100 } |
1113 | 1101 |
1114 // create a HPROF_FRAME record of the given methodOop and bci | 1102 // create a HPROF_FRAME record of the given Method* and bci |
1115 void DumperSupport::dump_stack_frame(DumpWriter* writer, | 1103 void DumperSupport::dump_stack_frame(DumpWriter* writer, |
1116 int frame_serial_num, | 1104 int frame_serial_num, |
1117 int class_serial_num, | 1105 int class_serial_num, |
1118 methodOop m, | 1106 Method* m, |
1119 int bci) { | 1107 int bci) { |
1120 int line_number; | 1108 int line_number; |
1121 if (m->is_native()) { | 1109 if (m->is_native()) { |
1122 line_number = -3; // native frame | 1110 line_number = -3; // native frame |
1123 } else { | 1111 } else { |
1127 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4)); | 1115 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4)); |
1128 writer->write_id(frame_serial_num); // frame serial number | 1116 writer->write_id(frame_serial_num); // frame serial number |
1129 writer->write_symbolID(m->name()); // method's name | 1117 writer->write_symbolID(m->name()); // method's name |
1130 writer->write_symbolID(m->signature()); // method's signature | 1118 writer->write_symbolID(m->signature()); // method's signature |
1131 | 1119 |
1132 assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass"); | 1120 assert(Klass::cast(m->method_holder())->oop_is_instance(), "not InstanceKlass"); |
1133 writer->write_symbolID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name | 1121 writer->write_symbolID(InstanceKlass::cast(m->method_holder())->source_file_name()); // source file name |
1134 writer->write_u4(class_serial_num); // class serial number | 1122 writer->write_u4(class_serial_num); // class serial number |
1135 writer->write_u4((u4) line_number); // line number | 1123 writer->write_u4((u4) line_number); // line number |
1136 } | 1124 } |
1137 | 1125 |
1138 | 1126 |
1240 }; | 1228 }; |
1241 | 1229 |
1242 | 1230 |
1243 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records | 1231 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records |
1244 | 1232 |
1245 class StickyClassDumper : public OopClosure { | 1233 class StickyClassDumper : public KlassClosure { |
1246 private: | 1234 private: |
1247 DumpWriter* _writer; | 1235 DumpWriter* _writer; |
1248 DumpWriter* writer() const { return _writer; } | 1236 DumpWriter* writer() const { return _writer; } |
1249 public: | 1237 public: |
1250 StickyClassDumper(DumpWriter* writer) { | 1238 StickyClassDumper(DumpWriter* writer) { |
1251 _writer = writer; | 1239 _writer = writer; |
1252 } | 1240 } |
1253 void do_oop(oop* obj_p); | 1241 void do_klass(Klass* k) { |
1254 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } | 1242 if (k->oop_is_instance()) { |
1255 }; | 1243 InstanceKlass* ik = InstanceKlass::cast(k); |
1256 | |
1257 void StickyClassDumper::do_oop(oop* obj_p) { | |
1258 if (*obj_p != NULL) { | |
1259 oop o = *obj_p; | |
1260 if (o->is_klass()) { | |
1261 klassOop k = klassOop(o); | |
1262 if (Klass::cast(k)->oop_is_instance()) { | |
1263 instanceKlass* ik = instanceKlass::cast(k); | |
1264 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS); | 1244 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS); |
1265 writer()->write_classID(ik); | 1245 writer()->write_classID(ik); |
1266 } | 1246 } |
1267 } | 1247 } |
1268 } | 1248 }; |
1269 } | |
1270 | 1249 |
1271 | 1250 |
1272 class VM_HeapDumper; | 1251 class VM_HeapDumper; |
1273 | 1252 |
1274 // Support class using when iterating over the heap. | 1253 // Support class using when iterating over the heap. |
1295 }; | 1274 }; |
1296 | 1275 |
1297 void HeapObjectDumper::do_object(oop o) { | 1276 void HeapObjectDumper::do_object(oop o) { |
1298 // hide the sentinel for deleted handles | 1277 // hide the sentinel for deleted handles |
1299 if (o == JNIHandles::deleted_handle()) return; | 1278 if (o == JNIHandles::deleted_handle()) return; |
1300 | |
1301 // ignore KlassKlass objects | |
1302 if (o->is_klass()) return; | |
1303 | 1279 |
1304 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records | 1280 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records |
1305 if (o->klass() == SystemDictionary::Class_klass()) { | 1281 if (o->klass() == SystemDictionary::Class_klass()) { |
1306 if (!java_lang_Class::is_primitive(o)) { | 1282 if (!java_lang_Class::is_primitive(o)) { |
1307 return; | 1283 return; |
1332 private: | 1308 private: |
1333 static VM_HeapDumper* _global_dumper; | 1309 static VM_HeapDumper* _global_dumper; |
1334 static DumpWriter* _global_writer; | 1310 static DumpWriter* _global_writer; |
1335 DumpWriter* _local_writer; | 1311 DumpWriter* _local_writer; |
1336 JavaThread* _oome_thread; | 1312 JavaThread* _oome_thread; |
1337 methodOop _oome_constructor; | 1313 Method* _oome_constructor; |
1338 bool _gc_before_heap_dump; | 1314 bool _gc_before_heap_dump; |
1339 bool _is_segmented_dump; | 1315 bool _is_segmented_dump; |
1340 jlong _dump_start; | 1316 jlong _dump_start; |
1341 GrowableArray<Klass*>* _klass_map; | 1317 GrowableArray<Klass*>* _klass_map; |
1342 ThreadStackTrace** _stack_traces; | 1318 ThreadStackTrace** _stack_traces; |
1362 void set_dump_start(jlong pos); | 1338 void set_dump_start(jlong pos); |
1363 | 1339 |
1364 bool skip_operation() const; | 1340 bool skip_operation() const; |
1365 | 1341 |
1366 // writes a HPROF_LOAD_CLASS record | 1342 // writes a HPROF_LOAD_CLASS record |
1367 static void do_load_class(klassOop k); | 1343 static void do_load_class(Klass* k); |
1368 | 1344 |
1369 // writes a HPROF_GC_CLASS_DUMP record for the given class | 1345 // writes a HPROF_GC_CLASS_DUMP record for the given class |
1370 // (and each array class too) | 1346 // (and each array class too) |
1371 static void do_class_dump(klassOop k); | 1347 static void do_class_dump(Klass* k); |
1372 | 1348 |
1373 // writes a HPROF_GC_CLASS_DUMP records for a given basic type | 1349 // writes a HPROF_GC_CLASS_DUMP records for a given basic type |
1374 // array (and each multi-dimensional array too) | 1350 // array (and each multi-dimensional array too) |
1375 static void do_basic_type_array_class_dump(klassOop k); | 1351 static void do_basic_type_array_class_dump(Klass* k); |
1376 | 1352 |
1377 // HPROF_GC_ROOT_THREAD_OBJ records | 1353 // HPROF_GC_ROOT_THREAD_OBJ records |
1378 int do_thread(JavaThread* thread, u4 thread_serial_num); | 1354 int do_thread(JavaThread* thread, u4 thread_serial_num); |
1379 void do_threads(); | 1355 void do_threads(); |
1380 | 1356 |
1409 _stack_traces = NULL; | 1385 _stack_traces = NULL; |
1410 _num_threads = 0; | 1386 _num_threads = 0; |
1411 if (oome) { | 1387 if (oome) { |
1412 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread"); | 1388 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread"); |
1413 // get OutOfMemoryError zero-parameter constructor | 1389 // get OutOfMemoryError zero-parameter constructor |
1414 instanceKlass* oome_ik = instanceKlass::cast(SystemDictionary::OutOfMemoryError_klass()); | 1390 InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass()); |
1415 _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(), | 1391 _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(), |
1416 vmSymbols::void_method_signature()); | 1392 vmSymbols::void_method_signature()); |
1417 // get thread throwing OOME when generating the heap dump at OOME | 1393 // get thread throwing OOME when generating the heap dump at OOME |
1418 _oome_thread = JavaThread::current(); | 1394 _oome_thread = JavaThread::current(); |
1419 } else { | 1395 } else { |
1533 dumper()->check_segment_length(); | 1509 dumper()->check_segment_length(); |
1534 } | 1510 } |
1535 | 1511 |
1536 // writes a HPROF_LOAD_CLASS record for the class (and each of its | 1512 // writes a HPROF_LOAD_CLASS record for the class (and each of its |
1537 // array classes) | 1513 // array classes) |
1538 void VM_HeapDumper::do_load_class(klassOop k) { | 1514 void VM_HeapDumper::do_load_class(Klass* k) { |
1539 static u4 class_serial_num = 0; | 1515 static u4 class_serial_num = 0; |
1540 | 1516 |
1541 // len of HPROF_LOAD_CLASS record | 1517 // len of HPROF_LOAD_CLASS record |
1542 u4 remaining = 2*oopSize + 2*sizeof(u4); | 1518 u4 remaining = 2*oopSize + 2*sizeof(u4); |
1543 | 1519 |
1550 | 1526 |
1551 // class ID | 1527 // class ID |
1552 Klass* klass = Klass::cast(k); | 1528 Klass* klass = Klass::cast(k); |
1553 writer()->write_classID(klass); | 1529 writer()->write_classID(klass); |
1554 | 1530 |
1555 // add the klassOop and class serial number pair | 1531 // add the Klass* and class serial number pair |
1556 dumper()->add_class_serial_number(klass, class_serial_num); | 1532 dumper()->add_class_serial_number(klass, class_serial_num); |
1557 | 1533 |
1558 writer()->write_u4(STACK_TRACE_ID); | 1534 writer()->write_u4(STACK_TRACE_ID); |
1559 | 1535 |
1560 // class name ID | 1536 // class name ID |
1565 k = klass->array_klass_or_null(); | 1541 k = klass->array_klass_or_null(); |
1566 } while (k != NULL); | 1542 } while (k != NULL); |
1567 } | 1543 } |
1568 | 1544 |
1569 // writes a HPROF_GC_CLASS_DUMP record for the given class | 1545 // writes a HPROF_GC_CLASS_DUMP record for the given class |
1570 void VM_HeapDumper::do_class_dump(klassOop k) { | 1546 void VM_HeapDumper::do_class_dump(Klass* k) { |
1571 DumperSupport::dump_class_and_array_classes(writer(), k); | 1547 DumperSupport::dump_class_and_array_classes(writer(), k); |
1572 } | 1548 } |
1573 | 1549 |
1574 // writes a HPROF_GC_CLASS_DUMP records for a given basic type | 1550 // writes a HPROF_GC_CLASS_DUMP records for a given basic type |
1575 // array (and each multi-dimensional array too) | 1551 // array (and each multi-dimensional array too) |
1576 void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) { | 1552 void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) { |
1577 DumperSupport::dump_basic_type_array_class(writer(), k); | 1553 DumperSupport::dump_basic_type_array_class(writer(), k); |
1578 } | 1554 } |
1579 | 1555 |
1580 // Walk the stack of the given thread. | 1556 // Walk the stack of the given thread. |
1581 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local | 1557 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local |
1783 JNIHandles::oops_do(&jni_dumper); | 1759 JNIHandles::oops_do(&jni_dumper); |
1784 check_segment_length(); | 1760 check_segment_length(); |
1785 | 1761 |
1786 // HPROF_GC_ROOT_STICKY_CLASS | 1762 // HPROF_GC_ROOT_STICKY_CLASS |
1787 StickyClassDumper class_dumper(writer()); | 1763 StickyClassDumper class_dumper(writer()); |
1788 SystemDictionary::always_strong_oops_do(&class_dumper); | 1764 SystemDictionary::always_strong_classes_do(&class_dumper); |
1789 | 1765 |
1790 // fixes up the length of the dump record. In the case of a segmented | 1766 // fixes up the length of the dump record. In the case of a segmented |
1791 // heap then the HPROF_HEAP_DUMP_END record is also written. | 1767 // heap then the HPROF_HEAP_DUMP_END record is also written. |
1792 end_of_dump(); | 1768 end_of_dump(); |
1793 | 1769 |
1827 _oome_constructor, 0); | 1803 _oome_constructor, 0); |
1828 extra_frames++; | 1804 extra_frames++; |
1829 } | 1805 } |
1830 for (int j=0; j < depth; j++) { | 1806 for (int j=0; j < depth; j++) { |
1831 StackFrameInfo* frame = stack_trace->stack_frame_at(j); | 1807 StackFrameInfo* frame = stack_trace->stack_frame_at(j); |
1832 methodOop m = frame->method(); | 1808 Method* m = frame->method(); |
1833 int class_serial_num = _klass_map->find(Klass::cast(m->method_holder())); | 1809 int class_serial_num = _klass_map->find(Klass::cast(m->method_holder())); |
1834 // the class serial number starts from 1 | 1810 // the class serial number starts from 1 |
1835 assert(class_serial_num > 0, "class not found"); | 1811 assert(class_serial_num > 0, "class not found"); |
1836 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci()); | 1812 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci()); |
1837 } | 1813 } |