1 /* |
1 /* |
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2019, 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. |
684 // fixes up the length of the current dump record |
684 // fixes up the length of the current dump record |
685 static void write_current_dump_record_length(DumpWriter* writer); |
685 static void write_current_dump_record_length(DumpWriter* writer); |
686 |
686 |
687 // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record |
687 // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record |
688 static void end_of_dump(DumpWriter* writer); |
688 static void end_of_dump(DumpWriter* writer); |
|
689 |
|
690 static oop mask_dormant_archived_object(oop o) { |
|
691 if (o != NULL && o->klass()->java_mirror() == NULL) { |
|
692 // Ignore this object since the corresponding java mirror is not loaded. |
|
693 // Might be a dormant archive object. |
|
694 return NULL; |
|
695 } else { |
|
696 return o; |
|
697 } |
|
698 } |
689 }; |
699 }; |
690 |
700 |
691 // write a header of the given type |
701 // write a header of the given type |
692 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) { |
702 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) { |
693 writer->write_u1((u1)tag); |
703 writer->write_u1((u1)tag); |
759 void DumperSupport::dump_field_value(DumpWriter* writer, char type, oop obj, int offset) { |
769 void DumperSupport::dump_field_value(DumpWriter* writer, char type, oop obj, int offset) { |
760 switch (type) { |
770 switch (type) { |
761 case JVM_SIGNATURE_CLASS : |
771 case JVM_SIGNATURE_CLASS : |
762 case JVM_SIGNATURE_ARRAY : { |
772 case JVM_SIGNATURE_ARRAY : { |
763 oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset); |
773 oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset); |
|
774 if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) { |
|
775 ResourceMark rm; |
|
776 log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)", |
|
777 p2i(o), o->klass()->external_name(), |
|
778 p2i(obj), obj->klass()->external_name()); |
|
779 } |
|
780 o = mask_dormant_archived_object(o); |
764 assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o)); |
781 assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o)); |
765 writer->write_objectID(o); |
782 writer->write_objectID(o); |
766 break; |
783 break; |
767 } |
784 } |
768 case JVM_SIGNATURE_BYTE : { |
785 case JVM_SIGNATURE_BYTE : { |
956 } |
973 } |
957 |
974 |
958 // creates HPROF_GC_INSTANCE_DUMP record for the given object |
975 // creates HPROF_GC_INSTANCE_DUMP record for the given object |
959 void DumperSupport::dump_instance(DumpWriter* writer, oop o) { |
976 void DumperSupport::dump_instance(DumpWriter* writer, oop o) { |
960 Klass* k = o->klass(); |
977 Klass* k = o->klass(); |
961 if (k->java_mirror() == NULL) { |
|
962 // Ignoring this object since the corresponding java mirror is not loaded. |
|
963 // Might be a dormant archive object. |
|
964 return; |
|
965 } |
|
966 |
978 |
967 writer->write_u1(HPROF_GC_INSTANCE_DUMP); |
979 writer->write_u1(HPROF_GC_INSTANCE_DUMP); |
968 writer->write_objectID(o); |
980 writer->write_objectID(o); |
969 writer->write_u4(STACK_TRACE_ID); |
981 writer->write_u4(STACK_TRACE_ID); |
970 |
982 |
1146 writer->write_classID(array->klass()); |
1158 writer->write_classID(array->klass()); |
1147 |
1159 |
1148 // [id]* elements |
1160 // [id]* elements |
1149 for (int index = 0; index < length; index++) { |
1161 for (int index = 0; index < length; index++) { |
1150 oop o = array->obj_at(index); |
1162 oop o = array->obj_at(index); |
|
1163 if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) { |
|
1164 ResourceMark rm; |
|
1165 log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)", |
|
1166 p2i(o), o->klass()->external_name(), |
|
1167 p2i(array), array->klass()->external_name()); |
|
1168 } |
|
1169 o = mask_dormant_archived_object(o); |
1151 writer->write_objectID(o); |
1170 writer->write_objectID(o); |
1152 } |
1171 } |
1153 } |
1172 } |
1154 |
1173 |
1155 #define WRITE_ARRAY(Array, Type, Size, Length) \ |
1174 #define WRITE_ARRAY(Array, Type, Size, Length) \ |
1423 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records |
1442 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records |
1424 if (o->klass() == SystemDictionary::Class_klass()) { |
1443 if (o->klass() == SystemDictionary::Class_klass()) { |
1425 if (!java_lang_Class::is_primitive(o)) { |
1444 if (!java_lang_Class::is_primitive(o)) { |
1426 return; |
1445 return; |
1427 } |
1446 } |
|
1447 } |
|
1448 |
|
1449 if (DumperSupport::mask_dormant_archived_object(o) == NULL) { |
|
1450 log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", p2i(o), o->klass()->external_name()); |
|
1451 return; |
1428 } |
1452 } |
1429 |
1453 |
1430 if (o->is_instance()) { |
1454 if (o->is_instance()) { |
1431 // create a HPROF_GC_INSTANCE record for each object |
1455 // create a HPROF_GC_INSTANCE record for each object |
1432 DumperSupport::dump_instance(writer(), o); |
1456 DumperSupport::dump_instance(writer(), o); |