< prev index next >

src/hotspot/share/services/heapDumper.cpp

Print this page

  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "classfile/classLoaderData.inline.hpp"
  28 #include "classfile/classLoaderDataGraph.hpp"
  29 #include "classfile/javaClasses.inline.hpp"
  30 #include "classfile/symbolTable.hpp"
  31 #include "classfile/vmClasses.hpp"
  32 #include "classfile/vmSymbols.hpp"
  33 #include "gc/shared/gcLocker.hpp"
  34 #include "gc/shared/gcVMOperations.hpp"
  35 #include "gc/shared/workerThread.hpp"
  36 #include "jfr/jfrEvents.hpp"
  37 #include "memory/allocation.inline.hpp"
  38 #include "memory/resourceArea.hpp"
  39 #include "memory/universe.hpp"
  40 #include "oops/klass.inline.hpp"
  41 #include "oops/objArrayKlass.hpp"
  42 #include "oops/objArrayOop.inline.hpp"


  43 #include "oops/oop.inline.hpp"
  44 #include "oops/typeArrayOop.inline.hpp"

  45 #include "runtime/frame.inline.hpp"
  46 #include "runtime/handles.inline.hpp"
  47 #include "runtime/javaCalls.hpp"
  48 #include "runtime/jniHandles.hpp"
  49 #include "runtime/os.hpp"
  50 #include "runtime/reflectionUtils.hpp"
  51 #include "runtime/thread.inline.hpp"
  52 #include "runtime/threadSMR.hpp"
  53 #include "runtime/vframe.hpp"
  54 #include "runtime/vmOperations.hpp"
  55 #include "runtime/vmThread.hpp"
  56 #include "services/heapDumper.hpp"
  57 #include "services/heapDumperCompression.hpp"
  58 #include "services/threadService.hpp"
  59 #include "utilities/macros.hpp"
  60 #include "utilities/ostream.hpp"
  61 
  62 /*
  63  * HPROF binary format - description copied from:
  64  *   src/share/demo/jvmti/hprof/hprof_io.c

 291  *                                     7:  double array
 292  *                                     8:  byte array
 293  *                                     9:  short array
 294  *                                     10: int array
 295  *                                     11: long array
 296  *                          [u1]*      elements
 297  *
 298  * HPROF_CPU_SAMPLES        a set of sample traces of running threads
 299  *
 300  *                u4        total number of samples
 301  *                u4        # of traces
 302  *               [u4        # of samples
 303  *                u4]*      stack trace serial number
 304  *
 305  * HPROF_CONTROL_SETTINGS   the settings of on/off switches
 306  *
 307  *                u4        0x00000001: alloc traces on/off
 308  *                          0x00000002: cpu sampling on/off
 309  *                u2        stack trace depth
 310  *






















 311  *
 312  * When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
 313  * be generated as a sequence of heap dump segments. This sequence is
 314  * terminated by an end record. The additional tags allowed by format
 315  * "JAVA PROFILE 1.0.2" are:
 316  *
 317  * HPROF_HEAP_DUMP_SEGMENT  denote a heap dump segment
 318  *
 319  *               [heap dump sub-records]*
 320  *               The same sub-record types allowed by HPROF_HEAP_DUMP
 321  *
 322  * HPROF_HEAP_DUMP_END      denotes the end of a heap dump
 323  *
 324  */
 325 
 326 
 327 // HPROF tags
 328 
 329 enum hprofTag : u1 {
 330   // top-level records
 331   HPROF_UTF8                    = 0x01,
 332   HPROF_LOAD_CLASS              = 0x02,
 333   HPROF_UNLOAD_CLASS            = 0x03,
 334   HPROF_FRAME                   = 0x04,
 335   HPROF_TRACE                   = 0x05,
 336   HPROF_ALLOC_SITES             = 0x06,
 337   HPROF_HEAP_SUMMARY            = 0x07,
 338   HPROF_START_THREAD            = 0x0A,
 339   HPROF_END_THREAD              = 0x0B,
 340   HPROF_HEAP_DUMP               = 0x0C,
 341   HPROF_CPU_SAMPLES             = 0x0D,
 342   HPROF_CONTROL_SETTINGS        = 0x0E,
 343 
 344   // 1.0.2 record types
 345   HPROF_HEAP_DUMP_SEGMENT       = 0x1C,
 346   HPROF_HEAP_DUMP_END           = 0x2C,
 347 







 348   // field types
 349   HPROF_ARRAY_OBJECT            = 0x01,
 350   HPROF_NORMAL_OBJECT           = 0x02,
 351   HPROF_BOOLEAN                 = 0x04,
 352   HPROF_CHAR                    = 0x05,
 353   HPROF_FLOAT                   = 0x06,
 354   HPROF_DOUBLE                  = 0x07,
 355   HPROF_BYTE                    = 0x08,
 356   HPROF_SHORT                   = 0x09,
 357   HPROF_INT                     = 0x0A,
 358   HPROF_LONG                    = 0x0B,
 359 
 360   // data-dump sub-records
 361   HPROF_GC_ROOT_UNKNOWN         = 0xFF,
 362   HPROF_GC_ROOT_JNI_GLOBAL      = 0x01,
 363   HPROF_GC_ROOT_JNI_LOCAL       = 0x02,
 364   HPROF_GC_ROOT_JAVA_FRAME      = 0x03,
 365   HPROF_GC_ROOT_NATIVE_STACK    = 0x04,
 366   HPROF_GC_ROOT_STICKY_CLASS    = 0x05,
 367   HPROF_GC_ROOT_THREAD_BLOCK    = 0x06,
 368   HPROF_GC_ROOT_MONITOR_USED    = 0x07,
 369   HPROF_GC_ROOT_THREAD_OBJ      = 0x08,
 370   HPROF_GC_CLASS_DUMP           = 0x20,
 371   HPROF_GC_INSTANCE_DUMP        = 0x21,
 372   HPROF_GC_OBJ_ARRAY_DUMP       = 0x22,
 373   HPROF_GC_PRIM_ARRAY_DUMP      = 0x23
 374 };
 375 
 376 // Default stack trace ID (used for dummy HPROF_TRACE record)
 377 enum {
 378   STACK_TRACE_ID = 1,
 379   INITIAL_CLASS_COUNT = 200
 380 };
 381 

































































 382 // Supports I/O operations for a dump
 383 // Base class for dump and parallel dump
 384 class AbstractDumpWriter : public StackObj {
 385  protected:
 386   enum {
 387     io_buffer_max_size = 1*M,
 388     io_buffer_max_waste = 10*K,
 389     dump_segment_header_size = 9
 390   };
 391 
 392   char* _buffer;    // internal buffer
 393   size_t _size;
 394   size_t _pos;
 395 
 396   bool _in_dump_segment; // Are we currently in a dump segment?
 397   bool _is_huge_sub_record; // Are we writing a sub-record larger than the buffer size?
 398   DEBUG_ONLY(size_t _sub_record_left;) // The bytes not written for the current sub-record.
 399   DEBUG_ONLY(bool _sub_record_ended;) // True if we have called the end_sub_record().
 400 
 401   virtual void flush(bool force = false) = 0;

 874   }
 875 };
 876 
 877 Monitor* ParDumpWriter::_lock = NULL;
 878 
 879 // Support class with a collection of functions used when dumping the heap
 880 
 881 class DumperSupport : AllStatic {
 882  public:
 883 
 884   // write a header of the given type
 885   static void write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len);
 886 
 887   // returns hprof tag for the given type signature
 888   static hprofTag sig2tag(Symbol* sig);
 889   // returns hprof tag for the given basic type
 890   static hprofTag type2tag(BasicType type);
 891   // Returns the size of the data to write.
 892   static u4 sig2size(Symbol* sig);
 893 
 894   // returns the size of the instance of the given class
 895   static u4 instance_size(Klass* k);
 896 
 897   // dump a jfloat
 898   static void dump_float(AbstractDumpWriter* writer, jfloat f);
 899   // dump a jdouble
 900   static void dump_double(AbstractDumpWriter* writer, jdouble d);
 901   // dumps the raw value of the given field
 902   static void dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset);
 903   // returns the size of the static fields; also counts the static fields
 904   static u4 get_static_fields_size(InstanceKlass* ik, u2& field_count);
 905   // dumps static fields of the given class
 906   static void dump_static_fields(AbstractDumpWriter* writer, Klass* k);
 907   // dump the raw values of the instance fields of the given object
 908   static void dump_instance_fields(AbstractDumpWriter* writer, oop o);






 909   // get the count of the instance fields for a given class
 910   static u2 get_instance_fields_count(InstanceKlass* ik);
 911   // dumps the definition of the instance fields for a given class
 912   static void dump_instance_field_descriptors(AbstractDumpWriter* writer, Klass* k);
 913   // creates HPROF_GC_INSTANCE_DUMP record for the given object
 914   static void dump_instance(AbstractDumpWriter* writer, oop o);
 915   // creates HPROF_GC_CLASS_DUMP record for the given instance class
 916   static void dump_instance_class(AbstractDumpWriter* writer, Klass* k);
 917   // creates HPROF_GC_CLASS_DUMP record for a given array class
 918   static void dump_array_class(AbstractDumpWriter* writer, Klass* k);
 919 
 920   // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
 921   static void dump_object_array(AbstractDumpWriter* writer, objArrayOop array);


 922   // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
 923   static void dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array);
 924   // create HPROF_FRAME record for the given method and bci
 925   static void dump_stack_frame(AbstractDumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
 926 
 927   // check if we need to truncate an array
 928   static int calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size);



 929 
 930   // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
 931   static void end_of_dump(AbstractDumpWriter* writer);
 932 
 933   static oop mask_dormant_archived_object(oop o) {
 934     if (o != NULL && o->klass()->java_mirror() == NULL) {
 935       // Ignore this object since the corresponding java mirror is not loaded.
 936       // Might be a dormant archive object.
 937       return NULL;
 938     } else {
 939       return o;
 940     }
 941   }










 942 };
 943 
 944 // write a header of the given type
 945 void DumperSupport:: write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len) {
 946   writer->write_u1(tag);
 947   writer->write_u4(0);                  // current ticks
 948   writer->write_u4(len);
 949 }
 950 
 951 // returns hprof tag for the given type signature
 952 hprofTag DumperSupport::sig2tag(Symbol* sig) {
 953   switch (sig->char_at(0)) {
 954     case JVM_SIGNATURE_CLASS    : return HPROF_NORMAL_OBJECT;

 955     case JVM_SIGNATURE_ARRAY    : return HPROF_NORMAL_OBJECT;
 956     case JVM_SIGNATURE_BYTE     : return HPROF_BYTE;
 957     case JVM_SIGNATURE_CHAR     : return HPROF_CHAR;
 958     case JVM_SIGNATURE_FLOAT    : return HPROF_FLOAT;
 959     case JVM_SIGNATURE_DOUBLE   : return HPROF_DOUBLE;
 960     case JVM_SIGNATURE_INT      : return HPROF_INT;
 961     case JVM_SIGNATURE_LONG     : return HPROF_LONG;
 962     case JVM_SIGNATURE_SHORT    : return HPROF_SHORT;
 963     case JVM_SIGNATURE_BOOLEAN  : return HPROF_BOOLEAN;
 964     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
 965   }
 966 }
 967 
 968 hprofTag DumperSupport::type2tag(BasicType type) {
 969   switch (type) {
 970     case T_BYTE     : return HPROF_BYTE;
 971     case T_CHAR     : return HPROF_CHAR;
 972     case T_FLOAT    : return HPROF_FLOAT;
 973     case T_DOUBLE   : return HPROF_DOUBLE;
 974     case T_INT      : return HPROF_INT;
 975     case T_LONG     : return HPROF_LONG;
 976     case T_SHORT    : return HPROF_SHORT;
 977     case T_BOOLEAN  : return HPROF_BOOLEAN;
 978     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
 979   }
 980 }
 981 
 982 u4 DumperSupport::sig2size(Symbol* sig) {
 983   switch (sig->char_at(0)) {
 984     case JVM_SIGNATURE_CLASS:

 985     case JVM_SIGNATURE_ARRAY: return sizeof(address);
 986     case JVM_SIGNATURE_BOOLEAN:
 987     case JVM_SIGNATURE_BYTE: return 1;
 988     case JVM_SIGNATURE_SHORT:
 989     case JVM_SIGNATURE_CHAR: return 2;
 990     case JVM_SIGNATURE_INT:
 991     case JVM_SIGNATURE_FLOAT: return 4;
 992     case JVM_SIGNATURE_LONG:
 993     case JVM_SIGNATURE_DOUBLE: return 8;
 994     default: ShouldNotReachHere(); /* to shut up compiler */ return 0;
 995   }
 996 }
 997 
 998 template<typename T, typename F> T bit_cast(F from) { // replace with the real thing when we can use c++20
 999   T to;
1000   static_assert(sizeof(to) == sizeof(from), "must be of the same size");
1001   memcpy(&to, &from, sizeof(to));
1002   return to;
1003 }
1004 
1005 // dump a jfloat
1006 void DumperSupport::dump_float(AbstractDumpWriter* writer, jfloat f) {
1007   if (g_isnan(f)) {
1008     writer->write_u4(0x7fc00000); // collapsing NaNs
1009   } else {
1010     writer->write_u4(bit_cast<u4>(f));
1011   }
1012 }
1013 
1014 // dump a jdouble
1015 void DumperSupport::dump_double(AbstractDumpWriter* writer, jdouble d) {
1016   if (g_isnan(d)) {
1017     writer->write_u8(0x7ff80000ull << 32); // collapsing NaNs
1018   } else {
1019     writer->write_u8(bit_cast<u8>(d));
1020   }
1021 }
1022 

1023 // dumps the raw value of the given field
1024 void DumperSupport::dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset) {
1025   switch (type) {
1026     case JVM_SIGNATURE_CLASS :

1027     case JVM_SIGNATURE_ARRAY : {
1028       oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset);
1029       if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
1030         ResourceMark rm;
1031         log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
1032                              p2i(o), o->klass()->external_name(),
1033                              p2i(obj), obj->klass()->external_name());
1034       }
1035       o = mask_dormant_archived_object(o);
1036       assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
1037       writer->write_objectID(o);
1038       break;
1039     }
1040     case JVM_SIGNATURE_BYTE : {
1041       jbyte b = obj->byte_field(offset);
1042       writer->write_u1(b);
1043       break;
1044     }
1045     case JVM_SIGNATURE_CHAR : {
1046       jchar c = obj->char_field(offset);

1067       writer->write_u4(i);
1068       break;
1069     }
1070     case JVM_SIGNATURE_LONG : {
1071       jlong l = obj->long_field(offset);
1072       writer->write_u8(l);
1073       break;
1074     }
1075     case JVM_SIGNATURE_BOOLEAN : {
1076       jboolean b = obj->bool_field(offset);
1077       writer->write_u1(b);
1078       break;
1079     }
1080     default : {
1081       ShouldNotReachHere();
1082       break;
1083     }
1084   }
1085 }
1086 
1087 // returns the size of the instance of the given class
1088 u4 DumperSupport::instance_size(Klass* k) {
1089   InstanceKlass* ik = InstanceKlass::cast(k);
1090   u4 size = 0;
1091 
1092   for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1093     if (!fld.access_flags().is_static()) {
1094       size += sig2size(fld.signature());




1095     }
1096   }
1097   return size;
1098 }
1099 
1100 u4 DumperSupport::get_static_fields_size(InstanceKlass* ik, u2& field_count) {
1101   field_count = 0;
1102   u4 size = 0;
1103 
1104   for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) {
1105     if (fldc.access_flags().is_static()) {


1106       field_count++;
1107       size += sig2size(fldc.signature());
1108     }
1109   }
1110 
1111   // Add in resolved_references which is referenced by the cpCache
1112   // The resolved_references is an array per InstanceKlass holding the
1113   // strings and other oops resolved from the constant pool.
1114   oop resolved_references = ik->constants()->resolved_references_or_null();
1115   if (resolved_references != NULL) {
1116     field_count++;
1117     size += sizeof(address);
1118 
1119     // Add in the resolved_references of the used previous versions of the class
1120     // in the case of RedefineClasses
1121     InstanceKlass* prev = ik->previous_versions();
1122     while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
1123       field_count++;
1124       size += sizeof(address);
1125       prev = prev->previous_versions();

1128 
1129   // Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]
1130   // arrays.
1131   oop init_lock = ik->init_lock();
1132   if (init_lock != NULL) {
1133     field_count++;
1134     size += sizeof(address);
1135   }
1136 
1137   // We write the value itself plus a name and a one byte type tag per field.
1138   return size + field_count * (sizeof(address) + 1);
1139 }
1140 
1141 // dumps static fields of the given class
1142 void DumperSupport::dump_static_fields(AbstractDumpWriter* writer, Klass* k) {
1143   InstanceKlass* ik = InstanceKlass::cast(k);
1144 
1145   // dump the field descriptors and raw values
1146   for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) {
1147     if (fld.access_flags().is_static()) {


1148       Symbol* sig = fld.signature();
1149 
1150       writer->write_symbolID(fld.name());   // name
1151       writer->write_u1(sig2tag(sig));       // type
1152 
1153       // value
1154       dump_field_value(writer, sig->char_at(0), ik->java_mirror(), fld.offset());
1155     }
1156   }
1157 
1158   // Add resolved_references for each class that has them
1159   oop resolved_references = ik->constants()->resolved_references_or_null();
1160   if (resolved_references != NULL) {
1161     writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1162     writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1163     writer->write_objectID(resolved_references);
1164 
1165     // Also write any previous versions
1166     InstanceKlass* prev = ik->previous_versions();
1167     while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
1168       writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1169       writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1170       writer->write_objectID(prev->constants()->resolved_references());
1171       prev = prev->previous_versions();
1172     }
1173   }
1174 
1175   // Add init lock to the end if the class is not yet initialized
1176   oop init_lock = ik->init_lock();
1177   if (init_lock != NULL) {
1178     writer->write_symbolID(vmSymbols::init_lock_name());         // name
1179     writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type
1180     writer->write_objectID(init_lock);
1181   }
1182 }
1183 
1184 // dump the raw values of the instance fields of the given object
1185 void DumperSupport::dump_instance_fields(AbstractDumpWriter* writer, oop o) {
1186   InstanceKlass* ik = InstanceKlass::cast(o->klass());
1187 
1188   for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1189     if (!fld.access_flags().is_static()) {
1190       Symbol* sig = fld.signature();
1191       dump_field_value(writer, sig->char_at(0), o, fld.offset());







1192     }
1193   }
1194 }
1195 
1196 // dumps the definition of the instance fields for a given class





1197 u2 DumperSupport::get_instance_fields_count(InstanceKlass* ik) {
1198   u2 field_count = 0;
1199 
1200   for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) {
1201     if (!fldc.access_flags().is_static()) field_count++;







1202   }
1203 
1204   return field_count;
1205 }
1206 
1207 // dumps the definition of the instance fields for a given class
1208 void DumperSupport::dump_instance_field_descriptors(AbstractDumpWriter* writer, Klass* k) {
1209   InstanceKlass* ik = InstanceKlass::cast(k);






1210 
1211   // dump the field descriptors
1212   for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) {
1213     if (!fld.access_flags().is_static()) {
1214       Symbol* sig = fld.signature();






















1215 
1216       writer->write_symbolID(fld.name());   // name
1217       writer->write_u1(sig2tag(sig));       // type

1218     }
1219   }
1220 }
1221 
1222 // creates HPROF_GC_INSTANCE_DUMP record for the given object
1223 void DumperSupport::dump_instance(AbstractDumpWriter* writer, oop o) {
1224   InstanceKlass* ik = InstanceKlass::cast(o->klass());
1225   u4 is = instance_size(ik);
1226   u4 size = 1 + sizeof(address) + 4 + sizeof(address) + 4 + is;
1227 
1228   writer->start_sub_record(HPROF_GC_INSTANCE_DUMP, size);
1229   writer->write_objectID(o);
1230   writer->write_u4(STACK_TRACE_ID);
1231 
1232   // class ID
1233   writer->write_classID(ik);
1234 
1235   // number of bytes that follow
1236   writer->write_u4(is);
1237 
1238   // field values
1239   dump_instance_fields(writer, o);
1240 
1241   writer->end_sub_record();
1242 }
1243 
1244 // creates HPROF_GC_CLASS_DUMP record for the given instance class
1245 void DumperSupport::dump_instance_class(AbstractDumpWriter* writer, Klass* k) {
1246   InstanceKlass* ik = InstanceKlass::cast(k);
1247 
1248   // We can safepoint and do a heap dump at a point where we have a Klass,
1249   // but no java mirror class has been setup for it. So we need to check
1250   // that the class is at least loaded, to avoid crash from a null mirror.
1251   if (!ik->is_loaded()) {
1252     return;
1253   }
1254 
1255   u2 static_fields_count = 0;
1256   u4 static_size = get_static_fields_size(ik, static_fields_count);
1257   u2 instance_fields_count = get_instance_fields_count(ik);
1258   u4 instance_fields_size = instance_fields_count * (sizeof(address) + 1);
1259   u4 size = 1 + sizeof(address) + 4 + 6 * sizeof(address) + 4 + 2 + 2 + static_size + 2 + instance_fields_size;

1264   writer->write_classID(ik);
1265   writer->write_u4(STACK_TRACE_ID);
1266 
1267   // super class ID
1268   InstanceKlass* java_super = ik->java_super();
1269   if (java_super == NULL) {
1270     writer->write_objectID(oop(NULL));
1271   } else {
1272     writer->write_classID(java_super);
1273   }
1274 
1275   writer->write_objectID(ik->class_loader());
1276   writer->write_objectID(ik->signers());
1277   writer->write_objectID(ik->protection_domain());
1278 
1279   // reserved
1280   writer->write_objectID(oop(NULL));
1281   writer->write_objectID(oop(NULL));
1282 
1283   // instance size
1284   writer->write_u4(DumperSupport::instance_size(ik));
1285 
1286   // size of constant pool - ignored by HAT 1.1
1287   writer->write_u2(0);
1288 
1289   // static fields
1290   writer->write_u2(static_fields_count);
1291   dump_static_fields(writer, ik);
1292 
1293   // description of instance fields
1294   writer->write_u2(instance_fields_count);
1295   dump_instance_field_descriptors(writer, ik);
1296 
1297   writer->end_sub_record();
1298 }
1299 
1300 // creates HPROF_GC_CLASS_DUMP record for the given array class
1301 void DumperSupport::dump_array_class(AbstractDumpWriter* writer, Klass* k) {
1302   InstanceKlass* ik = NULL; // bottom class for object arrays, NULL for primitive type arrays
1303   if (k->is_objArray_klass()) {
1304     Klass *bk = ObjArrayKlass::cast(k)->bottom_klass();

1318   assert(java_super != NULL, "checking");
1319   writer->write_classID(java_super);
1320 
1321   writer->write_objectID(ik == NULL ? oop(NULL) : ik->class_loader());
1322   writer->write_objectID(ik == NULL ? oop(NULL) : ik->signers());
1323   writer->write_objectID(ik == NULL ? oop(NULL) : ik->protection_domain());
1324 
1325   writer->write_objectID(oop(NULL));    // reserved
1326   writer->write_objectID(oop(NULL));
1327   writer->write_u4(0);             // instance size
1328   writer->write_u2(0);             // constant pool
1329   writer->write_u2(0);             // static fields
1330   writer->write_u2(0);             // instance fields
1331 
1332   writer->end_sub_record();
1333 
1334 }
1335 
1336 // Hprof uses an u4 as record length field,
1337 // which means we need to truncate arrays that are too long.
1338 int DumperSupport::calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size) {
1339   BasicType type = ArrayKlass::cast(array->klass())->element_type();
1340   assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
1341 
1342   int length = array->length();
1343 
1344   int type_size;
1345   if (type == T_OBJECT) {
1346     type_size = sizeof(address);
1347   } else {
1348     type_size = type2aelembytes(type);
1349   }
1350 
1351   size_t length_in_bytes = (size_t)length * type_size;
1352   uint max_bytes = max_juint - header_size;
1353 
1354   if (length_in_bytes > max_bytes) {
1355     length = max_bytes / type_size;
1356     length_in_bytes = (size_t)length * type_size;
1357 

1358     warning("cannot dump array of type %s[] with length %d; truncating to length %d",
1359             type2name_tab[type], array->length(), length);
1360   }
1361   return length;
1362 }
1363 













1364 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
1365 void DumperSupport::dump_object_array(AbstractDumpWriter* writer, objArrayOop array) {
1366   // sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)
1367   short header_size = 1 + 2 * 4 + 2 * sizeof(address);
1368   int length = calculate_array_max_length(writer, array, header_size);
1369   u4 size = header_size + length * sizeof(address);
1370 
1371   writer->start_sub_record(HPROF_GC_OBJ_ARRAY_DUMP, size);
1372   writer->write_objectID(array);
1373   writer->write_u4(STACK_TRACE_ID);
1374   writer->write_u4(length);
1375 
1376   // array class ID
1377   writer->write_classID(array->klass());
1378 
1379   // [id]* elements
1380   for (int index = 0; index < length; index++) {
1381     oop o = array->obj_at(index);
1382     if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
1383       ResourceMark rm;
1384       log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
1385                            p2i(o), o->klass()->external_name(),
1386                            p2i(array), array->klass()->external_name());
1387     }
1388     o = mask_dormant_archived_object(o);
1389     writer->write_objectID(o);
1390   }
1391 
1392   writer->end_sub_record();
1393 }
1394 








































1395 #define WRITE_ARRAY(Array, Type, Size, Length) \
1396   for (int i = 0; i < Length; i++) { writer->write_##Size((Size)Array->Type##_at(i)); }
1397 
1398 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
1399 void DumperSupport::dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array) {
1400   BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
1401   // 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)
1402   short header_size = 2 * 1 + 2 * 4 + sizeof(address);
1403 
1404   int length = calculate_array_max_length(writer, array, header_size);
1405   int type_size = type2aelembytes(type);
1406   u4 length_in_bytes = (u4)length * type_size;
1407   u4 size = header_size + length_in_bytes;
1408 
1409   writer->start_sub_record(HPROF_GC_PRIM_ARRAY_DUMP, size);
1410   writer->write_objectID(array);
1411   writer->write_u4(STACK_TRACE_ID);
1412   writer->write_u4(length);
1413   writer->write_u1(type2tag(type));
1414 

1496                                      int bci) {
1497   int line_number;
1498   if (m->is_native()) {
1499     line_number = -3;  // native frame
1500   } else {
1501     line_number = m->line_number_from_bci(bci);
1502   }
1503 
1504   write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
1505   writer->write_id(frame_serial_num);               // frame serial number
1506   writer->write_symbolID(m->name());                // method's name
1507   writer->write_symbolID(m->signature());           // method's signature
1508 
1509   assert(m->method_holder()->is_instance_klass(), "not InstanceKlass");
1510   writer->write_symbolID(m->method_holder()->source_file_name());  // source file name
1511   writer->write_u4(class_serial_num);               // class serial number
1512   writer->write_u4((u4) line_number);               // line number
1513 }
1514 
1515 








































































































































































































































































1516 // Support class used to generate HPROF_UTF8 records from the entries in the
1517 // SymbolTable.
1518 
1519 class SymbolTableDumper : public SymbolClosure {
1520  private:
1521   AbstractDumpWriter* _writer;
1522   AbstractDumpWriter* writer() const                { return _writer; }
1523  public:
1524   SymbolTableDumper(AbstractDumpWriter* writer)     { _writer = writer; }
1525   void do_symbol(Symbol** p);
1526 };
1527 
1528 void SymbolTableDumper::do_symbol(Symbol** p) {
1529   ResourceMark rm;
1530   Symbol* sym = *p;
1531   int len = sym->utf8_length();
1532   if (len > 0) {
1533     char* s = sym->as_utf8();
1534     DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
1535     writer()->write_symbolID(sym);

1718   }
1719 
1720   if (DumperSupport::mask_dormant_archived_object(o) == NULL) {
1721     log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", p2i(o), o->klass()->external_name());
1722     return;
1723   }
1724 
1725   // If large object list exists and it is large object/array,
1726   // add oop into the list and skip scan. VM thread will process it later.
1727   if (_list != NULL && is_large(o)) {
1728     _list->atomic_push(o);
1729     return;
1730   }
1731 
1732   if (o->is_instance()) {
1733     // create a HPROF_GC_INSTANCE record for each object
1734     DumperSupport::dump_instance(writer(), o);
1735   } else if (o->is_objArray()) {
1736     // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
1737     DumperSupport::dump_object_array(writer(), objArrayOop(o));


1738   } else if (o->is_typeArray()) {
1739     // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
1740     DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
1741   }
1742 }
1743 
1744 bool HeapObjectDumper::is_large(oop o) {
1745   size_t size = 0;
1746   if (o->is_instance()) {
1747     // Use o->size() * 8 as the upper limit of instance size to avoid iterating static fields
1748     size = o->size() * 8;
1749   } else if (o->is_objArray()) {
1750     objArrayOop array = objArrayOop(o);
1751     BasicType type = ArrayKlass::cast(array->klass())->element_type();
1752     assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
1753     int length = array->length();
1754     int type_size = sizeof(address);
1755     size = (size_t)length * type_size;








1756   } else if (o->is_typeArray()) {
1757     typeArrayOop array = typeArrayOop(o);
1758     BasicType type = ArrayKlass::cast(array->klass())->element_type();
1759     assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
1760     int length = array->length();
1761     int type_size = type2aelembytes(type);
1762     size = (size_t)length * type_size;
1763   }
1764   return size > HeapDumpLargeObjectList::LargeObjectSizeThreshold;
1765 }
1766 
1767 // The dumper controller for parallel heap dump
1768 class DumperController : public CHeapObj<mtInternal> {
1769  private:
1770    bool     _started;
1771    Monitor* _lock;
1772    uint   _dumper_number;
1773    uint   _complete_number;
1774 
1775  public:

1808      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
1809      while (_complete_number != _dumper_number) {
1810         ml.wait();
1811      }
1812      _started = false;
1813    }
1814 };
1815 
1816 // The VM operation that performs the heap dump
1817 class VM_HeapDumper : public VM_GC_Operation, public WorkerTask {
1818  private:
1819   static VM_HeapDumper*   _global_dumper;
1820   static DumpWriter*      _global_writer;
1821   DumpWriter*             _local_writer;
1822   JavaThread*             _oome_thread;
1823   Method*                 _oome_constructor;
1824   bool                    _gc_before_heap_dump;
1825   GrowableArray<Klass*>*  _klass_map;
1826   ThreadStackTrace**      _stack_traces;
1827   int                     _num_threads;





1828   // parallel heap dump support
1829   uint                    _num_dumper_threads;
1830   uint                    _num_writer_threads;
1831   DumperController*       _dumper_controller;
1832   ParallelObjectIterator* _poi;
1833   HeapDumpLargeObjectList* _large_object_list;
1834 
1835   // VMDumperType is for thread that dumps both heap and non-heap data.
1836   static const size_t VMDumperType = 0;
1837   static const size_t WriterType = 1;
1838   static const size_t DumperType = 2;
1839   // worker id of VMDumper thread.
1840   static const size_t VMDumperWorkerId = 0;
1841 
1842   size_t get_worker_type(uint worker_id) {
1843     assert(_num_writer_threads >= 1, "Must be at least one writer");
1844     // worker id of VMDumper that dump heap and non-heap data
1845     if (worker_id == VMDumperWorkerId) {
1846       return VMDumperType;
1847     }

2217       writer()->writer_loop();
2218       return;
2219     }
2220     if (_num_dumper_threads > 1 && get_worker_type(worker_id) == DumperType) {
2221       _dumper_controller->wait_for_start_signal();
2222     }
2223   } else {
2224     // The worker 0 on all non-heap data dumping and part of heap iteration.
2225     // Write the file header - we always use 1.0.2
2226     const char* header = "JAVA PROFILE 1.0.2";
2227 
2228     // header is few bytes long - no chance to overflow int
2229     writer()->write_raw(header, strlen(header) + 1); // NUL terminated
2230     writer()->write_u4(oopSize);
2231     // timestamp is current time in ms
2232     writer()->write_u8(os::javaTimeMillis());
2233     // HPROF_UTF8 records
2234     SymbolTableDumper sym_dumper(writer());
2235     SymbolTable::symbols_do(&sym_dumper);
2236 







2237     // write HPROF_LOAD_CLASS records
2238     {
2239       LockedClassesDo locked_load_classes(&do_load_class);
2240       ClassLoaderDataGraph::classes_do(&locked_load_classes);
2241     }
2242 
2243     // write HPROF_FRAME and HPROF_TRACE records
2244     // this must be called after _klass_map is built when iterating the classes above.
2245     dump_stack_traces();
2246 
2247     // Writes HPROF_GC_CLASS_DUMP records
2248     {
2249       LockedClassesDo locked_dump_class(&do_class_dump);
2250       ClassLoaderDataGraph::classes_do(&locked_dump_class);
2251     }
2252 
2253     // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
2254     do_threads();
2255 
2256     // HPROF_GC_ROOT_JNI_GLOBAL

2295        if (get_worker_type(worker_id) == VMDumperType) {
2296          _dumper_controller->wait_all_dumpers_complete();
2297          // clear internal buffer;
2298          pw.finish_dump_segment(true);
2299          // refresh the global_writer's buffer and position;
2300          writer()->refresh();
2301        } else {
2302          pw.finish_dump_segment(true);
2303          _dumper_controller->dumper_complete();
2304          return;
2305        }
2306     }
2307   }
2308 
2309   assert(get_worker_type(worker_id) == VMDumperType, "Heap dumper must be VMDumper");
2310   // Use writer() rather than ParDumpWriter to avoid memory consumption.
2311   HeapObjectDumper obj_dumper(writer());
2312   dump_large_objects(&obj_dumper);
2313   // Writes the HPROF_HEAP_DUMP_END record.
2314   DumperSupport::end_of_dump(writer());



2315   // We are done with writing. Release the worker threads.
2316   writer()->deactivate();


2317 }
2318 
2319 void VM_HeapDumper::dump_stack_traces() {
2320   // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
2321   DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
2322   writer()->write_u4((u4) STACK_TRACE_ID);
2323   writer()->write_u4(0);                    // thread number
2324   writer()->write_u4(0);                    // frame count
2325 
2326   _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
2327   int frame_serial_num = 0;
2328   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
2329     oop threadObj = thread->threadObj();
2330     if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
2331       // dump thread stack trace
2332       Thread* current_thread = Thread::current();
2333       ResourceMark rm(current_thread);
2334       HandleMark hm(current_thread);
2335 
2336       ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);

  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "classfile/classLoaderData.inline.hpp"
  28 #include "classfile/classLoaderDataGraph.hpp"
  29 #include "classfile/javaClasses.inline.hpp"
  30 #include "classfile/symbolTable.hpp"
  31 #include "classfile/vmClasses.hpp"
  32 #include "classfile/vmSymbols.hpp"
  33 #include "gc/shared/gcLocker.hpp"
  34 #include "gc/shared/gcVMOperations.hpp"
  35 #include "gc/shared/workerThread.hpp"
  36 #include "jfr/jfrEvents.hpp"
  37 #include "memory/allocation.inline.hpp"
  38 #include "memory/resourceArea.hpp"
  39 #include "memory/universe.hpp"
  40 #include "oops/klass.inline.hpp"
  41 #include "oops/objArrayKlass.hpp"
  42 #include "oops/objArrayOop.inline.hpp"
  43 #include "oops/flatArrayKlass.hpp"
  44 #include "oops/flatArrayOop.inline.hpp"
  45 #include "oops/oop.inline.hpp"
  46 #include "oops/typeArrayOop.inline.hpp"
  47 #include "runtime/fieldDescriptor.inline.hpp"
  48 #include "runtime/frame.inline.hpp"
  49 #include "runtime/handles.inline.hpp"
  50 #include "runtime/javaCalls.hpp"
  51 #include "runtime/jniHandles.hpp"
  52 #include "runtime/os.hpp"
  53 #include "runtime/reflectionUtils.hpp"
  54 #include "runtime/thread.inline.hpp"
  55 #include "runtime/threadSMR.hpp"
  56 #include "runtime/vframe.hpp"
  57 #include "runtime/vmOperations.hpp"
  58 #include "runtime/vmThread.hpp"
  59 #include "services/heapDumper.hpp"
  60 #include "services/heapDumperCompression.hpp"
  61 #include "services/threadService.hpp"
  62 #include "utilities/macros.hpp"
  63 #include "utilities/ostream.hpp"
  64 
  65 /*
  66  * HPROF binary format - description copied from:
  67  *   src/share/demo/jvmti/hprof/hprof_io.c

 294  *                                     7:  double array
 295  *                                     8:  byte array
 296  *                                     9:  short array
 297  *                                     10: int array
 298  *                                     11: long array
 299  *                          [u1]*      elements
 300  *
 301  * HPROF_CPU_SAMPLES        a set of sample traces of running threads
 302  *
 303  *                u4        total number of samples
 304  *                u4        # of traces
 305  *               [u4        # of samples
 306  *                u4]*      stack trace serial number
 307  *
 308  * HPROF_CONTROL_SETTINGS   the settings of on/off switches
 309  *
 310  *                u4        0x00000001: alloc traces on/off
 311  *                          0x00000002: cpu sampling on/off
 312  *                u2        stack trace depth
 313  *
 314  * HPROF_FLAT_ARRAYS        list of flat arrays
 315  *
 316  *               [flat array sub-records]*
 317  *
 318  *               HPROF_FLAT_ARRAY      flat array
 319  *
 320  *                          id         array object ID (dumped as HPROF_GC_PRIM_ARRAY_DUMP)
 321  *                          id         element class ID (dumped by HPROF_GC_CLASS_DUMP)
 322  *
 323  * HPROF_INLINED_FIELDS     decribes inlined fields
 324  *
 325  *               [class with inlined fields sub-records]*
 326  *
 327  *               HPROF_CLASS_WITH_INLINED_FIELDS
 328  *
 329  *                          id         class ID (dumped as HPROF_GC_CLASS_DUMP)
 330  *
 331  *                          u2         number of instance inlined fields (not including super)
 332  *                          [u2,       inlined field index,
 333  *                           u2,       synthetic field count,
 334  *                           id,       original field name,
 335  *                           id]*      inlined field class ID (dumped by HPROF_GC_CLASS_DUMP)
 336  *
 337  * When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
 338  * be generated as a sequence of heap dump segments. This sequence is
 339  * terminated by an end record. The additional tags allowed by format
 340  * "JAVA PROFILE 1.0.2" are:
 341  *
 342  * HPROF_HEAP_DUMP_SEGMENT  denote a heap dump segment
 343  *
 344  *               [heap dump sub-records]*
 345  *               The same sub-record types allowed by HPROF_HEAP_DUMP
 346  *
 347  * HPROF_HEAP_DUMP_END      denotes the end of a heap dump
 348  *
 349  */
 350 
 351 
 352 // HPROF tags
 353 
 354 enum hprofTag : u1 {
 355   // top-level records
 356   HPROF_UTF8                    = 0x01,
 357   HPROF_LOAD_CLASS              = 0x02,
 358   HPROF_UNLOAD_CLASS            = 0x03,
 359   HPROF_FRAME                   = 0x04,
 360   HPROF_TRACE                   = 0x05,
 361   HPROF_ALLOC_SITES             = 0x06,
 362   HPROF_HEAP_SUMMARY            = 0x07,
 363   HPROF_START_THREAD            = 0x0A,
 364   HPROF_END_THREAD              = 0x0B,
 365   HPROF_HEAP_DUMP               = 0x0C,
 366   HPROF_CPU_SAMPLES             = 0x0D,
 367   HPROF_CONTROL_SETTINGS        = 0x0E,
 368 
 369   // 1.0.2 record types
 370   HPROF_HEAP_DUMP_SEGMENT       = 0x1C,
 371   HPROF_HEAP_DUMP_END           = 0x2C,
 372 
 373   // inlined object support
 374   HPROF_FLAT_ARRAYS             = 0x12,
 375   HPROF_INLINED_FIELDS          = 0x13,
 376   // inlined object subrecords
 377   HPROF_FLAT_ARRAY                  = 0x01,
 378   HPROF_CLASS_WITH_INLINED_FIELDS   = 0x01,
 379 
 380   // field types
 381   HPROF_ARRAY_OBJECT            = 0x01,
 382   HPROF_NORMAL_OBJECT           = 0x02,
 383   HPROF_BOOLEAN                 = 0x04,
 384   HPROF_CHAR                    = 0x05,
 385   HPROF_FLOAT                   = 0x06,
 386   HPROF_DOUBLE                  = 0x07,
 387   HPROF_BYTE                    = 0x08,
 388   HPROF_SHORT                   = 0x09,
 389   HPROF_INT                     = 0x0A,
 390   HPROF_LONG                    = 0x0B,
 391 
 392   // data-dump sub-records
 393   HPROF_GC_ROOT_UNKNOWN         = 0xFF,
 394   HPROF_GC_ROOT_JNI_GLOBAL      = 0x01,
 395   HPROF_GC_ROOT_JNI_LOCAL       = 0x02,
 396   HPROF_GC_ROOT_JAVA_FRAME      = 0x03,
 397   HPROF_GC_ROOT_NATIVE_STACK    = 0x04,
 398   HPROF_GC_ROOT_STICKY_CLASS    = 0x05,
 399   HPROF_GC_ROOT_THREAD_BLOCK    = 0x06,
 400   HPROF_GC_ROOT_MONITOR_USED    = 0x07,
 401   HPROF_GC_ROOT_THREAD_OBJ      = 0x08,
 402   HPROF_GC_CLASS_DUMP           = 0x20,
 403   HPROF_GC_INSTANCE_DUMP        = 0x21,
 404   HPROF_GC_OBJ_ARRAY_DUMP       = 0x22,
 405   HPROF_GC_PRIM_ARRAY_DUMP      = 0x23
 406 };
 407 
 408 // Default stack trace ID (used for dummy HPROF_TRACE record)
 409 enum {
 410   STACK_TRACE_ID = 1,
 411   INITIAL_CLASS_COUNT = 200
 412 };
 413 
 414 
 415 class AbstractDumpWriter;
 416 
 417 class InlinedObjects {
 418 
 419   struct ClassInlinedFields {
 420     const Klass *klass;
 421     uintx base_index;   // base index of the inlined field names (1st field has index base_index+1).
 422     ClassInlinedFields(const Klass *klass = nullptr, uintx base_index = 0) : klass(klass), base_index(base_index) {}
 423 
 424     // For GrowableArray::find_sorted().
 425     static int compare(const ClassInlinedFields& a, const ClassInlinedFields& b) {
 426       return a.klass - b.klass;
 427     }
 428     // For GrowableArray::sort().
 429     static int compare(ClassInlinedFields* a, ClassInlinedFields* b) {
 430       return compare(*a, *b);
 431     }
 432   };
 433 
 434   uintx _min_string_id;
 435   uintx _max_string_id;
 436 
 437   GrowableArray<ClassInlinedFields> *_inlined_field_map;
 438 
 439   // counters for classes with inlined fields and for the fields
 440   int _classes_count;
 441   int _inlined_fields_count;
 442 
 443   static InlinedObjects *_instance;
 444 
 445   static void inlined_field_names_callback(InlinedObjects* _this, const Klass *klass, uintx base_index, int count);
 446 
 447   GrowableArray<oop> *_flat_arrays;
 448 
 449 public:
 450   InlinedObjects()
 451     : _min_string_id(0), _max_string_id(0),
 452     _inlined_field_map(nullptr),
 453     _classes_count(0), _inlined_fields_count(0),
 454     _flat_arrays(nullptr) {
 455   }
 456 
 457   static InlinedObjects* get_instance() {
 458     return _instance;
 459   }
 460 
 461   void init();
 462   void release();
 463 
 464   void dump_inlined_field_names(AbstractDumpWriter *writer);
 465 
 466   uintx get_base_index_for(Klass* k);
 467   uintx get_next_string_id(uintx id);
 468 
 469   void dump_classed_with_inlined_fields(AbstractDumpWriter* writer);
 470 
 471   void add_flat_array(oop array);
 472   void dump_flat_arrays(AbstractDumpWriter* writer);
 473 
 474 };
 475 
 476 InlinedObjects *InlinedObjects::_instance = nullptr;
 477 
 478 
 479 // Supports I/O operations for a dump
 480 // Base class for dump and parallel dump
 481 class AbstractDumpWriter : public StackObj {
 482  protected:
 483   enum {
 484     io_buffer_max_size = 1*M,
 485     io_buffer_max_waste = 10*K,
 486     dump_segment_header_size = 9
 487   };
 488 
 489   char* _buffer;    // internal buffer
 490   size_t _size;
 491   size_t _pos;
 492 
 493   bool _in_dump_segment; // Are we currently in a dump segment?
 494   bool _is_huge_sub_record; // Are we writing a sub-record larger than the buffer size?
 495   DEBUG_ONLY(size_t _sub_record_left;) // The bytes not written for the current sub-record.
 496   DEBUG_ONLY(bool _sub_record_ended;) // True if we have called the end_sub_record().
 497 
 498   virtual void flush(bool force = false) = 0;

 971   }
 972 };
 973 
 974 Monitor* ParDumpWriter::_lock = NULL;
 975 
 976 // Support class with a collection of functions used when dumping the heap
 977 
 978 class DumperSupport : AllStatic {
 979  public:
 980 
 981   // write a header of the given type
 982   static void write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len);
 983 
 984   // returns hprof tag for the given type signature
 985   static hprofTag sig2tag(Symbol* sig);
 986   // returns hprof tag for the given basic type
 987   static hprofTag type2tag(BasicType type);
 988   // Returns the size of the data to write.
 989   static u4 sig2size(Symbol* sig);
 990 
 991   // calculates the total size of the all fields of the given class.
 992   static u4 instance_size(InstanceKlass* ik);
 993 
 994   // dump a jfloat
 995   static void dump_float(AbstractDumpWriter* writer, jfloat f);
 996   // dump a jdouble
 997   static void dump_double(AbstractDumpWriter* writer, jdouble d);
 998   // dumps the raw value of the given field
 999   static void dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset);
1000   // returns the size of the static fields; also counts the static fields
1001   static u4 get_static_fields_size(InstanceKlass* ik, u2& field_count);
1002   // dumps static fields of the given class
1003   static void dump_static_fields(AbstractDumpWriter* writer, Klass* k);
1004   // dump the raw values of the instance fields of the given identity or inlined object;
1005   // for identity objects offset is 0 and 'klass' is o->klass(),
1006   // for inlined objects offset is the offset in the holder object, 'klass' is inlined object class
1007   static void dump_instance_fields(AbstractDumpWriter* writer, oop o, int offset, InstanceKlass* klass);
1008   // dump the raw values of the instance fields of the given inlined object;
1009   // dump_instance_fields wrapper for inlined objects
1010   static void dump_inlined_object_fields(AbstractDumpWriter* writer, oop o, int offset, InlineKlass* klass);
1011 
1012   // get the count of the instance fields for a given class
1013   static u2 get_instance_fields_count(InstanceKlass* ik);
1014   // dumps the definition of the instance fields for a given class
1015   static void dump_instance_field_descriptors(AbstractDumpWriter* writer, InstanceKlass* k, uintx *inlined_fields_index = nullptr);
1016   // creates HPROF_GC_INSTANCE_DUMP record for the given object
1017   static void dump_instance(AbstractDumpWriter* writer, oop o);
1018   // creates HPROF_GC_CLASS_DUMP record for the given instance class
1019   static void dump_instance_class(AbstractDumpWriter* writer, Klass* k);
1020   // creates HPROF_GC_CLASS_DUMP record for a given array class
1021   static void dump_array_class(AbstractDumpWriter* writer, Klass* k);
1022 
1023   // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
1024   static void dump_object_array(AbstractDumpWriter* writer, objArrayOop array);
1025   // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given flat array
1026   static void dump_flat_array(AbstractDumpWriter* writer, flatArrayOop array);
1027   // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
1028   static void dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array);
1029   // create HPROF_FRAME record for the given method and bci
1030   static void dump_stack_frame(AbstractDumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
1031 
1032   // check if we need to truncate an array
1033   static int calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size);
1034   // extended version to dump flat arrays as primitive arrays;
1035   // type_size specifies size of the inlined objects.
1036   static int calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, int type_size, short header_size);
1037 
1038   // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
1039   static void end_of_dump(AbstractDumpWriter* writer);
1040 
1041   static oop mask_dormant_archived_object(oop o) {
1042     if (o != NULL && o->klass()->java_mirror() == NULL) {
1043       // Ignore this object since the corresponding java mirror is not loaded.
1044       // Might be a dormant archive object.
1045       return NULL;
1046     } else {
1047       return o;
1048     }
1049   }
1050 
1051   // helper methods for inlined fields.
1052   static bool is_inlined_field(const FieldStream& fld) {
1053     return fld.field_descriptor().is_inlined();
1054   }
1055   static InlineKlass* get_inlined_field_klass(const FieldStream &fld) {
1056     assert(is_inlined_field(fld), "must be inlined field");
1057     InstanceKlass* holder_klass = fld.field_descriptor().field_holder();
1058     return InlineKlass::cast(holder_klass->get_inline_type_field_klass(fld.index()));
1059   }
1060 };
1061 
1062 // write a header of the given type
1063 void DumperSupport:: write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len) {
1064   writer->write_u1(tag);
1065   writer->write_u4(0);                  // current ticks
1066   writer->write_u4(len);
1067 }
1068 
1069 // returns hprof tag for the given type signature
1070 hprofTag DumperSupport::sig2tag(Symbol* sig) {
1071   switch (sig->char_at(0)) {
1072     case JVM_SIGNATURE_CLASS    : return HPROF_NORMAL_OBJECT;
1073     case JVM_SIGNATURE_PRIMITIVE_OBJECT: return HPROF_NORMAL_OBJECT; // not inlined Q-object, i.e. identity object.
1074     case JVM_SIGNATURE_ARRAY    : return HPROF_NORMAL_OBJECT;
1075     case JVM_SIGNATURE_BYTE     : return HPROF_BYTE;
1076     case JVM_SIGNATURE_CHAR     : return HPROF_CHAR;
1077     case JVM_SIGNATURE_FLOAT    : return HPROF_FLOAT;
1078     case JVM_SIGNATURE_DOUBLE   : return HPROF_DOUBLE;
1079     case JVM_SIGNATURE_INT      : return HPROF_INT;
1080     case JVM_SIGNATURE_LONG     : return HPROF_LONG;
1081     case JVM_SIGNATURE_SHORT    : return HPROF_SHORT;
1082     case JVM_SIGNATURE_BOOLEAN  : return HPROF_BOOLEAN;
1083     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
1084   }
1085 }
1086 
1087 hprofTag DumperSupport::type2tag(BasicType type) {
1088   switch (type) {
1089     case T_BYTE     : return HPROF_BYTE;
1090     case T_CHAR     : return HPROF_CHAR;
1091     case T_FLOAT    : return HPROF_FLOAT;
1092     case T_DOUBLE   : return HPROF_DOUBLE;
1093     case T_INT      : return HPROF_INT;
1094     case T_LONG     : return HPROF_LONG;
1095     case T_SHORT    : return HPROF_SHORT;
1096     case T_BOOLEAN  : return HPROF_BOOLEAN;
1097     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
1098   }
1099 }
1100 
1101 u4 DumperSupport::sig2size(Symbol* sig) {
1102   switch (sig->char_at(0)) {
1103     case JVM_SIGNATURE_CLASS:
1104     case JVM_SIGNATURE_PRIMITIVE_OBJECT:
1105     case JVM_SIGNATURE_ARRAY: return sizeof(address);
1106     case JVM_SIGNATURE_BOOLEAN:
1107     case JVM_SIGNATURE_BYTE: return 1;
1108     case JVM_SIGNATURE_SHORT:
1109     case JVM_SIGNATURE_CHAR: return 2;
1110     case JVM_SIGNATURE_INT:
1111     case JVM_SIGNATURE_FLOAT: return 4;
1112     case JVM_SIGNATURE_LONG:
1113     case JVM_SIGNATURE_DOUBLE: return 8;
1114     default: ShouldNotReachHere(); /* to shut up compiler */ return 0;
1115   }
1116 }
1117 
1118 template<typename T, typename F> T bit_cast(F from) { // replace with the real thing when we can use c++20
1119   T to;
1120   static_assert(sizeof(to) == sizeof(from), "must be of the same size");
1121   memcpy(&to, &from, sizeof(to));
1122   return to;
1123 }
1124 
1125 // dump a jfloat
1126 void DumperSupport::dump_float(AbstractDumpWriter* writer, jfloat f) {
1127   if (g_isnan(f)) {
1128     writer->write_u4(0x7fc00000); // collapsing NaNs
1129   } else {
1130     writer->write_u4(bit_cast<u4>(f));
1131   }
1132 }
1133 
1134 // dump a jdouble
1135 void DumperSupport::dump_double(AbstractDumpWriter* writer, jdouble d) {
1136   if (g_isnan(d)) {
1137     writer->write_u8(0x7ff80000ull << 32); // collapsing NaNs
1138   } else {
1139     writer->write_u8(bit_cast<u8>(d));
1140   }
1141 }
1142 
1143 
1144 // dumps the raw value of the given field
1145 void DumperSupport::dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset) {
1146   switch (type) {
1147     case JVM_SIGNATURE_CLASS :
1148     case JVM_SIGNATURE_PRIMITIVE_OBJECT: // not inlined Q-object, i.e. identity object.
1149     case JVM_SIGNATURE_ARRAY : {
1150       oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset);
1151       if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
1152         ResourceMark rm;
1153         log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
1154                              p2i(o), o->klass()->external_name(),
1155                              p2i(obj), obj->klass()->external_name());
1156       }
1157       o = mask_dormant_archived_object(o);
1158       assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
1159       writer->write_objectID(o);
1160       break;
1161     }
1162     case JVM_SIGNATURE_BYTE : {
1163       jbyte b = obj->byte_field(offset);
1164       writer->write_u1(b);
1165       break;
1166     }
1167     case JVM_SIGNATURE_CHAR : {
1168       jchar c = obj->char_field(offset);

1189       writer->write_u4(i);
1190       break;
1191     }
1192     case JVM_SIGNATURE_LONG : {
1193       jlong l = obj->long_field(offset);
1194       writer->write_u8(l);
1195       break;
1196     }
1197     case JVM_SIGNATURE_BOOLEAN : {
1198       jboolean b = obj->bool_field(offset);
1199       writer->write_u1(b);
1200       break;
1201     }
1202     default : {
1203       ShouldNotReachHere();
1204       break;
1205     }
1206   }
1207 }
1208 
1209 // calculates the total size of the all fields of the given class.
1210 u4 DumperSupport::instance_size(InstanceKlass *ik) {

1211   u4 size = 0;
1212 
1213   for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1214     if (!fld.access_flags().is_static()) {
1215       if (is_inlined_field(fld)) {
1216         size += instance_size(get_inlined_field_klass(fld));
1217       } else {
1218         size += sig2size(fld.signature());
1219       }
1220     }
1221   }
1222   return size;
1223 }
1224 
1225 u4 DumperSupport::get_static_fields_size(InstanceKlass* ik, u2& field_count) {
1226   field_count = 0;
1227   u4 size = 0;
1228 
1229   for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) {
1230     if (fldc.access_flags().is_static()) {
1231       assert(!is_inlined_field(fldc), "static fields cannot be inlined");
1232 
1233       field_count++;
1234       size += sig2size(fldc.signature());
1235     }
1236   }
1237 
1238   // Add in resolved_references which is referenced by the cpCache
1239   // The resolved_references is an array per InstanceKlass holding the
1240   // strings and other oops resolved from the constant pool.
1241   oop resolved_references = ik->constants()->resolved_references_or_null();
1242   if (resolved_references != NULL) {
1243     field_count++;
1244     size += sizeof(address);
1245 
1246     // Add in the resolved_references of the used previous versions of the class
1247     // in the case of RedefineClasses
1248     InstanceKlass* prev = ik->previous_versions();
1249     while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
1250       field_count++;
1251       size += sizeof(address);
1252       prev = prev->previous_versions();

1255 
1256   // Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]
1257   // arrays.
1258   oop init_lock = ik->init_lock();
1259   if (init_lock != NULL) {
1260     field_count++;
1261     size += sizeof(address);
1262   }
1263 
1264   // We write the value itself plus a name and a one byte type tag per field.
1265   return size + field_count * (sizeof(address) + 1);
1266 }
1267 
1268 // dumps static fields of the given class
1269 void DumperSupport::dump_static_fields(AbstractDumpWriter* writer, Klass* k) {
1270   InstanceKlass* ik = InstanceKlass::cast(k);
1271 
1272   // dump the field descriptors and raw values
1273   for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) {
1274     if (fld.access_flags().is_static()) {
1275       assert(!is_inlined_field(fld), "static fields cannot be inlined");
1276 
1277       Symbol* sig = fld.signature();
1278 
1279       writer->write_symbolID(fld.name());   // name
1280       writer->write_u1(sig2tag(sig));       // type
1281 
1282       // value
1283       dump_field_value(writer, sig->char_at(0), ik->java_mirror(), fld.offset());
1284     }
1285   }
1286 
1287   // Add resolved_references for each class that has them
1288   oop resolved_references = ik->constants()->resolved_references_or_null();
1289   if (resolved_references != NULL) {
1290     writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1291     writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1292     writer->write_objectID(resolved_references);
1293 
1294     // Also write any previous versions
1295     InstanceKlass* prev = ik->previous_versions();
1296     while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
1297       writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1298       writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1299       writer->write_objectID(prev->constants()->resolved_references());
1300       prev = prev->previous_versions();
1301     }
1302   }
1303 
1304   // Add init lock to the end if the class is not yet initialized
1305   oop init_lock = ik->init_lock();
1306   if (init_lock != NULL) {
1307     writer->write_symbolID(vmSymbols::init_lock_name());         // name
1308     writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type
1309     writer->write_objectID(init_lock);
1310   }
1311 }
1312 
1313 // dump the raw values of the instance fields of the given identity or inlined object;
1314 // for identity objects offset is 0 and 'klass' is o->klass(),
1315 // for inlined objects offset is the offset in the holder object, 'klass' is inlined object class.
1316 void DumperSupport::dump_instance_fields(AbstractDumpWriter* writer, oop o, int offset, InstanceKlass *klass) {
1317   for (FieldStream fld(klass, false, false); !fld.eos(); fld.next()) {
1318     if (!fld.access_flags().is_static()) {
1319       if (is_inlined_field(fld)) {
1320         InlineKlass* field_klass = get_inlined_field_klass(fld);
1321         // the field is inlined, so all its fields are stored without headers.
1322         int fields_offset = offset + fld.offset() - field_klass->first_field_offset();
1323         dump_inlined_object_fields(writer, o, offset + fld.offset(), field_klass);
1324       } else {
1325         Symbol* sig = fld.signature();
1326         dump_field_value(writer, sig->char_at(0), o, offset + fld.offset());
1327       }
1328     }
1329   }
1330 }
1331 
1332 void DumperSupport::dump_inlined_object_fields(AbstractDumpWriter* writer, oop o, int offset, InlineKlass* klass) {
1333   // the object is inlined, so all its fields are stored without headers.
1334   dump_instance_fields(writer, o, offset - klass->first_field_offset(), klass);
1335 }
1336 
1337 // gets the count of the instance fields for a given class
1338 u2 DumperSupport::get_instance_fields_count(InstanceKlass* ik) {
1339   u2 field_count = 0;
1340 
1341   for (FieldStream fldc(ik, true, true); !fldc.eos(); fldc.next()) {
1342     if (!fldc.access_flags().is_static()) {
1343       if (is_inlined_field(fldc)) {
1344         // add "synthetic" fields for inlined fields.
1345         field_count += get_instance_fields_count(get_inlined_field_klass(fldc));
1346       } else {
1347         field_count++;
1348       }
1349     }
1350   }
1351 
1352   return field_count;
1353 }
1354 
1355 // dumps the definition of the instance fields for a given class
1356 // inlined_fields_id is not-NULL for inlined fields (to get synthetic field name IDs
1357 // by using InlinedObjects::get_next_string_id()).
1358 void DumperSupport::dump_instance_field_descriptors(AbstractDumpWriter* writer, InstanceKlass* ik, uintx* inlined_fields_id) {
1359   // inlined_fields_id != NULL means ik is a class of inlined field.
1360   // Inlined field id pointer for this class; lazyly initialized
1361   // if the class has inlined field(s) and the caller didn't provide inlined_fields_id.
1362   uintx *this_klass_inlined_fields_id = inlined_fields_id;
1363   uintx inlined_id = 0;
1364 
1365   // dump the field descriptors
1366   for (FieldStream fld(ik, true, true); !fld.eos(); fld.next()) {
1367     if (!fld.access_flags().is_static()) {
1368       if (is_inlined_field(fld)) {
1369         // dump "synthetic" fields for inlined fields.
1370         if (this_klass_inlined_fields_id == nullptr) {
1371           inlined_id = InlinedObjects::get_instance()->get_base_index_for(ik);
1372           this_klass_inlined_fields_id = &inlined_id;
1373         }
1374         dump_instance_field_descriptors(writer, get_inlined_field_klass(fld), this_klass_inlined_fields_id);
1375       } else {
1376         Symbol* sig = fld.signature();
1377         Symbol* name = nullptr;
1378         // Use inlined_fields_id provided by caller.
1379         if (inlined_fields_id != nullptr) {
1380           uintx name_id = InlinedObjects::get_instance()->get_next_string_id(*inlined_fields_id);
1381 
1382           // name_id == 0 is returned on error. use original field signature.
1383           if (name_id != 0) {
1384             *inlined_fields_id = name_id;
1385             name = reinterpret_cast<Symbol*>(name_id);
1386           }
1387         }
1388         if (name == nullptr) {
1389           name = fld.name();
1390         }
1391 
1392         writer->write_symbolID(name);         // name
1393         writer->write_u1(sig2tag(sig));       // type
1394       }
1395     }
1396   }
1397 }
1398 
1399 // creates HPROF_GC_INSTANCE_DUMP record for the given object
1400 void DumperSupport::dump_instance(AbstractDumpWriter* writer, oop o) {
1401   InstanceKlass* ik = InstanceKlass::cast(o->klass());
1402   u4 is = instance_size(ik);
1403   u4 size = 1 + sizeof(address) + 4 + sizeof(address) + 4 + is;
1404 
1405   writer->start_sub_record(HPROF_GC_INSTANCE_DUMP, size);
1406   writer->write_objectID(o);
1407   writer->write_u4(STACK_TRACE_ID);
1408 
1409   // class ID
1410   writer->write_classID(ik);
1411 
1412   // number of bytes that follow
1413   writer->write_u4(is);
1414 
1415   // field values
1416   dump_instance_fields(writer, o, 0, ik);
1417 
1418   writer->end_sub_record();
1419 }
1420 
1421 // creates HPROF_GC_CLASS_DUMP record for the given instance class
1422 void DumperSupport::dump_instance_class(AbstractDumpWriter* writer, Klass* k) {
1423   InstanceKlass* ik = InstanceKlass::cast(k);
1424 
1425   // We can safepoint and do a heap dump at a point where we have a Klass,
1426   // but no java mirror class has been setup for it. So we need to check
1427   // that the class is at least loaded, to avoid crash from a null mirror.
1428   if (!ik->is_loaded()) {
1429     return;
1430   }
1431 
1432   u2 static_fields_count = 0;
1433   u4 static_size = get_static_fields_size(ik, static_fields_count);
1434   u2 instance_fields_count = get_instance_fields_count(ik);
1435   u4 instance_fields_size = instance_fields_count * (sizeof(address) + 1);
1436   u4 size = 1 + sizeof(address) + 4 + 6 * sizeof(address) + 4 + 2 + 2 + static_size + 2 + instance_fields_size;

1441   writer->write_classID(ik);
1442   writer->write_u4(STACK_TRACE_ID);
1443 
1444   // super class ID
1445   InstanceKlass* java_super = ik->java_super();
1446   if (java_super == NULL) {
1447     writer->write_objectID(oop(NULL));
1448   } else {
1449     writer->write_classID(java_super);
1450   }
1451 
1452   writer->write_objectID(ik->class_loader());
1453   writer->write_objectID(ik->signers());
1454   writer->write_objectID(ik->protection_domain());
1455 
1456   // reserved
1457   writer->write_objectID(oop(NULL));
1458   writer->write_objectID(oop(NULL));
1459 
1460   // instance size
1461   writer->write_u4(HeapWordSize * ik->size_helper());
1462 
1463   // size of constant pool - ignored by HAT 1.1
1464   writer->write_u2(0);
1465 
1466   // static fields
1467   writer->write_u2(static_fields_count);
1468   dump_static_fields(writer, ik);
1469 
1470   // description of instance fields
1471   writer->write_u2(instance_fields_count);
1472   dump_instance_field_descriptors(writer, ik);
1473 
1474   writer->end_sub_record();
1475 }
1476 
1477 // creates HPROF_GC_CLASS_DUMP record for the given array class
1478 void DumperSupport::dump_array_class(AbstractDumpWriter* writer, Klass* k) {
1479   InstanceKlass* ik = NULL; // bottom class for object arrays, NULL for primitive type arrays
1480   if (k->is_objArray_klass()) {
1481     Klass *bk = ObjArrayKlass::cast(k)->bottom_klass();

1495   assert(java_super != NULL, "checking");
1496   writer->write_classID(java_super);
1497 
1498   writer->write_objectID(ik == NULL ? oop(NULL) : ik->class_loader());
1499   writer->write_objectID(ik == NULL ? oop(NULL) : ik->signers());
1500   writer->write_objectID(ik == NULL ? oop(NULL) : ik->protection_domain());
1501 
1502   writer->write_objectID(oop(NULL));    // reserved
1503   writer->write_objectID(oop(NULL));
1504   writer->write_u4(0);             // instance size
1505   writer->write_u2(0);             // constant pool
1506   writer->write_u2(0);             // static fields
1507   writer->write_u2(0);             // instance fields
1508 
1509   writer->end_sub_record();
1510 
1511 }
1512 
1513 // Hprof uses an u4 as record length field,
1514 // which means we need to truncate arrays that are too long.
1515 int DumperSupport::calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, int type_size, short header_size) {



1516   int length = array->length();
1517 







1518   size_t length_in_bytes = (size_t)length * type_size;
1519   uint max_bytes = max_juint - header_size;
1520 
1521   if (length_in_bytes > max_bytes) {
1522     length = max_bytes / type_size;
1523     length_in_bytes = (size_t)length * type_size;
1524 
1525     BasicType type = ArrayKlass::cast(array->klass())->element_type();
1526     warning("cannot dump array of type %s[] with length %d; truncating to length %d",
1527             type2name_tab[type], array->length(), length);
1528   }
1529   return length;
1530 }
1531 
1532 int DumperSupport::calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size) {
1533   BasicType type = ArrayKlass::cast(array->klass())->element_type();
1534   assert((type >= T_BOOLEAN && type <= T_OBJECT) || type == T_PRIMITIVE_OBJECT, "invalid array element type");
1535   int type_size;
1536   if (type == T_OBJECT || type == T_PRIMITIVE_OBJECT) {  // TODO: FIXME
1537     type_size = sizeof(address);
1538   } else {
1539     type_size = type2aelembytes(type);
1540   }
1541 
1542   return calculate_array_max_length(writer, array, type_size, header_size);
1543 }
1544 
1545 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
1546 void DumperSupport::dump_object_array(AbstractDumpWriter* writer, objArrayOop array) {
1547   // sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)
1548   short header_size = 1 + 2 * 4 + 2 * sizeof(address);
1549   int length = calculate_array_max_length(writer, array, header_size);
1550   u4 size = header_size + length * sizeof(address);
1551 
1552   writer->start_sub_record(HPROF_GC_OBJ_ARRAY_DUMP, size);
1553   writer->write_objectID(array);
1554   writer->write_u4(STACK_TRACE_ID);
1555   writer->write_u4(length);
1556 
1557   // array class ID
1558   writer->write_classID(array->klass());
1559 
1560   // [id]* elements
1561   for (int index = 0; index < length; index++) {
1562     oop o = array->obj_at(index);
1563     if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
1564       ResourceMark rm;
1565       log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
1566                            p2i(o), o->klass()->external_name(),
1567                            p2i(array), array->klass()->external_name());
1568     }
1569     o = mask_dormant_archived_object(o);
1570     writer->write_objectID(o);
1571   }
1572 
1573   writer->end_sub_record();
1574 }
1575 
1576 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given flat array
1577 void DumperSupport::dump_flat_array(AbstractDumpWriter* writer, flatArrayOop array) {
1578   FlatArrayKlass* array_klass = FlatArrayKlass::cast(array->klass());
1579   InlineKlass* element_klass = array_klass->element_klass();
1580   int element_size = instance_size(element_klass);
1581   /*                          id         array object ID
1582    *                          u4         stack trace serial number
1583    *                          u4         number of elements
1584    *                          u1         element type
1585    */
1586   short header_size = 1 + sizeof(address) + 2 * 4 + 1;
1587 
1588   // TODO: use T_SHORT/T_INT/T_LONG if needed to avoid truncation
1589   BasicType type = T_BYTE;
1590   int type_size = type2aelembytes(type);
1591   int length = calculate_array_max_length(writer, array, element_size, header_size);
1592   u4 length_in_bytes = (u4)(length * element_size);
1593   u4 size = header_size + length_in_bytes;
1594 
1595   writer->start_sub_record(HPROF_GC_PRIM_ARRAY_DUMP, size);
1596   writer->write_objectID(array);
1597   writer->write_u4(STACK_TRACE_ID);
1598   // TODO: round up array length for T_SHORT/T_INT/T_LONG
1599   writer->write_u4(length * element_size);
1600   writer->write_u1(type2tag(type));
1601 
1602   for (int index = 0; index < length; index++) {
1603     // need offset in the holder to read inlined object. calculate it from flatArrayOop::value_at_addr()
1604     int offset = (int)((address)array->value_at_addr(index, array_klass->layout_helper())
1605                   - cast_from_oop<address>(array));
1606     dump_inlined_object_fields(writer, array, offset, element_klass);
1607   }
1608 
1609   // TODO: write padding bytes for T_SHORT/T_INT/T_LONG
1610 
1611   InlinedObjects::get_instance()->add_flat_array(array);
1612 
1613   writer->end_sub_record();
1614 }
1615 
1616 #define WRITE_ARRAY(Array, Type, Size, Length) \
1617   for (int i = 0; i < Length; i++) { writer->write_##Size((Size)Array->Type##_at(i)); }
1618 
1619 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
1620 void DumperSupport::dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array) {
1621   BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
1622   // 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)
1623   short header_size = 2 * 1 + 2 * 4 + sizeof(address);
1624 
1625   int length = calculate_array_max_length(writer, array, header_size);
1626   int type_size = type2aelembytes(type);
1627   u4 length_in_bytes = (u4)length * type_size;
1628   u4 size = header_size + length_in_bytes;
1629 
1630   writer->start_sub_record(HPROF_GC_PRIM_ARRAY_DUMP, size);
1631   writer->write_objectID(array);
1632   writer->write_u4(STACK_TRACE_ID);
1633   writer->write_u4(length);
1634   writer->write_u1(type2tag(type));
1635 

1717                                      int bci) {
1718   int line_number;
1719   if (m->is_native()) {
1720     line_number = -3;  // native frame
1721   } else {
1722     line_number = m->line_number_from_bci(bci);
1723   }
1724 
1725   write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
1726   writer->write_id(frame_serial_num);               // frame serial number
1727   writer->write_symbolID(m->name());                // method's name
1728   writer->write_symbolID(m->signature());           // method's signature
1729 
1730   assert(m->method_holder()->is_instance_klass(), "not InstanceKlass");
1731   writer->write_symbolID(m->method_holder()->source_file_name());  // source file name
1732   writer->write_u4(class_serial_num);               // class serial number
1733   writer->write_u4((u4) line_number);               // line number
1734 }
1735 
1736 
1737 class InlinedFieldNameDumper : public LockedClassesDo {
1738 public:
1739   typedef void (*Callback)(InlinedObjects *owner, const Klass *klass, uintx base_index, int count);
1740 
1741 private:
1742   AbstractDumpWriter* _writer;
1743   InlinedObjects *_owner;
1744   Callback       _callback;
1745   uintx _index;
1746 
1747   void dump_inlined_field_names(GrowableArray<Symbol*>* super_names, Symbol* field_name, InlineKlass* klass) {
1748     super_names->push(field_name);
1749     for (FieldStream fld(klass, false, false); !fld.eos(); fld.next()) {
1750       if (!fld.access_flags().is_static()) {
1751         if (DumperSupport::is_inlined_field(fld)) {
1752           dump_inlined_field_names(super_names, fld.name(), DumperSupport::get_inlined_field_klass(fld));
1753         } else {
1754           // get next string ID.
1755           uintx next_index = _owner->get_next_string_id(_index);
1756           if (next_index == 0) {
1757             // something went wrong (overflow?)
1758             // stop generation; the rest of inlined objects will have original field names.
1759             return;
1760           }
1761           _index = next_index;
1762 
1763           // Calculate length.
1764           int len = fld.name()->utf8_length();
1765           for (GrowableArrayIterator<Symbol*> it = super_names->begin(); it != super_names->end(); ++it) {
1766             len += (*it)->utf8_length() + 1;    // +1 for ".".
1767           }
1768 
1769           DumperSupport::write_header(_writer, HPROF_UTF8, oopSize + len);
1770           _writer->write_symbolID(reinterpret_cast<Symbol*>(_index));
1771           // Write the string value.
1772           // 1) super_names.
1773           for (GrowableArrayIterator<Symbol*> it = super_names->begin(); it != super_names->end(); ++it) {
1774             _writer->write_raw((*it)->bytes(), (*it)->utf8_length());
1775             _writer->write_u1('.');
1776           }
1777           // 2) field name.
1778           _writer->write_raw(fld.name()->bytes(), fld.name()->utf8_length());
1779         }
1780       }
1781     }
1782     super_names->pop();
1783   }
1784 
1785   void dump_inlined_field_names(Symbol* field_name, InlineKlass* field_klass) {
1786     GrowableArray<Symbol*> super_names(4, mtServiceability);
1787     dump_inlined_field_names(&super_names, field_name, field_klass);
1788   }
1789 
1790 public:
1791   InlinedFieldNameDumper(AbstractDumpWriter* writer, InlinedObjects* owner, Callback callback)
1792     : _writer(writer), _owner(owner), _callback(callback), _index(0)  {
1793   }
1794 
1795   void do_klass(Klass* k) {
1796     if (!k->is_instance_klass()) {
1797       return;
1798     }
1799     InstanceKlass* ik = InstanceKlass::cast(k);
1800     // if (ik->has_inline_type_fields()) {
1801     //   return;
1802     // }
1803 
1804     uintx base_index = _index;
1805     int count = 0;
1806 
1807     for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1808       if (!fld.access_flags().is_static()) {
1809         if (DumperSupport::is_inlined_field(fld)) {
1810           dump_inlined_field_names(fld.name(), DumperSupport::get_inlined_field_klass(fld));
1811           count++;
1812         }
1813       }
1814     }
1815 
1816     if (count != 0) {
1817       _callback(_owner, k, base_index, count);
1818     }
1819   }
1820 };
1821 
1822 class InlinedFieldsDumper : public LockedClassesDo {
1823 private:
1824   AbstractDumpWriter* _writer;
1825 
1826 public:
1827   InlinedFieldsDumper(AbstractDumpWriter* writer) : _writer(writer) {}
1828 
1829   void do_klass(Klass* k) {
1830     if (!k->is_instance_klass()) {
1831       return;
1832     }
1833     InstanceKlass* ik = InstanceKlass::cast(k);
1834     // if (ik->has_inline_type_fields()) {
1835     //   return;
1836     // }
1837 
1838     // We can be at a point where java mirror does not exist yet.
1839     // So we need to check that the class is at least loaded, to avoid crash from a null mirror.
1840     if (!ik->is_loaded()) {
1841       return;
1842     }
1843 
1844     u2 inlined_count = 0;
1845     for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1846       if (!fld.access_flags().is_static()) {
1847         if (DumperSupport::is_inlined_field(fld)) {
1848           inlined_count++;
1849         }
1850       }
1851     }
1852     if (inlined_count != 0) {
1853       _writer->write_u1(HPROF_CLASS_WITH_INLINED_FIELDS);
1854 
1855       // class ID
1856       _writer->write_classID(ik);
1857       // number of inlined fields
1858       _writer->write_u2(inlined_count);
1859       u2 index = 0;
1860       for (FieldStream fld(ik, false, false); !fld.eos(); fld.next()) {
1861         if (!fld.access_flags().is_static()) {
1862           if (DumperSupport::is_inlined_field(fld)) {
1863             // inlined field index
1864             _writer->write_u2(index);
1865             // synthetic field count
1866             u2 field_count = DumperSupport::get_instance_fields_count(DumperSupport::get_inlined_field_klass(fld));
1867             _writer->write_u2(field_count);
1868             // original field name
1869             _writer->write_symbolID(fld.name());
1870             // inlined field class ID
1871             _writer->write_classID(DumperSupport::get_inlined_field_klass(fld));
1872 
1873             index += field_count;
1874           } else {
1875             index++;
1876           }
1877         }
1878       }
1879     }
1880   }
1881 };
1882 
1883 
1884 void InlinedObjects::init() {
1885   _instance = this;
1886 
1887   struct Closure : public SymbolClosure {
1888     uintx _min_id = max_uintx;
1889     uintx _max_id = 0;
1890     Closure() : _min_id(max_uintx), _max_id(0) {}
1891 
1892     void do_symbol(Symbol** p) {
1893       uintx val = reinterpret_cast<uintx>(*p);
1894       if (val < _min_id) {
1895         _min_id = val;
1896       }
1897       if (val > _max_id) {
1898         _max_id = val;
1899       }
1900     }
1901   } closure;
1902 
1903   SymbolTable::symbols_do(&closure);
1904 
1905   _min_string_id = closure._min_id;
1906   _max_string_id = closure._max_id;
1907 }
1908 
1909 void InlinedObjects::release() {
1910   _instance = nullptr;
1911 
1912   if (_inlined_field_map != nullptr) {
1913     delete _inlined_field_map;
1914     _inlined_field_map = nullptr;
1915   }
1916   if (_flat_arrays != nullptr) {
1917     delete _flat_arrays;
1918     _flat_arrays = nullptr;
1919   }
1920 }
1921 
1922 void InlinedObjects::inlined_field_names_callback(InlinedObjects* _this, const Klass* klass, uintx base_index, int count) {
1923   if (_this->_inlined_field_map == nullptr) {
1924     _this->_inlined_field_map = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<ClassInlinedFields>(100, mtServiceability);
1925   }
1926   _this->_inlined_field_map->append(ClassInlinedFields(klass, base_index));
1927 
1928   // counters for dumping classes with inlined fields
1929   _this->_classes_count++;
1930   _this->_inlined_fields_count += count;
1931 }
1932 
1933 void InlinedObjects::dump_inlined_field_names(AbstractDumpWriter* writer) {
1934   InlinedFieldNameDumper nameDumper(writer, this, inlined_field_names_callback);
1935   ClassLoaderDataGraph::classes_do(&nameDumper);
1936 
1937   if (_inlined_field_map != nullptr) {
1938     // prepare the map for  get_base_index_for().
1939     _inlined_field_map->sort(ClassInlinedFields::compare);
1940   }
1941 }
1942 
1943 uintx InlinedObjects::get_base_index_for(Klass* k) {
1944   if (_inlined_field_map != nullptr) {
1945     bool found = false;
1946     int idx = _inlined_field_map->find_sorted<ClassInlinedFields, ClassInlinedFields::compare>(ClassInlinedFields(k, 0), found);
1947     if (found) {
1948         return _inlined_field_map->at(idx).base_index;
1949     }
1950   }
1951 
1952   // return max_uintx, so get_next_string_id returns 0.
1953   return max_uintx;
1954 }
1955 
1956 uintx InlinedObjects::get_next_string_id(uintx id) {
1957   if (++id == _min_string_id) {
1958     return _max_string_id + 1;
1959   }
1960   return id;
1961 }
1962 
1963 void InlinedObjects::dump_classed_with_inlined_fields(AbstractDumpWriter* writer) {
1964   if (_classes_count != 0) {
1965     // Record for each class contains tag(u1), class ID and count(u2)
1966     // for each inlined field index(u2), synthetic fields count(u2), original field name and class ID
1967     int size = _classes_count * (1 + sizeof(address) + 2)
1968              + _inlined_fields_count * (2 + 2 + sizeof(address) + sizeof(address));
1969     DumperSupport::write_header(writer, HPROF_INLINED_FIELDS, (u4)size);
1970 
1971     InlinedFieldsDumper dumper(writer);
1972     ClassLoaderDataGraph::classes_do(&dumper);
1973   }
1974 }
1975 
1976 void InlinedObjects::add_flat_array(oop array) {
1977   if (_flat_arrays == nullptr) {
1978     _flat_arrays = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<oop>(100, mtServiceability);
1979   }
1980   _flat_arrays->append(array);
1981 }
1982 
1983 void InlinedObjects::dump_flat_arrays(AbstractDumpWriter* writer) {
1984   if (_flat_arrays != nullptr) {
1985     // For each flat array the record contains tag (u1), object ID and class ID.
1986     int size = _flat_arrays->length() * (1 + sizeof(address) + sizeof(address));
1987 
1988     DumperSupport::write_header(writer, HPROF_FLAT_ARRAYS, (u4)size);
1989     for (GrowableArrayIterator<oop> it = _flat_arrays->begin(); it != _flat_arrays->end(); ++it) {
1990       flatArrayOop array = flatArrayOop(*it);
1991       FlatArrayKlass* array_klass = FlatArrayKlass::cast(array->klass());
1992       InlineKlass* element_klass = array_klass->element_klass();
1993       writer->write_u1(HPROF_FLAT_ARRAY);
1994       writer->write_objectID(array);
1995       writer->write_classID(element_klass);
1996     }
1997   }
1998 }
1999 
2000 
2001 // Support class used to generate HPROF_UTF8 records from the entries in the
2002 // SymbolTable.
2003 
2004 class SymbolTableDumper : public SymbolClosure {
2005  private:
2006   AbstractDumpWriter* _writer;
2007   AbstractDumpWriter* writer() const                { return _writer; }
2008  public:
2009   SymbolTableDumper(AbstractDumpWriter* writer)     { _writer = writer; }
2010   void do_symbol(Symbol** p);
2011 };
2012 
2013 void SymbolTableDumper::do_symbol(Symbol** p) {
2014   ResourceMark rm;
2015   Symbol* sym = *p;
2016   int len = sym->utf8_length();
2017   if (len > 0) {
2018     char* s = sym->as_utf8();
2019     DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
2020     writer()->write_symbolID(sym);

2203   }
2204 
2205   if (DumperSupport::mask_dormant_archived_object(o) == NULL) {
2206     log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", p2i(o), o->klass()->external_name());
2207     return;
2208   }
2209 
2210   // If large object list exists and it is large object/array,
2211   // add oop into the list and skip scan. VM thread will process it later.
2212   if (_list != NULL && is_large(o)) {
2213     _list->atomic_push(o);
2214     return;
2215   }
2216 
2217   if (o->is_instance()) {
2218     // create a HPROF_GC_INSTANCE record for each object
2219     DumperSupport::dump_instance(writer(), o);
2220   } else if (o->is_objArray()) {
2221     // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
2222     DumperSupport::dump_object_array(writer(), objArrayOop(o));
2223   } else if (o->is_flatArray()) {
2224     DumperSupport::dump_flat_array(writer(), flatArrayOop(o));
2225   } else if (o->is_typeArray()) {
2226     // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
2227     DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
2228   }
2229 }
2230 
2231 bool HeapObjectDumper::is_large(oop o) {
2232   size_t size = 0;
2233   if (o->is_instance()) {
2234     // Use o->size() * 8 as the upper limit of instance size to avoid iterating static fields
2235     size = o->size() * 8;
2236   } else if (o->is_objArray()) {
2237     objArrayOop array = objArrayOop(o);
2238     BasicType type = ArrayKlass::cast(array->klass())->element_type();
2239     assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
2240     int length = array->length();
2241     int type_size = sizeof(address);
2242     size = (size_t)length * type_size;
2243   } else if (o->is_typeArray()) {
2244     flatArrayOop array = flatArrayOop(o);
2245     BasicType type = ArrayKlass::cast(array->klass())->element_type();
2246     assert(type == T_PRIMITIVE_OBJECT, "invalid array element type");
2247     int length = array->length();
2248     //TODO: FIXME
2249     //int type_size = type2aelembytes(type);
2250     //size = (size_t)length * type_size;
2251   } else if (o->is_typeArray()) {
2252     typeArrayOop array = typeArrayOop(o);
2253     BasicType type = ArrayKlass::cast(array->klass())->element_type();
2254     assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
2255     int length = array->length();
2256     int type_size = type2aelembytes(type);
2257     size = (size_t)length * type_size;
2258   }
2259   return size > HeapDumpLargeObjectList::LargeObjectSizeThreshold;
2260 }
2261 
2262 // The dumper controller for parallel heap dump
2263 class DumperController : public CHeapObj<mtInternal> {
2264  private:
2265    bool     _started;
2266    Monitor* _lock;
2267    uint   _dumper_number;
2268    uint   _complete_number;
2269 
2270  public:

2303      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
2304      while (_complete_number != _dumper_number) {
2305         ml.wait();
2306      }
2307      _started = false;
2308    }
2309 };
2310 
2311 // The VM operation that performs the heap dump
2312 class VM_HeapDumper : public VM_GC_Operation, public WorkerTask {
2313  private:
2314   static VM_HeapDumper*   _global_dumper;
2315   static DumpWriter*      _global_writer;
2316   DumpWriter*             _local_writer;
2317   JavaThread*             _oome_thread;
2318   Method*                 _oome_constructor;
2319   bool                    _gc_before_heap_dump;
2320   GrowableArray<Klass*>*  _klass_map;
2321   ThreadStackTrace**      _stack_traces;
2322   int                     _num_threads;
2323 
2324   // Inlined object support.
2325   InlinedObjects          _inlined_objects;
2326   InlinedObjects* inlined_objects() { return &_inlined_objects; }
2327 
2328   // parallel heap dump support
2329   uint                    _num_dumper_threads;
2330   uint                    _num_writer_threads;
2331   DumperController*       _dumper_controller;
2332   ParallelObjectIterator* _poi;
2333   HeapDumpLargeObjectList* _large_object_list;
2334 
2335   // VMDumperType is for thread that dumps both heap and non-heap data.
2336   static const size_t VMDumperType = 0;
2337   static const size_t WriterType = 1;
2338   static const size_t DumperType = 2;
2339   // worker id of VMDumper thread.
2340   static const size_t VMDumperWorkerId = 0;
2341 
2342   size_t get_worker_type(uint worker_id) {
2343     assert(_num_writer_threads >= 1, "Must be at least one writer");
2344     // worker id of VMDumper that dump heap and non-heap data
2345     if (worker_id == VMDumperWorkerId) {
2346       return VMDumperType;
2347     }

2717       writer()->writer_loop();
2718       return;
2719     }
2720     if (_num_dumper_threads > 1 && get_worker_type(worker_id) == DumperType) {
2721       _dumper_controller->wait_for_start_signal();
2722     }
2723   } else {
2724     // The worker 0 on all non-heap data dumping and part of heap iteration.
2725     // Write the file header - we always use 1.0.2
2726     const char* header = "JAVA PROFILE 1.0.2";
2727 
2728     // header is few bytes long - no chance to overflow int
2729     writer()->write_raw(header, strlen(header) + 1); // NUL terminated
2730     writer()->write_u4(oopSize);
2731     // timestamp is current time in ms
2732     writer()->write_u8(os::javaTimeMillis());
2733     // HPROF_UTF8 records
2734     SymbolTableDumper sym_dumper(writer());
2735     SymbolTable::symbols_do(&sym_dumper);
2736 
2737     // HPROF_UTF8 records for inlined field names.
2738     inlined_objects()->init();
2739     inlined_objects()->dump_inlined_field_names(writer());
2740 
2741     // HPROF_INLINED_FIELDS
2742     inlined_objects()->dump_classed_with_inlined_fields(writer());
2743 
2744     // write HPROF_LOAD_CLASS records
2745     {
2746       LockedClassesDo locked_load_classes(&do_load_class);
2747       ClassLoaderDataGraph::classes_do(&locked_load_classes);
2748     }
2749 
2750     // write HPROF_FRAME and HPROF_TRACE records
2751     // this must be called after _klass_map is built when iterating the classes above.
2752     dump_stack_traces();
2753 
2754     // Writes HPROF_GC_CLASS_DUMP records
2755     {
2756       LockedClassesDo locked_dump_class(&do_class_dump);
2757       ClassLoaderDataGraph::classes_do(&locked_dump_class);
2758     }
2759 
2760     // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
2761     do_threads();
2762 
2763     // HPROF_GC_ROOT_JNI_GLOBAL

2802        if (get_worker_type(worker_id) == VMDumperType) {
2803          _dumper_controller->wait_all_dumpers_complete();
2804          // clear internal buffer;
2805          pw.finish_dump_segment(true);
2806          // refresh the global_writer's buffer and position;
2807          writer()->refresh();
2808        } else {
2809          pw.finish_dump_segment(true);
2810          _dumper_controller->dumper_complete();
2811          return;
2812        }
2813     }
2814   }
2815 
2816   assert(get_worker_type(worker_id) == VMDumperType, "Heap dumper must be VMDumper");
2817   // Use writer() rather than ParDumpWriter to avoid memory consumption.
2818   HeapObjectDumper obj_dumper(writer());
2819   dump_large_objects(&obj_dumper);
2820   // Writes the HPROF_HEAP_DUMP_END record.
2821   DumperSupport::end_of_dump(writer());
2822 
2823   inlined_objects()->dump_flat_arrays(writer());
2824 
2825   // We are done with writing. Release the worker threads.
2826   writer()->deactivate();
2827 
2828   inlined_objects()->release();
2829 }
2830 
2831 void VM_HeapDumper::dump_stack_traces() {
2832   // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
2833   DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
2834   writer()->write_u4((u4) STACK_TRACE_ID);
2835   writer()->write_u4(0);                    // thread number
2836   writer()->write_u4(0);                    // frame count
2837 
2838   _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
2839   int frame_serial_num = 0;
2840   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
2841     oop threadObj = thread->threadObj();
2842     if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
2843       // dump thread stack trace
2844       Thread* current_thread = Thread::current();
2845       ResourceMark rm(current_thread);
2846       HandleMark hm(current_thread);
2847 
2848       ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);
< prev index next >