1 /*
   2  * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2023, Alibaba Group Holding Limited. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "classfile/classLoaderData.inline.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/javaClasses.inline.hpp"
  29 #include "classfile/symbolTable.hpp"
  30 #include "classfile/vmClasses.hpp"
  31 #include "classfile/vmSymbols.hpp"
  32 #include "gc/shared/gcLocker.hpp"
  33 #include "gc/shared/gcVMOperations.hpp"
  34 #include "gc/shared/workerThread.hpp"
  35 #include "jfr/jfrEvents.hpp"
  36 #include "jvm.h"
  37 #include "memory/allocation.inline.hpp"
  38 #include "memory/resourceArea.hpp"
  39 #include "memory/universe.hpp"
  40 #include "oops/fieldStreams.inline.hpp"
  41 #include "oops/flatArrayKlass.hpp"
  42 #include "oops/flatArrayOop.inline.hpp"
  43 #include "oops/klass.inline.hpp"
  44 #include "oops/objArrayKlass.hpp"
  45 #include "oops/objArrayOop.inline.hpp"
  46 #include "oops/oop.inline.hpp"
  47 #include "oops/oopCast.inline.hpp"
  48 #include "oops/typeArrayOop.inline.hpp"
  49 #include "runtime/arguments.hpp"
  50 #include "runtime/atomicAccess.hpp"
  51 #include "runtime/continuationWrapper.inline.hpp"
  52 #include "runtime/frame.inline.hpp"
  53 #include "runtime/handles.inline.hpp"
  54 #include "runtime/javaCalls.hpp"
  55 #include "runtime/javaThread.inline.hpp"
  56 #include "runtime/jniHandles.hpp"
  57 #include "runtime/os.hpp"
  58 #include "runtime/threads.hpp"
  59 #include "runtime/threadSMR.hpp"
  60 #include "runtime/timerTrace.hpp"
  61 #include "runtime/vframe.hpp"
  62 #include "runtime/vmOperations.hpp"
  63 #include "runtime/vmThread.hpp"
  64 #include "services/heapDumper.hpp"
  65 #include "services/heapDumperCompression.hpp"
  66 #include "services/threadService.hpp"
  67 #include "utilities/checkedCast.hpp"
  68 #include "utilities/macros.hpp"
  69 #include "utilities/ostream.hpp"
  70 #ifdef LINUX
  71 #include "os_linux.hpp"
  72 #endif
  73 
  74 /*
  75  * HPROF binary format - description copied from:
  76  *   src/share/demo/jvmti/hprof/hprof_io.c
  77  *
  78  *
  79  *  header    "JAVA PROFILE 1.0.2" (0-terminated)
  80  *
  81  *  u4        size of identifiers. Identifiers are used to represent
  82  *            UTF8 strings, objects, stack traces, etc. They usually
  83  *            have the same size as host pointers.
  84  * u4         high word
  85  * u4         low word    number of milliseconds since 0:00 GMT, 1/1/70
  86  * [record]*  a sequence of records.
  87  *
  88  *
  89  * Record format:
  90  *
  91  * u1         a TAG denoting the type of the record
  92  * u4         number of *microseconds* since the time stamp in the
  93  *            header. (wraps around in a little more than an hour)
  94  * u4         number of bytes *remaining* in the record. Note that
  95  *            this number excludes the tag and the length field itself.
  96  * [u1]*      BODY of the record (a sequence of bytes)
  97  *
  98  *
  99  * The following TAGs are supported:
 100  *
 101  * TAG           BODY       notes
 102  *----------------------------------------------------------
 103  * HPROF_UTF8               a UTF8-encoded name
 104  *
 105  *               id         name ID
 106  *               [u1]*      UTF8 characters (no trailing zero)
 107  *
 108  * HPROF_LOAD_CLASS         a newly loaded class
 109  *
 110  *                u4        class serial number (> 0)
 111  *                id        class object ID
 112  *                u4        stack trace serial number
 113  *                id        class name ID
 114  *
 115  * HPROF_UNLOAD_CLASS       an unloading class
 116  *
 117  *                u4        class serial_number
 118  *
 119  * HPROF_FRAME              a Java stack frame
 120  *
 121  *                id        stack frame ID
 122  *                id        method name ID
 123  *                id        method signature ID
 124  *                id        source file name ID
 125  *                u4        class serial number
 126  *                i4        line number. >0: normal
 127  *                                       -1: unknown
 128  *                                       -2: compiled method
 129  *                                       -3: native method
 130  *
 131  * HPROF_TRACE              a Java stack trace
 132  *
 133  *               u4         stack trace serial number
 134  *               u4         thread serial number
 135  *               u4         number of frames
 136  *               [id]*      stack frame IDs
 137  *
 138  *
 139  * HPROF_ALLOC_SITES        a set of heap allocation sites, obtained after GC
 140  *
 141  *               u2         flags 0x0001: incremental vs. complete
 142  *                                0x0002: sorted by allocation vs. live
 143  *                                0x0004: whether to force a GC
 144  *               u4         cutoff ratio
 145  *               u4         total live bytes
 146  *               u4         total live instances
 147  *               u8         total bytes allocated
 148  *               u8         total instances allocated
 149  *               u4         number of sites that follow
 150  *               [u1        is_array: 0:  normal object
 151  *                                    2:  object array
 152  *                                    4:  boolean array
 153  *                                    5:  char array
 154  *                                    6:  float array
 155  *                                    7:  double array
 156  *                                    8:  byte array
 157  *                                    9:  short array
 158  *                                    10: int array
 159  *                                    11: long array
 160  *                u4        class serial number (may be zero during startup)
 161  *                u4        stack trace serial number
 162  *                u4        number of bytes alive
 163  *                u4        number of instances alive
 164  *                u4        number of bytes allocated
 165  *                u4]*      number of instance allocated
 166  *
 167  * HPROF_START_THREAD       a newly started thread.
 168  *
 169  *               u4         thread serial number (> 0)
 170  *               id         thread object ID
 171  *               u4         stack trace serial number
 172  *               id         thread name ID
 173  *               id         thread group name ID
 174  *               id         thread group parent name ID
 175  *
 176  * HPROF_END_THREAD         a terminating thread.
 177  *
 178  *               u4         thread serial number
 179  *
 180  * HPROF_HEAP_SUMMARY       heap summary
 181  *
 182  *               u4         total live bytes
 183  *               u4         total live instances
 184  *               u8         total bytes allocated
 185  *               u8         total instances allocated
 186  *
 187  * HPROF_HEAP_DUMP          denote a heap dump
 188  *
 189  *               [heap dump sub-records]*
 190  *
 191  *                          There are four kinds of heap dump sub-records:
 192  *
 193  *               u1         sub-record type
 194  *
 195  *               HPROF_GC_ROOT_UNKNOWN         unknown root
 196  *
 197  *                          id         object ID
 198  *
 199  *               HPROF_GC_ROOT_THREAD_OBJ      thread object
 200  *
 201  *                          id         thread object ID  (may be 0 for a
 202  *                                     thread newly attached through JNI)
 203  *                          u4         thread sequence number
 204  *                          u4         stack trace sequence number
 205  *
 206  *               HPROF_GC_ROOT_JNI_GLOBAL      JNI global ref root
 207  *
 208  *                          id         object ID
 209  *                          id         JNI global ref ID
 210  *
 211  *               HPROF_GC_ROOT_JNI_LOCAL       JNI local ref
 212  *
 213  *                          id         object ID
 214  *                          u4         thread serial number
 215  *                          u4         frame # in stack trace (-1 for empty)
 216  *
 217  *               HPROF_GC_ROOT_JAVA_FRAME      Java stack frame
 218  *
 219  *                          id         object ID
 220  *                          u4         thread serial number
 221  *                          u4         frame # in stack trace (-1 for empty)
 222  *
 223  *               HPROF_GC_ROOT_NATIVE_STACK    Native stack
 224  *
 225  *                          id         object ID
 226  *                          u4         thread serial number
 227  *
 228  *               HPROF_GC_ROOT_STICKY_CLASS    System class
 229  *
 230  *                          id         object ID
 231  *
 232  *               HPROF_GC_ROOT_THREAD_BLOCK    Reference from thread block
 233  *
 234  *                          id         object ID
 235  *                          u4         thread serial number
 236  *
 237  *               HPROF_GC_ROOT_MONITOR_USED    Busy monitor
 238  *
 239  *                          id         object ID
 240  *
 241  *               HPROF_GC_CLASS_DUMP           dump of a class object
 242  *
 243  *                          id         class object ID
 244  *                          u4         stack trace serial number
 245  *                          id         super class object ID
 246  *                          id         class loader object ID
 247  *                          id         signers object ID
 248  *                          id         protection domain object ID
 249  *                          id         reserved
 250  *                          id         reserved
 251  *
 252  *                          u4         instance size (in bytes)
 253  *
 254  *                          u2         size of constant pool
 255  *                          [u2,       constant pool index,
 256  *                           ty,       type
 257  *                                     2:  object
 258  *                                     4:  boolean
 259  *                                     5:  char
 260  *                                     6:  float
 261  *                                     7:  double
 262  *                                     8:  byte
 263  *                                     9:  short
 264  *                                     10: int
 265  *                                     11: long
 266  *                           vl]*      and value
 267  *
 268  *                          u2         number of static fields
 269  *                          [id,       static field name,
 270  *                           ty,       type,
 271  *                           vl]*      and value
 272  *
 273  *                          u2         number of inst. fields (not inc. super)
 274  *                          [id,       instance field name,
 275  *                           ty]*      type
 276  *
 277  *               HPROF_GC_INSTANCE_DUMP        dump of a normal object
 278  *
 279  *                          id         object ID
 280  *                          u4         stack trace serial number
 281  *                          id         class object ID
 282  *                          u4         number of bytes that follow
 283  *                          [vl]*      instance field values (class, followed
 284  *                                     by super, super's super ...)
 285  *
 286  *               HPROF_GC_OBJ_ARRAY_DUMP       dump of an object array
 287  *
 288  *                          id         array object ID
 289  *                          u4         stack trace serial number
 290  *                          u4         number of elements
 291  *                          id         array class ID
 292  *                          [id]*      elements
 293  *
 294  *               HPROF_GC_PRIM_ARRAY_DUMP      dump of a primitive array
 295  *
 296  *                          id         array object ID
 297  *                          u4         stack trace serial number
 298  *                          u4         number of elements
 299  *                          u1         element type
 300  *                                     4:  boolean array
 301  *                                     5:  char array
 302  *                                     6:  float array
 303  *                                     7:  double array
 304  *                                     8:  byte array
 305  *                                     9:  short array
 306  *                                     10: int array
 307  *                                     11: long array
 308  *                          [u1]*      elements
 309  *
 310  * HPROF_CPU_SAMPLES        a set of sample traces of running threads
 311  *
 312  *                u4        total number of samples
 313  *                u4        # of traces
 314  *               [u4        # of samples
 315  *                u4]*      stack trace serial number
 316  *
 317  * HPROF_CONTROL_SETTINGS   the settings of on/off switches
 318  *
 319  *                u4        0x00000001: alloc traces on/off
 320  *                          0x00000002: cpu sampling on/off
 321  *                u2        stack trace depth
 322  *
 323  *
 324  * When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
 325  * be generated as a sequence of heap dump segments. This sequence is
 326  * terminated by an end record. The additional tags allowed by format
 327  * "JAVA PROFILE 1.0.2" are:
 328  *
 329  * HPROF_HEAP_DUMP_SEGMENT  denote a heap dump segment
 330  *
 331  *               [heap dump sub-records]*
 332  *               The same sub-record types allowed by HPROF_HEAP_DUMP
 333  *
 334  * HPROF_HEAP_DUMP_END      denotes the end of a heap dump
 335  *
 336  */
 337 
 338 
 339 // HPROF tags
 340 
 341 enum hprofTag : u1 {
 342   // top-level records
 343   HPROF_UTF8                    = 0x01,
 344   HPROF_LOAD_CLASS              = 0x02,
 345   HPROF_UNLOAD_CLASS            = 0x03,
 346   HPROF_FRAME                   = 0x04,
 347   HPROF_TRACE                   = 0x05,
 348   HPROF_ALLOC_SITES             = 0x06,
 349   HPROF_HEAP_SUMMARY            = 0x07,
 350   HPROF_START_THREAD            = 0x0A,
 351   HPROF_END_THREAD              = 0x0B,
 352   HPROF_HEAP_DUMP               = 0x0C,
 353   HPROF_CPU_SAMPLES             = 0x0D,
 354   HPROF_CONTROL_SETTINGS        = 0x0E,
 355 
 356   // 1.0.2 record types
 357   HPROF_HEAP_DUMP_SEGMENT       = 0x1C,
 358   HPROF_HEAP_DUMP_END           = 0x2C,
 359 
 360   // field types
 361   HPROF_ARRAY_OBJECT            = 0x01,
 362   HPROF_NORMAL_OBJECT           = 0x02,
 363   HPROF_BOOLEAN                 = 0x04,
 364   HPROF_CHAR                    = 0x05,
 365   HPROF_FLOAT                   = 0x06,
 366   HPROF_DOUBLE                  = 0x07,
 367   HPROF_BYTE                    = 0x08,
 368   HPROF_SHORT                   = 0x09,
 369   HPROF_INT                     = 0x0A,
 370   HPROF_LONG                    = 0x0B,
 371 
 372   // data-dump sub-records
 373   HPROF_GC_ROOT_UNKNOWN         = 0xFF,
 374   HPROF_GC_ROOT_JNI_GLOBAL      = 0x01,
 375   HPROF_GC_ROOT_JNI_LOCAL       = 0x02,
 376   HPROF_GC_ROOT_JAVA_FRAME      = 0x03,
 377   HPROF_GC_ROOT_NATIVE_STACK    = 0x04,
 378   HPROF_GC_ROOT_STICKY_CLASS    = 0x05,
 379   HPROF_GC_ROOT_THREAD_BLOCK    = 0x06,
 380   HPROF_GC_ROOT_MONITOR_USED    = 0x07,
 381   HPROF_GC_ROOT_THREAD_OBJ      = 0x08,
 382   HPROF_GC_CLASS_DUMP           = 0x20,
 383   HPROF_GC_INSTANCE_DUMP        = 0x21,
 384   HPROF_GC_OBJ_ARRAY_DUMP       = 0x22,
 385   HPROF_GC_PRIM_ARRAY_DUMP      = 0x23
 386 };
 387 
 388 // Default stack trace ID (used for dummy HPROF_TRACE record)
 389 enum {
 390   STACK_TRACE_ID = 1,
 391   INITIAL_CLASS_COUNT = 200
 392 };
 393 
 394 // Supports I/O operations for a dump
 395 // Base class for dump and parallel dump
 396 class AbstractDumpWriter : public CHeapObj<mtInternal> {
 397  protected:
 398   enum {
 399     io_buffer_max_size = 1*M,
 400     dump_segment_header_size = 9
 401   };
 402 
 403   char* _buffer;    // internal buffer
 404   size_t _size;
 405   size_t _pos;
 406 
 407   bool _in_dump_segment; // Are we currently in a dump segment?
 408   bool _is_huge_sub_record; // Are we writing a sub-record larger than the buffer size?
 409   DEBUG_ONLY(size_t _sub_record_left;) // The bytes not written for the current sub-record.
 410   DEBUG_ONLY(bool _sub_record_ended;) // True if we have called the end_sub_record().
 411 
 412   char* buffer() const                          { return _buffer; }
 413   size_t buffer_size() const                    { return _size; }
 414   void set_position(size_t pos)                 { _pos = pos; }
 415 
 416   // Can be called if we have enough room in the buffer.
 417   void write_fast(const void* s, size_t len);
 418 
 419   // Returns true if we have enough room in the buffer for 'len' bytes.
 420   bool can_write_fast(size_t len);
 421 
 422   void write_address(address a);
 423 
 424  public:
 425   AbstractDumpWriter() :
 426     _buffer(nullptr),
 427     _size(io_buffer_max_size),
 428     _pos(0),
 429     _in_dump_segment(false) { }
 430 
 431   // Total number of bytes written to the disk
 432   virtual julong bytes_written() const = 0;
 433   // Return non-null if error occurred
 434   virtual char const* error() const = 0;
 435 
 436   size_t position() const                       { return _pos; }
 437   // writer functions
 438   virtual void write_raw(const void* s, size_t len);
 439   void write_u1(u1 x);
 440   void write_u2(u2 x);
 441   void write_u4(u4 x);
 442   void write_u8(u8 x);
 443   void write_objectID(oop o);
 444   void write_objectID(uintptr_t id);
 445   void write_rootID(oop* p);
 446   void write_symbolID(Symbol* o);
 447   void write_classID(Klass* k);
 448   void write_id(u4 x);
 449 
 450   // Start a new sub-record. Starts a new heap dump segment if needed.
 451   void start_sub_record(u1 tag, u4 len);
 452   // Ends the current sub-record.
 453   void end_sub_record();
 454   // Finishes the current dump segment if not already finished.
 455   void finish_dump_segment();
 456   // Flush internal buffer to persistent storage
 457   virtual void flush() = 0;
 458 };
 459 
 460 void AbstractDumpWriter::write_fast(const void* s, size_t len) {
 461   assert(!_in_dump_segment || (_sub_record_left >= len), "sub-record too large");
 462   assert(buffer_size() - position() >= len, "Must fit");
 463   DEBUG_ONLY(_sub_record_left -= len);
 464   memcpy(buffer() + position(), s, len);
 465   set_position(position() + len);
 466 }
 467 
 468 bool AbstractDumpWriter::can_write_fast(size_t len) {
 469   return buffer_size() - position() >= len;
 470 }
 471 
 472 // write raw bytes
 473 void AbstractDumpWriter::write_raw(const void* s, size_t len) {
 474   assert(!_in_dump_segment || (_sub_record_left >= len), "sub-record too large");
 475   DEBUG_ONLY(_sub_record_left -= len);
 476 
 477   // flush buffer to make room.
 478   while (len > buffer_size() - position()) {
 479     assert(!_in_dump_segment || _is_huge_sub_record,
 480            "Cannot overflow in non-huge sub-record.");
 481     size_t to_write = buffer_size() - position();
 482     memcpy(buffer() + position(), s, to_write);
 483     s = (void*) ((char*) s + to_write);
 484     len -= to_write;
 485     set_position(position() + to_write);
 486     flush();
 487   }
 488 
 489   memcpy(buffer() + position(), s, len);
 490   set_position(position() + len);
 491 }
 492 
 493 // Makes sure we inline the fast write into the write_u* functions. This is a big speedup.
 494 #define WRITE_KNOWN_TYPE(p, len) do { if (can_write_fast((len))) write_fast((p), (len)); \
 495                                       else write_raw((p), (len)); } while (0)
 496 
 497 void AbstractDumpWriter::write_u1(u1 x) {
 498   WRITE_KNOWN_TYPE(&x, 1);
 499 }
 500 
 501 void AbstractDumpWriter::write_u2(u2 x) {
 502   u2 v;
 503   Bytes::put_Java_u2((address)&v, x);
 504   WRITE_KNOWN_TYPE(&v, 2);
 505 }
 506 
 507 void AbstractDumpWriter::write_u4(u4 x) {
 508   u4 v;
 509   Bytes::put_Java_u4((address)&v, x);
 510   WRITE_KNOWN_TYPE(&v, 4);
 511 }
 512 
 513 void AbstractDumpWriter::write_u8(u8 x) {
 514   u8 v;
 515   Bytes::put_Java_u8((address)&v, x);
 516   WRITE_KNOWN_TYPE(&v, 8);
 517 }
 518 
 519 void AbstractDumpWriter::write_address(address a) {
 520 #ifdef _LP64
 521   write_u8((u8)a);
 522 #else
 523   write_u4((u4)a);
 524 #endif
 525 }
 526 
 527 void AbstractDumpWriter::write_objectID(oop o) {
 528   write_address(cast_from_oop<address>(o));
 529 }
 530 
 531 void AbstractDumpWriter::write_objectID(uintptr_t id) {
 532   write_address((address)id);
 533 }
 534 
 535 void AbstractDumpWriter::write_rootID(oop* p) {
 536   write_address((address)p);
 537 }
 538 
 539 void AbstractDumpWriter::write_symbolID(Symbol* s) {
 540   write_address((address)((uintptr_t)s));
 541 }
 542 
 543 void AbstractDumpWriter::write_id(u4 x) {
 544 #ifdef _LP64
 545   write_u8((u8) x);
 546 #else
 547   write_u4(x);
 548 #endif
 549 }
 550 
 551 // We use java mirror as the class ID
 552 void AbstractDumpWriter::write_classID(Klass* k) {
 553   write_objectID(k->java_mirror());
 554 }
 555 
 556 void AbstractDumpWriter::finish_dump_segment() {
 557   if (_in_dump_segment) {
 558     assert(_sub_record_left == 0, "Last sub-record not written completely");
 559     assert(_sub_record_ended, "sub-record must have ended");
 560 
 561     // Fix up the dump segment length if we haven't written a huge sub-record last
 562     // (in which case the segment length was already set to the correct value initially).
 563     if (!_is_huge_sub_record) {
 564       assert(position() > dump_segment_header_size, "Dump segment should have some content");
 565       Bytes::put_Java_u4((address) (buffer() + 5),
 566                          (u4) (position() - dump_segment_header_size));
 567     } else {
 568       // Finish process huge sub record
 569       // Set _is_huge_sub_record to false so the parallel dump writer can flush data to file.
 570       _is_huge_sub_record = false;
 571     }
 572 
 573     _in_dump_segment = false;
 574     flush();
 575   }
 576 }
 577 
 578 void AbstractDumpWriter::start_sub_record(u1 tag, u4 len) {
 579   if (!_in_dump_segment) {
 580     if (position() > 0) {
 581       flush();
 582     }
 583 
 584     assert(position() == 0 && buffer_size() > dump_segment_header_size, "Must be at the start");
 585 
 586     write_u1(HPROF_HEAP_DUMP_SEGMENT);
 587     write_u4(0); // timestamp
 588     // Will be fixed up later if we add more sub-records.  If this is a huge sub-record,
 589     // this is already the correct length, since we don't add more sub-records.
 590     write_u4(len);
 591     assert(Bytes::get_Java_u4((address)(buffer() + 5)) == len, "Inconsistent size!");
 592     _in_dump_segment = true;
 593     _is_huge_sub_record = len > buffer_size() - dump_segment_header_size;
 594   } else if (_is_huge_sub_record || (len > buffer_size() - position())) {
 595     // This object will not fit in completely or the last sub-record was huge.
 596     // Finish the current segment and try again.
 597     finish_dump_segment();
 598     start_sub_record(tag, len);
 599 
 600     return;
 601   }
 602 
 603   DEBUG_ONLY(_sub_record_left = len);
 604   DEBUG_ONLY(_sub_record_ended = false);
 605 
 606   write_u1(tag);
 607 }
 608 
 609 void AbstractDumpWriter::end_sub_record() {
 610   assert(_in_dump_segment, "must be in dump segment");
 611   assert(_sub_record_left == 0, "sub-record not written completely");
 612   assert(!_sub_record_ended, "Must not have ended yet");
 613   DEBUG_ONLY(_sub_record_ended = true);
 614 }
 615 
 616 // Supports I/O operations for a dump
 617 
 618 class DumpWriter : public AbstractDumpWriter {
 619 private:
 620   FileWriter* _writer;
 621   AbstractCompressor* _compressor;
 622   size_t _bytes_written;
 623   char* _error;
 624   // Compression support
 625   char* _out_buffer;
 626   size_t _out_size;
 627   size_t _out_pos;
 628   char* _tmp_buffer;
 629   size_t _tmp_size;
 630 
 631 private:
 632   void do_compress();
 633 
 634 public:
 635   DumpWriter(const char* path, bool overwrite, AbstractCompressor* compressor);
 636   ~DumpWriter();
 637   julong bytes_written() const override        { return (julong) _bytes_written; }
 638   char const* error() const override           { return _error; }
 639   void set_error(const char* error)            { _error = (char*)error; }
 640   bool has_error() const                       { return _error != nullptr; }
 641   const char* get_file_path() const            { return _writer->get_file_path(); }
 642   AbstractCompressor* compressor()             { return _compressor; }
 643   bool is_overwrite() const                    { return _writer->is_overwrite(); }
 644 
 645   void flush() override;
 646 
 647 private:
 648   // internals for DumpMerger
 649   friend class DumpMerger;
 650   void set_bytes_written(julong bytes_written) { _bytes_written = bytes_written; }
 651   int get_fd() const                           { return _writer->get_fd(); }
 652   void set_compressor(AbstractCompressor* p)   { _compressor = p; }
 653 };
 654 
 655 DumpWriter::DumpWriter(const char* path, bool overwrite, AbstractCompressor* compressor) :
 656   AbstractDumpWriter(),
 657   _writer(new (std::nothrow) FileWriter(path, overwrite)),
 658   _compressor(compressor),
 659   _bytes_written(0),
 660   _error(nullptr),
 661   _out_buffer(nullptr),
 662   _out_size(0),
 663   _out_pos(0),
 664   _tmp_buffer(nullptr),
 665   _tmp_size(0) {
 666   _error = (char*)_writer->open_writer();
 667   if (_error == nullptr) {
 668     _buffer = (char*)os::malloc(io_buffer_max_size, mtInternal);
 669     if (compressor != nullptr) {
 670       _error = (char*)_compressor->init(io_buffer_max_size, &_out_size, &_tmp_size);
 671       if (_error == nullptr) {
 672         if (_out_size > 0) {
 673           _out_buffer = (char*)os::malloc(_out_size, mtInternal);
 674         }
 675         if (_tmp_size > 0) {
 676           _tmp_buffer = (char*)os::malloc(_tmp_size, mtInternal);
 677         }
 678       }
 679     }
 680   }
 681   // initialize internal buffer
 682   _pos = 0;
 683   _size = io_buffer_max_size;
 684 }
 685 
 686 DumpWriter::~DumpWriter(){
 687   if (_buffer != nullptr) {
 688     os::free(_buffer);
 689   }
 690   if (_out_buffer != nullptr) {
 691     os::free(_out_buffer);
 692   }
 693   if (_tmp_buffer != nullptr) {
 694     os::free(_tmp_buffer);
 695   }
 696   if (_writer != nullptr) {
 697     delete _writer;
 698   }
 699   _bytes_written = -1;
 700 }
 701 
 702 // flush any buffered bytes to the file
 703 void DumpWriter::flush() {
 704   if (_pos <= 0) {
 705     return;
 706   }
 707   if (has_error()) {
 708     _pos = 0;
 709     return;
 710   }
 711   char* result = nullptr;
 712   if (_compressor == nullptr) {
 713     result = (char*)_writer->write_buf(_buffer, _pos);
 714     _bytes_written += _pos;
 715   } else {
 716     do_compress();
 717     if (!has_error()) {
 718       result = (char*)_writer->write_buf(_out_buffer, _out_pos);
 719       _bytes_written += _out_pos;
 720     }
 721   }
 722   _pos = 0; // reset pos to make internal buffer available
 723 
 724   if (result != nullptr) {
 725     set_error(result);
 726   }
 727 }
 728 
 729 void DumpWriter::do_compress() {
 730   const char* msg = _compressor->compress(_buffer, _pos, _out_buffer, _out_size,
 731                                           _tmp_buffer, _tmp_size, &_out_pos);
 732 
 733   if (msg != nullptr) {
 734     set_error(msg);
 735   }
 736 }
 737 
 738 class DumperClassCacheTable;
 739 class DumperClassCacheTableEntry;
 740 class DumperFlatObject;
 741 class DumperFlatObjectList;
 742 
 743 // Support class with a collection of functions used when dumping the heap
 744 class DumperSupport : AllStatic {
 745  public:
 746 
 747   // write a header of the given type
 748   static void write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len);
 749 
 750   // returns hprof tag for the given type signature
 751   static hprofTag sig2tag(Symbol* sig);
 752   // returns hprof tag for the given basic type
 753   static hprofTag type2tag(BasicType type);
 754   // Returns the size of the data to write.
 755   static u4 sig2size(Symbol* sig);
 756 
 757   // returns the size of the instance of the given class
 758   static u4 instance_size(InstanceKlass* ik);
 759 
 760   // dump a jfloat
 761   static void dump_float(AbstractDumpWriter* writer, jfloat f);
 762   // dump a jdouble
 763   static void dump_double(AbstractDumpWriter* writer, jdouble d);
 764   // dumps the raw value of the given field
 765   static void dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset);
 766   // returns the size of the static fields; also counts the static fields
 767   static u4 get_static_fields_size(InstanceKlass* ik, u2& field_count);
 768   // dumps static fields of the given class
 769   static void dump_static_fields(AbstractDumpWriter* writer, Klass* k);
 770   // dump the raw values of the instance fields of the given object, fills flat_fields
 771   static void dump_instance_fields(AbstractDumpWriter* writer, oop o, int offset,
 772                                    DumperClassCacheTableEntry* class_cache_entry, DumperFlatObjectList* flat_fields);
 773   // get the count of the instance fields for a given class
 774   static u2 get_instance_fields_count(InstanceKlass* ik);
 775   // dumps the definition of the instance fields for a given class
 776   static void dump_instance_field_descriptors(AbstractDumpWriter* writer, InstanceKlass* k);
 777   // creates HPROF_GC_INSTANCE_DUMP record for the given object, fills flat_fields
 778   static void dump_instance(AbstractDumpWriter* writer, uintptr_t id, oop o, int offset, InstanceKlass* ik,
 779                             DumperClassCacheTable* class_cache, DumperFlatObjectList* flat_fields);
 780   // creates HPROF_GC_CLASS_DUMP record for the given instance class
 781   static void dump_instance_class(AbstractDumpWriter* writer, InstanceKlass* ik);
 782   // creates HPROF_GC_CLASS_DUMP record for a given array class
 783   static void dump_array_class(AbstractDumpWriter* writer, Klass* k);
 784 
 785   // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array, fills flat_elements if the object is flat array
 786   static void dump_object_array(AbstractDumpWriter* writer, objArrayOop array, DumperFlatObjectList* flat_elements);
 787   // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
 788   static void dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array);
 789   // create HPROF_FRAME record for the given method and bci
 790   static void dump_stack_frame(AbstractDumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
 791 
 792   // check if we need to truncate an array
 793   static int calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size);
 794 
 795   // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
 796   static void end_of_dump(AbstractDumpWriter* writer);
 797 
 798   static oop mask_dormant_archived_object(oop o, oop ref_obj) {
 799     if (o != nullptr && o->klass()->java_mirror_no_keepalive() == nullptr) {
 800       // Ignore this object since the corresponding java mirror is not loaded.
 801       // Might be a dormant archive object.
 802       report_dormant_archived_object(o, ref_obj);
 803       return nullptr;
 804     } else {
 805       return o;
 806     }
 807   }
 808 
 809   static void report_dormant_archived_object(oop o, oop ref_obj) {
 810     if (log_is_enabled(Trace, aot, heap)) {
 811       ResourceMark rm;
 812       if (ref_obj != nullptr) {
 813         log_trace(aot, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
 814                   p2i(o), o->klass()->external_name(),
 815                   p2i(ref_obj), ref_obj->klass()->external_name());
 816       } else {
 817         log_trace(aot, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)",
 818                   p2i(o), o->klass()->external_name());
 819       }
 820     }
 821   }
 822 
 823   // Direct instances of ObjArrayKlass represent the Java types that Java code can see.
 824   // RefArrayKlass/FlatArrayKlass describe different implementations of the arrays, filter them out to avoid duplicates.
 825   static bool filter_out_klass(Klass* k) {
 826     if (k->is_objArray_klass() && k->kind() != Klass::KlassKind::ObjArrayKlassKind) {
 827       return true;
 828     }
 829     return false;
 830   }
 831 };
 832 
 833 // Hash table of klasses to the klass metadata. This should greatly improve the
 834 // hash dumping performance. This hash table is supposed to be used by a single
 835 // thread only.
 836 //
 837 class DumperClassCacheTableEntry : public CHeapObj<mtServiceability> {
 838   friend class DumperClassCacheTable;
 839 public:
 840   class FieldDescriptor {
 841   private:
 842     char _sigs_start;
 843     int _offset;
 844     InlineKlass* _inline_klass; // nullptr for heap object
 845     LayoutKind _layout_kind;
 846   public:
 847     FieldDescriptor(): _sigs_start(0), _offset(0), _inline_klass(nullptr), _layout_kind(LayoutKind::UNKNOWN) {}
 848 
 849     template<typename FieldStreamType>
 850     FieldDescriptor(const FieldStreamType& field)
 851       : _sigs_start(field.signature()->char_at(0)), _offset(field.offset())
 852     {
 853       if (field.is_flat()) {
 854         const fieldDescriptor& fd = field.field_descriptor();
 855         InstanceKlass* holder_klass = fd.field_holder();
 856         InlineLayoutInfo* layout_info = holder_klass->inline_layout_info_adr(fd.index());
 857         _inline_klass = layout_info->klass();
 858         _layout_kind = layout_info->kind();
 859       } else {
 860         _inline_klass = nullptr;
 861         _layout_kind = LayoutKind::REFERENCE;
 862       }
 863     }
 864 
 865     char sig_start() const            { return _sigs_start; }
 866     int offset() const                { return _offset; }
 867     bool is_flat() const              { return _inline_klass != nullptr; }
 868     InlineKlass* inline_klass() const { return _inline_klass; }
 869     LayoutKind layout_kind() const    { return _layout_kind; }
 870     bool is_flat_nullable() const     { return LayoutKindHelper::is_nullable_flat(_layout_kind); }
 871   };
 872 
 873 private:
 874   GrowableArray<FieldDescriptor> _fields;
 875   u4 _instance_size;
 876 
 877 public:
 878   DumperClassCacheTableEntry(): _instance_size(0) {}
 879 
 880   template<typename FieldStreamType>
 881   void add_field(const FieldStreamType& field) {
 882     _fields.push(FieldDescriptor(field));
 883     _instance_size += DumperSupport::sig2size(field.signature());
 884   }
 885 
 886   const FieldDescriptor& field(int index) const { return _fields.at(index); }
 887   int field_count() const { return _fields.length(); }
 888   u4 instance_size() const { return _instance_size; }
 889 };
 890 
 891 class DumperClassCacheTable {
 892 private:
 893   // HashTable SIZE is specified at compile time so we
 894   // use 1031 which is the first prime after 1024.
 895   static constexpr size_t TABLE_SIZE = 1031;
 896 
 897   // Maintain the cache for N classes. This limits memory footprint
 898   // impact, regardless of how many classes we have in the dump.
 899   // This also improves look up performance by keeping the statically
 900   // sized table from overloading.
 901   static constexpr int CACHE_TOP = 256;
 902 
 903   typedef HashTable<InstanceKlass*, DumperClassCacheTableEntry*,
 904                     TABLE_SIZE, AnyObj::C_HEAP, mtServiceability> PtrTable;
 905   PtrTable* _ptrs;
 906 
 907   // Single-slot cache to handle the major case of objects of the same
 908   // class back-to-back, e.g. from T[].
 909   InstanceKlass* _last_ik;
 910   DumperClassCacheTableEntry* _last_entry;
 911 
 912   void unlink_all(PtrTable* table) {
 913     class CleanupEntry: StackObj {
 914     public:
 915       bool do_entry(InstanceKlass*& key, DumperClassCacheTableEntry*& entry) {
 916         delete entry;
 917         return true;
 918       }
 919     } cleanup;
 920     table->unlink(&cleanup);
 921   }
 922 
 923 public:
 924   DumperClassCacheTableEntry* lookup_or_create(InstanceKlass* ik) {
 925     if (_last_ik == ik) {
 926       return _last_entry;
 927     }
 928 
 929     DumperClassCacheTableEntry* entry;
 930     DumperClassCacheTableEntry** from_cache = _ptrs->get(ik);
 931     if (from_cache == nullptr) {
 932       entry = new DumperClassCacheTableEntry();
 933       for (HierarchicalFieldStream<JavaFieldStream> fld(ik); !fld.done(); fld.next()) {
 934         if (!fld.access_flags().is_static()) {
 935           entry->add_field(fld);
 936         }
 937       }
 938 
 939       if (_ptrs->number_of_entries() >= CACHE_TOP) {
 940         // We do not track the individual hit rates for table entries.
 941         // Purge the entire table, and let the cache catch up with new
 942         // distribution.
 943         unlink_all(_ptrs);
 944       }
 945 
 946       _ptrs->put(ik, entry);
 947     } else {
 948       entry = *from_cache;
 949     }
 950 
 951     // Remember for single-slot cache.
 952     _last_ik = ik;
 953     _last_entry = entry;
 954 
 955     return entry;
 956   }
 957 
 958   DumperClassCacheTable() : _ptrs(new (mtServiceability) PtrTable), _last_ik(nullptr), _last_entry(nullptr) {}
 959 
 960   ~DumperClassCacheTable() {
 961     unlink_all(_ptrs);
 962     delete _ptrs;
 963   }
 964 };
 965 
 966 // Describes flat object (flatted field or element of flat array) in the holder oop
 967 class DumperFlatObject: public CHeapObj<mtServiceability> {
 968   friend class DumperFlatObjectList;
 969 private:
 970   DumperFlatObject* _next;
 971 
 972   const uintptr_t _id; // object id
 973 
 974   const int _offset;
 975   InlineKlass* const _inline_klass;
 976 
 977 public:
 978   DumperFlatObject(uintptr_t id, int offset, InlineKlass* inline_klass)
 979     : _next(nullptr), _id(id), _offset(offset), _inline_klass(inline_klass) {
 980   }
 981 
 982   uintptr_t object_id()       const { return _id; }
 983   int offset()                const { return _offset; }
 984   InlineKlass* inline_klass() const { return _inline_klass; }
 985 };
 986 
 987 class FlatObjectIdProvider {
 988 public:
 989   virtual uintptr_t get_id() = 0;
 990 };
 991 
 992 // Simple FIFO.
 993 class DumperFlatObjectList {
 994 private:
 995   FlatObjectIdProvider* _id_provider;
 996   DumperFlatObject* _head;
 997   DumperFlatObject* _tail;
 998 
 999   void push(DumperFlatObject* obj) {
1000     if (_head == nullptr) {
1001       _head = _tail = obj;
1002     } else {
1003       assert(_tail != nullptr, "must be");
1004       _tail->_next = obj;
1005       _tail = obj;
1006     }
1007   }
1008 
1009 public:
1010   DumperFlatObjectList(FlatObjectIdProvider* id_provider): _id_provider(id_provider), _head(nullptr), _tail(nullptr) {}
1011 
1012   bool is_empty() const { return _head == nullptr; }
1013 
1014   uintptr_t push(int offset, InlineKlass* inline_klass) {
1015     uintptr_t id = _id_provider->get_id();
1016     DumperFlatObject* obj = new DumperFlatObject(id, offset, inline_klass);
1017     push(obj);
1018     return id;
1019   }
1020 
1021   DumperFlatObject* pop() {
1022     assert(!is_empty(), "sanity");
1023     DumperFlatObject* element = _head;
1024     _head = element->_next;
1025     element->_next = nullptr;
1026     return element;
1027   }
1028 };
1029 
1030 // write a header of the given type
1031 void DumperSupport:: write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len) {
1032   writer->write_u1(tag);
1033   writer->write_u4(0);                  // current ticks
1034   writer->write_u4(len);
1035 }
1036 
1037 // returns hprof tag for the given type signature
1038 hprofTag DumperSupport::sig2tag(Symbol* sig) {
1039   switch (sig->char_at(0)) {
1040     case JVM_SIGNATURE_CLASS    : return HPROF_NORMAL_OBJECT;
1041     case JVM_SIGNATURE_ARRAY    : return HPROF_NORMAL_OBJECT;
1042     case JVM_SIGNATURE_BYTE     : return HPROF_BYTE;
1043     case JVM_SIGNATURE_CHAR     : return HPROF_CHAR;
1044     case JVM_SIGNATURE_FLOAT    : return HPROF_FLOAT;
1045     case JVM_SIGNATURE_DOUBLE   : return HPROF_DOUBLE;
1046     case JVM_SIGNATURE_INT      : return HPROF_INT;
1047     case JVM_SIGNATURE_LONG     : return HPROF_LONG;
1048     case JVM_SIGNATURE_SHORT    : return HPROF_SHORT;
1049     case JVM_SIGNATURE_BOOLEAN  : return HPROF_BOOLEAN;
1050     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
1051   }
1052 }
1053 
1054 hprofTag DumperSupport::type2tag(BasicType type) {
1055   switch (type) {
1056     case T_BYTE     : return HPROF_BYTE;
1057     case T_CHAR     : return HPROF_CHAR;
1058     case T_FLOAT    : return HPROF_FLOAT;
1059     case T_DOUBLE   : return HPROF_DOUBLE;
1060     case T_INT      : return HPROF_INT;
1061     case T_LONG     : return HPROF_LONG;
1062     case T_SHORT    : return HPROF_SHORT;
1063     case T_BOOLEAN  : return HPROF_BOOLEAN;
1064     default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
1065   }
1066 }
1067 
1068 u4 DumperSupport::sig2size(Symbol* sig) {
1069   switch (sig->char_at(0)) {
1070     case JVM_SIGNATURE_CLASS:
1071     case JVM_SIGNATURE_ARRAY: return sizeof(address);
1072     case JVM_SIGNATURE_BOOLEAN:
1073     case JVM_SIGNATURE_BYTE: return 1;
1074     case JVM_SIGNATURE_SHORT:
1075     case JVM_SIGNATURE_CHAR: return 2;
1076     case JVM_SIGNATURE_INT:
1077     case JVM_SIGNATURE_FLOAT: return 4;
1078     case JVM_SIGNATURE_LONG:
1079     case JVM_SIGNATURE_DOUBLE: return 8;
1080     default: ShouldNotReachHere(); /* to shut up compiler */ return 0;
1081   }
1082 }
1083 
1084 template<typename T, typename F> T bit_cast(F from) { // replace with the real thing when we can use c++20
1085   T to;
1086   static_assert(sizeof(to) == sizeof(from), "must be of the same size");
1087   memcpy(&to, &from, sizeof(to));
1088   return to;
1089 }
1090 
1091 // dump a jfloat
1092 void DumperSupport::dump_float(AbstractDumpWriter* writer, jfloat f) {
1093   if (g_isnan(f)) {
1094     writer->write_u4(0x7fc00000); // collapsing NaNs
1095   } else {
1096     writer->write_u4(bit_cast<u4>(f));
1097   }
1098 }
1099 
1100 // dump a jdouble
1101 void DumperSupport::dump_double(AbstractDumpWriter* writer, jdouble d) {
1102   if (g_isnan(d)) {
1103     writer->write_u8(0x7ff80000ull << 32); // collapsing NaNs
1104   } else {
1105     writer->write_u8(bit_cast<u8>(d));
1106   }
1107 }
1108 
1109 // dumps the raw value of the given field
1110 void DumperSupport::dump_field_value(AbstractDumpWriter* writer, char type, oop obj, int offset) {
1111   switch (type) {
1112     case JVM_SIGNATURE_CLASS :
1113     case JVM_SIGNATURE_ARRAY : {
1114       oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset);
1115       o = mask_dormant_archived_object(o, obj);
1116       assert(oopDesc::is_oop_or_null(o), "Expected an oop or nullptr at " PTR_FORMAT, p2i(o));
1117       writer->write_objectID(o);
1118       break;
1119     }
1120     case JVM_SIGNATURE_BYTE : {
1121       jbyte b = obj->byte_field(offset);
1122       writer->write_u1(b);
1123       break;
1124     }
1125     case JVM_SIGNATURE_CHAR : {
1126       jchar c = obj->char_field(offset);
1127       writer->write_u2(c);
1128       break;
1129     }
1130     case JVM_SIGNATURE_SHORT : {
1131       jshort s = obj->short_field(offset);
1132       writer->write_u2(s);
1133       break;
1134     }
1135     case JVM_SIGNATURE_FLOAT : {
1136       jfloat f = obj->float_field(offset);
1137       dump_float(writer, f);
1138       break;
1139     }
1140     case JVM_SIGNATURE_DOUBLE : {
1141       jdouble d = obj->double_field(offset);
1142       dump_double(writer, d);
1143       break;
1144     }
1145     case JVM_SIGNATURE_INT : {
1146       jint i = obj->int_field(offset);
1147       writer->write_u4(i);
1148       break;
1149     }
1150     case JVM_SIGNATURE_LONG : {
1151       jlong l = obj->long_field(offset);
1152       writer->write_u8(l);
1153       break;
1154     }
1155     case JVM_SIGNATURE_BOOLEAN : {
1156       jboolean b = obj->bool_field(offset);
1157       writer->write_u1(b);
1158       break;
1159     }
1160     default : {
1161       ShouldNotReachHere();
1162       break;
1163     }
1164   }
1165 }
1166 
1167 // returns the size of the instance of the given class
1168 u4 DumperSupport::instance_size(InstanceKlass* ik) {
1169   u4 size = 0;
1170   for (HierarchicalFieldStream<JavaFieldStream> fld(ik); !fld.done(); fld.next()) {
1171     if (!fld.access_flags().is_static()) {
1172       size += sig2size(fld.signature());
1173     }
1174   }
1175   return size;
1176 }
1177 
1178 u4 DumperSupport::get_static_fields_size(InstanceKlass* ik, u2& field_count) {
1179   field_count = 0;
1180   u4 size = 0;
1181 
1182   for (JavaFieldStream fldc(ik); !fldc.done(); fldc.next()) {
1183     if (fldc.access_flags().is_static()) {
1184       assert(!fldc.is_flat(), "static fields cannot be flat");
1185 
1186       field_count++;
1187       size += sig2size(fldc.signature());
1188     }
1189   }
1190 
1191   // Add in resolved_references which is referenced by the cpCache
1192   // The resolved_references is an array per InstanceKlass holding the
1193   // strings and other oops resolved from the constant pool.
1194   oop resolved_references = ik->constants()->resolved_references_or_null();
1195   if (resolved_references != nullptr) {
1196     field_count++;
1197     size += sizeof(address);
1198 
1199     // Add in the resolved_references of the used previous versions of the class
1200     // in the case of RedefineClasses
1201     InstanceKlass* prev = ik->previous_versions();
1202     while (prev != nullptr && prev->constants()->resolved_references_or_null() != nullptr) {
1203       field_count++;
1204       size += sizeof(address);
1205       prev = prev->previous_versions();
1206     }
1207   }
1208 
1209   // Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]
1210   // arrays.
1211   oop init_lock = ik->init_lock();
1212   if (init_lock != nullptr) {
1213     field_count++;
1214     size += sizeof(address);
1215   }
1216 
1217   // We write the value itself plus a name and a one byte type tag per field.
1218   return checked_cast<u4>(size + field_count * (sizeof(address) + 1));
1219 }
1220 
1221 // dumps static fields of the given class
1222 void DumperSupport::dump_static_fields(AbstractDumpWriter* writer, Klass* k) {
1223   InstanceKlass* ik = InstanceKlass::cast(k);
1224 
1225   // dump the field descriptors and raw values
1226   for (JavaFieldStream fld(ik); !fld.done(); fld.next()) {
1227     if (fld.access_flags().is_static()) {
1228       assert(!fld.is_flat(), "static fields cannot be flat");
1229 
1230       Symbol* sig = fld.signature();
1231 
1232       writer->write_symbolID(fld.name());   // name
1233       writer->write_u1(sig2tag(sig));       // type
1234 
1235       // value
1236       dump_field_value(writer, sig->char_at(0), ik->java_mirror(), fld.offset());
1237     }
1238   }
1239 
1240   // Add resolved_references for each class that has them
1241   oop resolved_references = ik->constants()->resolved_references_or_null();
1242   if (resolved_references != nullptr) {
1243     writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1244     writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1245     writer->write_objectID(resolved_references);
1246 
1247     // Also write any previous versions
1248     InstanceKlass* prev = ik->previous_versions();
1249     while (prev != nullptr && prev->constants()->resolved_references_or_null() != nullptr) {
1250       writer->write_symbolID(vmSymbols::resolved_references_name());  // name
1251       writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
1252       writer->write_objectID(prev->constants()->resolved_references());
1253       prev = prev->previous_versions();
1254     }
1255   }
1256 
1257   // Add init lock to the end if the class is not yet initialized
1258   oop init_lock = ik->init_lock();
1259   if (init_lock != nullptr) {
1260     writer->write_symbolID(vmSymbols::init_lock_name());         // name
1261     writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type
1262     writer->write_objectID(init_lock);
1263   }
1264 }
1265 
1266 // dump the raw values of the instance fields of the given object, fills flat_fields
1267 void DumperSupport:: dump_instance_fields(AbstractDumpWriter* writer, oop o, int offset,
1268                                           DumperClassCacheTableEntry* class_cache_entry, DumperFlatObjectList* flat_fields) {
1269   assert(class_cache_entry != nullptr, "Pre-condition: must be provided");
1270   for (int idx = 0; idx < class_cache_entry->field_count(); idx++) {
1271     const DumperClassCacheTableEntry::FieldDescriptor& field = class_cache_entry->field(idx);
1272     int field_offset = offset + field.offset();
1273     if (field.is_flat()) {
1274       // check for possible nulls
1275       if (field.is_flat_nullable()) {
1276         address payload = cast_from_oop<address>(o) + field_offset;
1277         if (field.inline_klass()->is_payload_marked_as_null(payload)) {
1278           writer->write_objectID(nullptr);
1279           continue;
1280         }
1281       }
1282       uintptr_t object_id = flat_fields->push(field_offset, field.inline_klass());
1283       writer->write_objectID(object_id);
1284     } else {
1285       dump_field_value(writer, field.sig_start(), o, field_offset);
1286     }
1287   }
1288 }
1289 
1290 // gets the count of the instance fields for a given class
1291 u2 DumperSupport::get_instance_fields_count(InstanceKlass* ik) {
1292   u2 field_count = 0;
1293 
1294   for (JavaFieldStream fldc(ik); !fldc.done(); fldc.next()) {
1295     if (!fldc.access_flags().is_static()) {
1296       field_count++;
1297     }
1298   }
1299 
1300   return field_count;
1301 }
1302 
1303 // dumps the definition of the instance fields for a given class
1304 void DumperSupport::dump_instance_field_descriptors(AbstractDumpWriter* writer, InstanceKlass* ik) {
1305   // dump the field descriptors
1306   for (JavaFieldStream fld(ik); !fld.done(); fld.next()) {
1307     if (!fld.access_flags().is_static()) {
1308       Symbol* sig = fld.signature();
1309 
1310       writer->write_symbolID(fld.name());   // name
1311       writer->write_u1(sig2tag(sig));       // type
1312     }
1313   }
1314 }
1315 
1316 // creates HPROF_GC_INSTANCE_DUMP record for the given object
1317 void DumperSupport::dump_instance(AbstractDumpWriter* writer, uintptr_t id, oop o, int offset, InstanceKlass* ik,
1318                                   DumperClassCacheTable* class_cache, DumperFlatObjectList* flat_fields) {
1319   DumperClassCacheTableEntry* cache_entry = class_cache->lookup_or_create(ik);
1320 
1321   u4 is = cache_entry->instance_size();
1322   u4 size = 1 + sizeof(address) + 4 + sizeof(address) + 4 + is;
1323 
1324   writer->start_sub_record(HPROF_GC_INSTANCE_DUMP, size);
1325   writer->write_objectID(id);
1326   writer->write_u4(STACK_TRACE_ID);
1327 
1328   // class ID
1329   writer->write_classID(ik);
1330 
1331   // number of bytes that follow
1332   writer->write_u4(is);
1333 
1334   // field values
1335   if (offset != 0) {
1336     // the object itself if flattened, so all fields are stored without headers
1337     InlineKlass* inline_klass = InlineKlass::cast(ik);
1338     offset -= inline_klass->payload_offset();
1339   }
1340 
1341   dump_instance_fields(writer, o, offset, cache_entry, flat_fields);
1342 
1343   writer->end_sub_record();
1344 }
1345 
1346 // creates HPROF_GC_CLASS_DUMP record for the given instance class
1347 void DumperSupport::dump_instance_class(AbstractDumpWriter* writer, InstanceKlass* ik) {
1348   // We can safepoint and do a heap dump at a point where we have a Klass,
1349   // but no java mirror class has been setup for it. So we need to check
1350   // that the class is at least loaded, to avoid crash from a null mirror.
1351   if (!ik->is_loaded()) {
1352     return;
1353   }
1354 
1355   u2 static_fields_count = 0;
1356   u4 static_size = get_static_fields_size(ik, static_fields_count);
1357   u2 instance_fields_count = get_instance_fields_count(ik);
1358   u4 instance_fields_size = instance_fields_count * (sizeof(address) + 1);
1359   u4 size = checked_cast<u4>(1 + sizeof(address) + 4 + 6 * sizeof(address) + 4 + 2 + 2 + static_size + 2 + instance_fields_size);
1360 
1361   writer->start_sub_record(HPROF_GC_CLASS_DUMP, size);
1362 
1363   // class ID
1364   writer->write_classID(ik);
1365   writer->write_u4(STACK_TRACE_ID);
1366 
1367   // super class ID
1368   InstanceKlass* super = ik->super();
1369   if (super == nullptr) {
1370     writer->write_objectID(oop(nullptr));
1371   } else {
1372     writer->write_classID(super);
1373   }
1374 
1375   writer->write_objectID(ik->class_loader());
1376   writer->write_objectID(ik->signers());
1377   writer->write_objectID(ik->protection_domain());
1378 
1379   // reserved
1380   writer->write_objectID(oop(nullptr));
1381   writer->write_objectID(oop(nullptr));
1382 
1383   // instance size
1384   writer->write_u4(DumperSupport::instance_size(ik));
1385 
1386   // size of constant pool - ignored by HAT 1.1
1387   writer->write_u2(0);
1388 
1389   // static fields
1390   writer->write_u2(static_fields_count);
1391   dump_static_fields(writer, ik);
1392 
1393   // description of instance fields
1394   writer->write_u2(instance_fields_count);
1395   dump_instance_field_descriptors(writer, ik);
1396 
1397   writer->end_sub_record();
1398 }
1399 
1400 // creates HPROF_GC_CLASS_DUMP record for the given array class
1401 void DumperSupport::dump_array_class(AbstractDumpWriter* writer, Klass* k) {
1402   InstanceKlass* ik = nullptr; // bottom class for object arrays, null for primitive type arrays
1403   if (k->is_objArray_klass()) {
1404     Klass *bk = ObjArrayKlass::cast(k)->bottom_klass();
1405     assert(bk != nullptr, "checking");
1406     if (bk->is_instance_klass()) {
1407       ik = InstanceKlass::cast(bk);
1408     }
1409   }
1410 
1411   u4 size = 1 + sizeof(address) + 4 + 6 * sizeof(address) + 4 + 2 + 2 + 2;
1412   writer->start_sub_record(HPROF_GC_CLASS_DUMP, size);
1413   writer->write_classID(k);
1414   writer->write_u4(STACK_TRACE_ID);
1415 
1416   // super class of array classes is java.lang.Object
1417   InstanceKlass* java_super = k->java_super();
1418   assert(java_super != nullptr, "checking");
1419   writer->write_classID(java_super);
1420 
1421   writer->write_objectID(ik == nullptr ? oop(nullptr) : ik->class_loader());
1422   writer->write_objectID(ik == nullptr ? oop(nullptr) : ik->signers());
1423   writer->write_objectID(ik == nullptr ? oop(nullptr) : ik->protection_domain());
1424 
1425   writer->write_objectID(oop(nullptr));    // reserved
1426   writer->write_objectID(oop(nullptr));
1427   writer->write_u4(0);             // instance size
1428   writer->write_u2(0);             // constant pool
1429   writer->write_u2(0);             // static fields
1430   writer->write_u2(0);             // instance fields
1431 
1432   writer->end_sub_record();
1433 
1434 }
1435 
1436 // Hprof uses an u4 as record length field,
1437 // which means we need to truncate arrays that are too long.
1438 int DumperSupport::calculate_array_max_length(AbstractDumpWriter* writer, arrayOop array, short header_size) {
1439   BasicType type = ArrayKlass::cast(array->klass())->element_type();
1440   assert((type >= T_BOOLEAN && type <= T_OBJECT) || type == T_FLAT_ELEMENT, "invalid array element type");
1441 
1442   int length = array->length();
1443 
1444   int type_size;
1445   if (type == T_OBJECT || type == T_FLAT_ELEMENT) {
1446     type_size = sizeof(address);
1447   } else {
1448     type_size = type2aelembytes(type);
1449   }
1450 
1451   size_t length_in_bytes = (size_t)length * type_size;
1452   uint max_bytes = max_juint - header_size;
1453 
1454   if (length_in_bytes > max_bytes) {
1455     length = max_bytes / type_size;
1456     length_in_bytes = (size_t)length * type_size;
1457 
1458     warning("cannot dump array of type %s[] with length %d; truncating to length %d",
1459             type2name_tab[type], array->length(), length);
1460   }
1461   return length;
1462 }
1463 
1464 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
1465 void DumperSupport::dump_object_array(AbstractDumpWriter* writer, objArrayOop array, DumperFlatObjectList* flat_elements) {
1466   // sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)
1467   short header_size = 1 + 2 * 4 + 2 * sizeof(address);
1468   int length = calculate_array_max_length(writer, array, header_size);
1469   u4 size = checked_cast<u4>(header_size + length * sizeof(address));
1470 
1471   writer->start_sub_record(HPROF_GC_OBJ_ARRAY_DUMP, size);
1472   writer->write_objectID(array);
1473   writer->write_u4(STACK_TRACE_ID);
1474   writer->write_u4(length);
1475 
1476   // array class ID
1477   writer->write_classID(array->klass());
1478 
1479   // [id]* elements
1480   if (array->is_flatArray()) {
1481     flatArrayOop farray = flatArrayOop(array);
1482     FlatArrayKlass* faklass = FlatArrayKlass::cast(farray->klass());
1483 
1484     InlineKlass* vk = faklass->element_klass();
1485     bool need_null_check = LayoutKindHelper::is_nullable_flat(faklass->layout_kind());
1486 
1487     for (int index = 0; index < length; index++) {
1488       address addr = (address)farray->value_at_addr(index, faklass->layout_helper());
1489       // check for null
1490       if (need_null_check) {
1491         if (vk->is_payload_marked_as_null(addr)) {
1492           writer->write_objectID(nullptr);
1493           continue;
1494         }
1495       }
1496       // offset in the array oop
1497       int offset = (int)(addr - cast_from_oop<address>(farray));
1498       uintptr_t object_id = flat_elements->push(offset, vk);
1499       writer->write_objectID(object_id);
1500     }
1501   } else {
1502     refArrayOop rarray = oop_cast<refArrayOop>(array);
1503     for (int index = 0; index < length; index++) {
1504       oop o = rarray->obj_at(index);
1505       o = mask_dormant_archived_object(o, array);
1506       writer->write_objectID(o);
1507     }
1508   }
1509 
1510   writer->end_sub_record();
1511 }
1512 
1513 #define WRITE_ARRAY(Array, Type, Size, Length) \
1514   for (int i = 0; i < Length; i++) { writer->write_##Size((Size)Array->Type##_at(i)); }
1515 
1516 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
1517 void DumperSupport::dump_prim_array(AbstractDumpWriter* writer, typeArrayOop array) {
1518   BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
1519   // 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)
1520   short header_size = 2 * 1 + 2 * 4 + sizeof(address);
1521 
1522   int length = calculate_array_max_length(writer, array, header_size);
1523   int type_size = type2aelembytes(type);
1524   u4 length_in_bytes = (u4)length * type_size;
1525   u4 size = header_size + length_in_bytes;
1526 
1527   writer->start_sub_record(HPROF_GC_PRIM_ARRAY_DUMP, size);
1528   writer->write_objectID(array);
1529   writer->write_u4(STACK_TRACE_ID);
1530   writer->write_u4(length);
1531   writer->write_u1(type2tag(type));
1532 
1533   // nothing to copy
1534   if (length == 0) {
1535     writer->end_sub_record();
1536     return;
1537   }
1538 
1539   // If the byte ordering is big endian then we can copy most types directly
1540 
1541   switch (type) {
1542     case T_INT : {
1543       if (Endian::is_Java_byte_ordering_different()) {
1544         WRITE_ARRAY(array, int, u4, length);
1545       } else {
1546         writer->write_raw(array->int_at_addr(0), length_in_bytes);
1547       }
1548       break;
1549     }
1550     case T_BYTE : {
1551       writer->write_raw(array->byte_at_addr(0), length_in_bytes);
1552       break;
1553     }
1554     case T_CHAR : {
1555       if (Endian::is_Java_byte_ordering_different()) {
1556         WRITE_ARRAY(array, char, u2, length);
1557       } else {
1558         writer->write_raw(array->char_at_addr(0), length_in_bytes);
1559       }
1560       break;
1561     }
1562     case T_SHORT : {
1563       if (Endian::is_Java_byte_ordering_different()) {
1564         WRITE_ARRAY(array, short, u2, length);
1565       } else {
1566         writer->write_raw(array->short_at_addr(0), length_in_bytes);
1567       }
1568       break;
1569     }
1570     case T_BOOLEAN : {
1571       if (Endian::is_Java_byte_ordering_different()) {
1572         WRITE_ARRAY(array, bool, u1, length);
1573       } else {
1574         writer->write_raw(array->bool_at_addr(0), length_in_bytes);
1575       }
1576       break;
1577     }
1578     case T_LONG : {
1579       if (Endian::is_Java_byte_ordering_different()) {
1580         WRITE_ARRAY(array, long, u8, length);
1581       } else {
1582         writer->write_raw(array->long_at_addr(0), length_in_bytes);
1583       }
1584       break;
1585     }
1586 
1587     // handle float/doubles in a special value to ensure than NaNs are
1588     // written correctly. TO DO: Check if we can avoid this on processors that
1589     // use IEEE 754.
1590 
1591     case T_FLOAT : {
1592       for (int i = 0; i < length; i++) {
1593         dump_float(writer, array->float_at(i));
1594       }
1595       break;
1596     }
1597     case T_DOUBLE : {
1598       for (int i = 0; i < length; i++) {
1599         dump_double(writer, array->double_at(i));
1600       }
1601       break;
1602     }
1603     default : ShouldNotReachHere();
1604   }
1605 
1606   writer->end_sub_record();
1607 }
1608 
1609 // create a HPROF_FRAME record of the given Method* and bci
1610 void DumperSupport::dump_stack_frame(AbstractDumpWriter* writer,
1611                                      int frame_serial_num,
1612                                      int class_serial_num,
1613                                      Method* m,
1614                                      int bci) {
1615   int line_number;
1616   if (m->is_native()) {
1617     line_number = -3;  // native frame
1618   } else {
1619     line_number = m->line_number_from_bci(bci);
1620   }
1621 
1622   write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
1623   writer->write_id(frame_serial_num);               // frame serial number
1624   writer->write_symbolID(m->name());                // method's name
1625   writer->write_symbolID(m->signature());           // method's signature
1626 
1627   assert(m->method_holder()->is_instance_klass(), "not InstanceKlass");
1628   writer->write_symbolID(m->method_holder()->source_file_name());  // source file name
1629   writer->write_u4(class_serial_num);               // class serial number
1630   writer->write_u4((u4) line_number);               // line number
1631 }
1632 
1633 
1634 // Support class used to generate HPROF_UTF8 records from the entries in the
1635 // SymbolTable.
1636 
1637 class SymbolTableDumper : public SymbolClosure {
1638  private:
1639   AbstractDumpWriter* _writer;
1640   AbstractDumpWriter* writer() const                { return _writer; }
1641  public:
1642   SymbolTableDumper(AbstractDumpWriter* writer)     { _writer = writer; }
1643   void do_symbol(Symbol** p);
1644 };
1645 
1646 void SymbolTableDumper::do_symbol(Symbol** p) {
1647   ResourceMark rm;
1648   Symbol* sym = *p;
1649   int len = sym->utf8_length();
1650   if (len > 0) {
1651     char* s = sym->as_utf8();
1652     DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
1653     writer()->write_symbolID(sym);
1654     writer()->write_raw(s, len);
1655   }
1656 }
1657 
1658 // Support class used to generate HPROF_GC_CLASS_DUMP records
1659 
1660 class ClassDumper : public KlassClosure {
1661  private:
1662   AbstractDumpWriter* _writer;
1663   AbstractDumpWriter* writer() const { return _writer; }
1664 
1665  public:
1666   ClassDumper(AbstractDumpWriter* writer) : _writer(writer) {}
1667 
1668   void do_klass(Klass* k) {
1669     if (DumperSupport::filter_out_klass(k)) {
1670       return;
1671     }
1672     if (k->is_instance_klass()) {
1673       DumperSupport::dump_instance_class(writer(), InstanceKlass::cast(k));
1674     } else {
1675       DumperSupport::dump_array_class(writer(), k);
1676     }
1677   }
1678 };
1679 
1680 // Support class used to generate HPROF_LOAD_CLASS records
1681 
1682 class LoadedClassDumper : public LockedClassesDo {
1683  private:
1684   AbstractDumpWriter* _writer;
1685   GrowableArray<Klass*>* _klass_map;
1686   u4 _class_serial_num;
1687   AbstractDumpWriter* writer() const { return _writer; }
1688   void add_class_serial_number(Klass* k, int serial_num) {
1689     _klass_map->at_put_grow(serial_num, k);
1690   }
1691  public:
1692   LoadedClassDumper(AbstractDumpWriter* writer, GrowableArray<Klass*>* klass_map)
1693     : _writer(writer), _klass_map(klass_map), _class_serial_num(0) {}
1694 
1695   void do_klass(Klass* k) {
1696     if (DumperSupport::filter_out_klass(k)) {
1697       return;
1698     }
1699     // len of HPROF_LOAD_CLASS record
1700     u4 remaining = 2 * oopSize + 2 * sizeof(u4);
1701     DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
1702     // class serial number is just a number
1703     writer()->write_u4(++_class_serial_num);
1704     // class ID
1705     writer()->write_classID(k);
1706     // add the Klass* and class serial number pair
1707     add_class_serial_number(k, _class_serial_num);
1708     writer()->write_u4(STACK_TRACE_ID);
1709     // class name ID
1710     Symbol* name = k->name();
1711     writer()->write_symbolID(name);
1712   }
1713 };
1714 
1715 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records
1716 
1717 class JNILocalsDumper : public OopClosure {
1718  private:
1719   AbstractDumpWriter* _writer;
1720   u4 _thread_serial_num;
1721   int _frame_num;
1722   AbstractDumpWriter* writer() const                { return _writer; }
1723  public:
1724   JNILocalsDumper(AbstractDumpWriter* writer, u4 thread_serial_num) {
1725     _writer = writer;
1726     _thread_serial_num = thread_serial_num;
1727     _frame_num = -1;  // default - empty stack
1728   }
1729   void set_frame_number(int n) { _frame_num = n; }
1730   void do_oop(oop* obj_p);
1731   void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
1732 };
1733 
1734 void JNILocalsDumper::do_oop(oop* obj_p) {
1735   // ignore null handles
1736   oop o = *obj_p;
1737   if (o != nullptr) {
1738     u4 size = 1 + sizeof(address) + 4 + 4;
1739     writer()->start_sub_record(HPROF_GC_ROOT_JNI_LOCAL, size);
1740     writer()->write_objectID(o);
1741     writer()->write_u4(_thread_serial_num);
1742     writer()->write_u4((u4)_frame_num);
1743     writer()->end_sub_record();
1744   }
1745 }
1746 
1747 
1748 // Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records
1749 
1750 class JNIGlobalsDumper : public OopClosure {
1751  private:
1752   AbstractDumpWriter* _writer;
1753   AbstractDumpWriter* writer() const                { return _writer; }
1754 
1755  public:
1756   JNIGlobalsDumper(AbstractDumpWriter* writer) {
1757     _writer = writer;
1758   }
1759   void do_oop(oop* obj_p);
1760   void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
1761 };
1762 
1763 void JNIGlobalsDumper::do_oop(oop* obj_p) {
1764   oop o = NativeAccess<AS_NO_KEEPALIVE>::oop_load(obj_p);
1765 
1766   // ignore these
1767   if (o == nullptr) return;
1768   // we ignore global ref to symbols and other internal objects
1769   if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {
1770     u4 size = 1 + 2 * sizeof(address);
1771     writer()->start_sub_record(HPROF_GC_ROOT_JNI_GLOBAL, size);
1772     writer()->write_objectID(o);
1773     writer()->write_rootID(obj_p);      // global ref ID
1774     writer()->end_sub_record();
1775   }
1776 };
1777 
1778 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records
1779 
1780 class StickyClassDumper : public KlassClosure {
1781  private:
1782   AbstractDumpWriter* _writer;
1783   AbstractDumpWriter* writer() const                { return _writer; }
1784  public:
1785   StickyClassDumper(AbstractDumpWriter* writer) {
1786     _writer = writer;
1787   }
1788   void do_klass(Klass* k) {
1789     if (k->is_instance_klass()) {
1790       InstanceKlass* ik = InstanceKlass::cast(k);
1791       u4 size = 1 + sizeof(address);
1792       writer()->start_sub_record(HPROF_GC_ROOT_STICKY_CLASS, size);
1793       writer()->write_classID(ik);
1794       writer()->end_sub_record();
1795     }
1796   }
1797 };
1798 
1799 // Support class used to generate HPROF_GC_ROOT_JAVA_FRAME records.
1800 
1801 class JavaStackRefDumper : public StackObj {
1802 private:
1803   AbstractDumpWriter* _writer;
1804   u4 _thread_serial_num;
1805   int _frame_num;
1806   AbstractDumpWriter* writer() const { return _writer; }
1807 public:
1808   JavaStackRefDumper(AbstractDumpWriter* writer, u4 thread_serial_num)
1809       : _writer(writer), _thread_serial_num(thread_serial_num), _frame_num(-1) // default - empty stack
1810   {
1811   }
1812 
1813   void set_frame_number(int n) { _frame_num = n; }
1814 
1815   void dump_java_stack_refs(StackValueCollection* values);
1816 };
1817 
1818 void JavaStackRefDumper::dump_java_stack_refs(StackValueCollection* values) {
1819   for (int index = 0; index < values->size(); index++) {
1820     if (values->at(index)->type() == T_OBJECT) {
1821       oop o = values->obj_at(index)();
1822       if (o != nullptr) {
1823         u4 size = 1 + sizeof(address) + 4 + 4;
1824         writer()->start_sub_record(HPROF_GC_ROOT_JAVA_FRAME, size);
1825         writer()->write_objectID(o);
1826         writer()->write_u4(_thread_serial_num);
1827         writer()->write_u4((u4)_frame_num);
1828         writer()->end_sub_record();
1829       }
1830     }
1831   }
1832 }
1833 
1834 // Class to collect, store and dump thread-related data:
1835 // - HPROF_TRACE and HPROF_FRAME records;
1836 // - HPROF_GC_ROOT_THREAD_OBJ/HPROF_GC_ROOT_JAVA_FRAME/HPROF_GC_ROOT_JNI_LOCAL subrecords.
1837 class ThreadDumper : public CHeapObj<mtInternal> {
1838 public:
1839   enum class ThreadType { Platform, MountedVirtual, UnmountedVirtual };
1840 
1841 private:
1842   ThreadType _thread_type;
1843   JavaThread* _java_thread;
1844   oop _thread_oop;
1845 
1846   GrowableArray<StackFrameInfo*>* _frames;
1847   // non-null if the thread is OOM thread
1848   Method* _oome_constructor;
1849   int _thread_serial_num;
1850   int _start_frame_serial_num;
1851 
1852   vframe* get_top_frame() const;
1853 
1854 public:
1855   static bool should_dump_pthread(JavaThread* thread) {
1856     return thread->threadObj() != nullptr && !thread->is_exiting() && !thread->is_hidden_from_external_view();
1857   }
1858 
1859   static bool should_dump_vthread(oop vt) {
1860     return java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::NEW
1861         && java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::TERMINATED;
1862   }
1863 
1864   static bool is_vthread_mounted(oop vt) {
1865     // The code should be consistent with the "mounted virtual thread" case
1866     // (VM_HeapDumper::dump_stack_traces(), ThreadDumper::get_top_frame()).
1867     // I.e. virtual thread is mounted if its carrierThread is not null
1868     // and is_vthread_mounted() for the carrier thread returns true.
1869     oop carrier_thread = java_lang_VirtualThread::carrier_thread(vt);
1870     if (carrier_thread == nullptr) {
1871       return false;
1872     }
1873     JavaThread* java_thread = java_lang_Thread::thread(carrier_thread);
1874     return java_thread->is_vthread_mounted();
1875   }
1876 
1877   ThreadDumper(ThreadType thread_type, JavaThread* java_thread, oop thread_oop);
1878   ~ThreadDumper() {
1879     for (int index = 0; index < _frames->length(); index++) {
1880       delete _frames->at(index);
1881     }
1882     delete _frames;
1883   }
1884 
1885   // affects frame_count
1886   void add_oom_frame(Method* oome_constructor) {
1887     assert(_start_frame_serial_num == 0, "add_oom_frame cannot be called after init_serial_nums");
1888     _oome_constructor = oome_constructor;
1889   }
1890 
1891   void init_serial_nums(volatile int* thread_counter, volatile int* frame_counter) {
1892     assert(_start_frame_serial_num == 0, "already initialized");
1893     _thread_serial_num = AtomicAccess::fetch_then_add(thread_counter, 1);
1894     _start_frame_serial_num = AtomicAccess::fetch_then_add(frame_counter, frame_count());
1895   }
1896 
1897   bool oom_thread() const {
1898     return _oome_constructor != nullptr;
1899   }
1900 
1901   int frame_count() const {
1902     return _frames->length() + (oom_thread() ? 1 : 0);
1903   }
1904 
1905   u4 thread_serial_num() const {
1906     return (u4)_thread_serial_num;
1907   }
1908 
1909   u4 stack_trace_serial_num() const {
1910     return (u4)(_thread_serial_num + STACK_TRACE_ID);
1911   }
1912 
1913   // writes HPROF_TRACE and HPROF_FRAME records
1914   // returns number of dumped frames
1915   void dump_stack_traces(AbstractDumpWriter* writer, GrowableArray<Klass*>* klass_map);
1916 
1917   // writes HPROF_GC_ROOT_THREAD_OBJ subrecord
1918   void dump_thread_obj(AbstractDumpWriter* writer);
1919 
1920   // Walk the stack of the thread.
1921   // Dumps a HPROF_GC_ROOT_JAVA_FRAME subrecord for each local
1922   // Dumps a HPROF_GC_ROOT_JNI_LOCAL subrecord for each JNI local
1923   void dump_stack_refs(AbstractDumpWriter* writer);
1924 
1925 };
1926 
1927 ThreadDumper::ThreadDumper(ThreadType thread_type, JavaThread* java_thread, oop thread_oop)
1928     : _thread_type(thread_type), _java_thread(java_thread), _thread_oop(thread_oop),
1929       _oome_constructor(nullptr),
1930       _thread_serial_num(0), _start_frame_serial_num(0)
1931 {
1932   // sanity checks
1933   if (_thread_type == ThreadType::UnmountedVirtual) {
1934     assert(_java_thread == nullptr, "sanity");
1935     assert(_thread_oop != nullptr, "sanity");
1936   } else {
1937     assert(_java_thread != nullptr, "sanity");
1938     assert(_thread_oop != nullptr, "sanity");
1939   }
1940 
1941   _frames = new (mtServiceability) GrowableArray<StackFrameInfo*>(10, mtServiceability);
1942   bool stop_at_vthread_entry = _thread_type == ThreadType::MountedVirtual;
1943 
1944   // vframes are resource allocated
1945   Thread* current_thread = Thread::current();
1946   ResourceMark rm(current_thread);
1947   HandleMark hm(current_thread);
1948 
1949   for (vframe* vf = get_top_frame(); vf != nullptr; vf = vf->sender()) {
1950     if (stop_at_vthread_entry && vf->is_vthread_entry()) {
1951       break;
1952     }
1953     if (vf->is_java_frame()) {
1954       javaVFrame* jvf = javaVFrame::cast(vf);
1955       _frames->append(new StackFrameInfo(jvf, false));
1956     } else {
1957       // ignore non-Java frames
1958     }
1959   }
1960 }
1961 
1962 void ThreadDumper::dump_stack_traces(AbstractDumpWriter* writer, GrowableArray<Klass*>* klass_map) {
1963   assert(_thread_serial_num != 0 && _start_frame_serial_num != 0, "serial_nums are not initialized");
1964 
1965   // write HPROF_FRAME records for this thread's stack trace
1966   int depth = _frames->length();
1967   int frame_serial_num = _start_frame_serial_num;
1968 
1969   if (oom_thread()) {
1970     // OOM thread
1971     // write fake frame that makes it look like the thread, which caused OOME,
1972     // is in the OutOfMemoryError zero-parameter constructor
1973     int oome_serial_num = klass_map->find(_oome_constructor->method_holder());
1974     // the class serial number starts from 1
1975     assert(oome_serial_num > 0, "OutOfMemoryError class not found");
1976     DumperSupport::dump_stack_frame(writer, ++frame_serial_num, oome_serial_num, _oome_constructor, 0);
1977     depth++;
1978   }
1979 
1980   for (int j = 0; j < _frames->length(); j++) {
1981     StackFrameInfo* frame = _frames->at(j);
1982     Method* m = frame->method();
1983     int class_serial_num = klass_map->find(m->method_holder());
1984     // the class serial number starts from 1
1985     assert(class_serial_num > 0, "class not found");
1986     DumperSupport::dump_stack_frame(writer, ++frame_serial_num, class_serial_num, m, frame->bci());
1987   }
1988 
1989   // write HPROF_TRACE record for the thread
1990   DumperSupport::write_header(writer, HPROF_TRACE, checked_cast<u4>(3 * sizeof(u4) + depth * oopSize));
1991   writer->write_u4(stack_trace_serial_num());   // stack trace serial number
1992   writer->write_u4(thread_serial_num());        // thread serial number
1993   writer->write_u4((u4)depth);                  // frame count (including oom frame)
1994   for (int j = 1; j <= depth; j++) {
1995     writer->write_id(_start_frame_serial_num + j);
1996   }
1997 }
1998 
1999 void ThreadDumper::dump_thread_obj(AbstractDumpWriter * writer) {
2000   assert(_thread_serial_num != 0 && _start_frame_serial_num != 0, "serial_num is not initialized");
2001 
2002   u4 size = 1 + sizeof(address) + 4 + 4;
2003   writer->start_sub_record(HPROF_GC_ROOT_THREAD_OBJ, size);
2004   writer->write_objectID(_thread_oop);
2005   writer->write_u4(thread_serial_num());      // thread serial number
2006   writer->write_u4(stack_trace_serial_num()); // stack trace serial number
2007   writer->end_sub_record();
2008 }
2009 
2010 void ThreadDumper::dump_stack_refs(AbstractDumpWriter * writer) {
2011   assert(_thread_serial_num != 0 && _start_frame_serial_num != 0, "serial_num is not initialized");
2012 
2013   JNILocalsDumper blk(writer, thread_serial_num());
2014   if (_thread_type == ThreadType::Platform) {
2015     if (!_java_thread->has_last_Java_frame()) {
2016       // no last java frame but there may be JNI locals
2017       _java_thread->active_handles()->oops_do(&blk);
2018       return;
2019     }
2020   }
2021 
2022   JavaStackRefDumper java_ref_dumper(writer, thread_serial_num());
2023 
2024   // vframes are resource allocated
2025   Thread* current_thread = Thread::current();
2026   ResourceMark rm(current_thread);
2027   HandleMark hm(current_thread);
2028 
2029   bool stopAtVthreadEntry = _thread_type == ThreadType::MountedVirtual;
2030   frame* last_entry_frame = nullptr;
2031   bool is_top_frame = true;
2032   int depth = 0;
2033   if (oom_thread()) {
2034     depth++;
2035   }
2036 
2037   for (vframe* vf = get_top_frame(); vf != nullptr; vf = vf->sender()) {
2038     if (stopAtVthreadEntry && vf->is_vthread_entry()) {
2039       break;
2040     }
2041 
2042     if (vf->is_java_frame()) {
2043       javaVFrame* jvf = javaVFrame::cast(vf);
2044       if (!(jvf->method()->is_native())) {
2045         java_ref_dumper.set_frame_number(depth);
2046         java_ref_dumper.dump_java_stack_refs(jvf->locals());
2047         java_ref_dumper.dump_java_stack_refs(jvf->expressions());
2048       } else {
2049         // native frame
2050         blk.set_frame_number(depth);
2051         if (is_top_frame) {
2052           // JNI locals for the top frame if mounted
2053           assert(_java_thread != nullptr || jvf->method()->is_synchronized()
2054                  || jvf->method()->is_object_wait0(), "impossible for unmounted vthread");
2055           if (_java_thread != nullptr) {
2056             _java_thread->active_handles()->oops_do(&blk);
2057           }
2058         } else {
2059           if (last_entry_frame != nullptr) {
2060             // JNI locals for the entry frame
2061             assert(last_entry_frame->is_entry_frame(), "checking");
2062             last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);
2063           }
2064         }
2065       }
2066       last_entry_frame = nullptr;
2067       // increment only for Java frames
2068       depth++;
2069     } else {
2070       // externalVFrame - for an entry frame then we report the JNI locals
2071       // when we find the corresponding javaVFrame
2072       frame* fr = vf->frame_pointer();
2073       assert(fr != nullptr, "sanity check");
2074       if (fr->is_entry_frame()) {
2075         last_entry_frame = fr;
2076       }
2077     }
2078   is_top_frame = false;
2079   }
2080   assert(depth == frame_count(), "total number of Java frames not matched");
2081 }
2082 
2083 vframe* ThreadDumper::get_top_frame() const {
2084   if (_thread_type == ThreadType::UnmountedVirtual) {
2085     ContinuationWrapper cont(java_lang_VirtualThread::continuation(_thread_oop));
2086     if (cont.is_empty()) {
2087       return nullptr;
2088     }
2089     assert(!cont.is_mounted(), "sanity check");
2090     stackChunkOop chunk = cont.last_nonempty_chunk();
2091     if (chunk == nullptr || chunk->is_empty()) {
2092       return nullptr;
2093     }
2094 
2095     RegisterMap reg_map(cont.continuation(), RegisterMap::UpdateMap::include);
2096     frame fr = chunk->top_frame(&reg_map);
2097     vframe* vf = vframe::new_vframe(&fr, &reg_map, nullptr); // don't need JavaThread
2098     return vf;
2099   }
2100 
2101   RegisterMap reg_map(_java_thread,
2102       RegisterMap::UpdateMap::include,
2103       RegisterMap::ProcessFrames::include,
2104       RegisterMap::WalkContinuation::skip);
2105   switch (_thread_type) {
2106   case ThreadType::Platform:
2107     if (!_java_thread->has_last_Java_frame()) {
2108       return nullptr;
2109     }
2110     return _java_thread->is_vthread_mounted()
2111         ? _java_thread->carrier_last_java_vframe(&reg_map)
2112         : _java_thread->platform_thread_last_java_vframe(&reg_map);
2113 
2114   case ThreadType::MountedVirtual:
2115     return _java_thread->last_java_vframe(&reg_map);
2116 
2117   default: // make compilers happy
2118       break;
2119   }
2120   ShouldNotReachHere();
2121   return nullptr;
2122 }
2123 
2124 class FlatObjectDumper: public FlatObjectIdProvider {
2125 private:
2126   volatile uintptr_t _id_counter;
2127 public:
2128   FlatObjectDumper(): _id_counter(0) {
2129   }
2130 
2131   void dump_flat_objects(AbstractDumpWriter* writer, oop holder,
2132                          DumperClassCacheTable* class_cache, DumperFlatObjectList* flat_objects);
2133 
2134   // FlatObjectIdProvider implementation
2135   virtual uintptr_t get_id() override {
2136     // need to protect against overflow, so use instead of fetch_then_add
2137     const uintptr_t max_value = (uintptr_t)-1;
2138     uintptr_t old_value = AtomicAccess::load(&_id_counter);
2139     while (old_value != max_value) {
2140       uintptr_t new_value = old_value + 1;
2141       // to avoid conflicts with oop addresses skip aligned values
2142       if ((new_value & MinObjAlignmentInBytesMask) == 0) {
2143         new_value++;
2144       }
2145       uintptr_t value = AtomicAccess::cmpxchg(&_id_counter, old_value, new_value);
2146       if (value == old_value) {
2147         // success
2148         return new_value;
2149       }
2150       old_value = value;
2151     }
2152     // if we are here, maximum id value is reached
2153     return max_value;
2154   }
2155 
2156 };
2157 
2158 void FlatObjectDumper::dump_flat_objects(AbstractDumpWriter* writer, oop holder,
2159                                          DumperClassCacheTable* class_cache, DumperFlatObjectList* flat_objects) {
2160   // DumperSupport::dump_instance can add entries to flat_objects
2161   while (!flat_objects->is_empty()) {
2162     DumperFlatObject* obj = flat_objects->pop();
2163     DumperSupport::dump_instance(writer, obj->object_id(), holder, obj->offset(), obj->inline_klass(), class_cache, flat_objects);
2164     delete obj;
2165   }
2166 }
2167 
2168 // Callback to dump thread-related data for unmounted virtual threads;
2169 // implemented by VM_HeapDumper.
2170 class UnmountedVThreadDumper {
2171 public:
2172   virtual void dump_vthread(oop vt, AbstractDumpWriter* segment_writer) = 0;
2173 };
2174 
2175 
2176 // Support class used when iterating over the heap.
2177 class HeapObjectDumper : public ObjectClosure {
2178  private:
2179   AbstractDumpWriter* _writer;
2180   AbstractDumpWriter* writer()                  { return _writer; }
2181   UnmountedVThreadDumper* _vthread_dumper;
2182   FlatObjectDumper* _flat_dumper;
2183 
2184   DumperClassCacheTable _class_cache;
2185 
2186  public:
2187   HeapObjectDumper(AbstractDumpWriter* writer, UnmountedVThreadDumper* vthread_dumper, FlatObjectDumper* flat_dumper)
2188     : _writer(writer), _vthread_dumper(vthread_dumper), _flat_dumper(flat_dumper) {}
2189 
2190   // called for each object in the heap
2191   void do_object(oop o);
2192 };
2193 
2194 void HeapObjectDumper::do_object(oop o) {
2195   // skip classes as these emitted as HPROF_GC_CLASS_DUMP records
2196   if (o->klass() == vmClasses::Class_klass()) {
2197     if (!java_lang_Class::is_primitive(o)) {
2198       return;
2199     }
2200   }
2201 
2202   if (DumperSupport::mask_dormant_archived_object(o, nullptr) == nullptr) {
2203     return;
2204   }
2205 
2206   if (o->is_instance()) {
2207     DumperFlatObjectList flat_fields(_flat_dumper);
2208     // create a HPROF_GC_INSTANCE record for each object
2209     DumperSupport::dump_instance(writer(),
2210                                  cast_from_oop<uintptr_t>(o), // object_id is the address
2211                                  o, 0,                        // for heap instance holder is oop, offset is 0
2212                                  InstanceKlass::cast(o->klass()),
2213                                  &_class_cache, &flat_fields);
2214 
2215     // if there are flattened fields, dump them
2216     if (!flat_fields.is_empty()) {
2217       _flat_dumper->dump_flat_objects(writer(), o, &_class_cache, &flat_fields);
2218     }
2219 
2220     // If we encounter an unmounted virtual thread it needs to be dumped explicitly
2221     // (mounted virtual threads are dumped with their carriers).
2222     if (java_lang_VirtualThread::is_instance(o)
2223         && ThreadDumper::should_dump_vthread(o) && !ThreadDumper::is_vthread_mounted(o)) {
2224       _vthread_dumper->dump_vthread(o, writer());
2225     }
2226   } else if (o->is_objArray()) {
2227     DumperFlatObjectList flat_elements(_flat_dumper);
2228     // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
2229     DumperSupport::dump_object_array(writer(), objArrayOop(o), &flat_elements);
2230     // if this is flat array, dump its elements
2231     if (!flat_elements.is_empty()) {
2232       _flat_dumper->dump_flat_objects(writer(), o, &_class_cache, &flat_elements);
2233     }
2234   } else if (o->is_typeArray()) {
2235     // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
2236     DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
2237   }
2238 }
2239 
2240 // The dumper controller for parallel heap dump
2241 class DumperController : public CHeapObj<mtInternal> {
2242  private:
2243    Monitor* _lock;
2244    Mutex* _global_writer_lock;
2245 
2246    const uint   _dumper_number;
2247    uint   _complete_number;
2248 
2249    bool   _started; // VM dumper started and acquired global writer lock
2250 
2251  public:
2252    DumperController(uint number) :
2253      // _lock and _global_writer_lock are used for synchronization between GC worker threads inside safepoint,
2254      // so we lock with _no_safepoint_check_flag.
2255      // signal_start() acquires _lock when global writer is locked,
2256      // its rank must be less than _global_writer_lock rank.
2257      _lock(new (std::nothrow) PaddedMonitor(Mutex::nosafepoint - 1, "DumperController_lock")),
2258      _global_writer_lock(new (std::nothrow) Mutex(Mutex::nosafepoint, "DumpWriter_lock")),
2259      _dumper_number(number),
2260      _complete_number(0),
2261      _started(false)
2262    {}
2263 
2264    ~DumperController() {
2265      delete _lock;
2266      delete _global_writer_lock;
2267    }
2268 
2269    // parallel (non VM) dumpers must wait until VM dumper acquires global writer lock
2270    void wait_for_start_signal() {
2271      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
2272      while (_started == false) {
2273        ml.wait();
2274      }
2275    }
2276 
2277    void signal_start() {
2278      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
2279      _started = true;
2280      ml.notify_all();
2281    }
2282 
2283    void lock_global_writer() {
2284      _global_writer_lock->lock_without_safepoint_check();
2285    }
2286 
2287    void unlock_global_writer() {
2288      _global_writer_lock->unlock();
2289    }
2290 
2291    void dumper_complete(DumpWriter* local_writer, DumpWriter* global_writer) {
2292      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
2293      _complete_number++;
2294      // propagate local error to global if any
2295      if (local_writer->has_error()) {
2296        global_writer->set_error(local_writer->error());
2297      }
2298      ml.notify();
2299    }
2300 
2301    void wait_all_dumpers_complete() {
2302      MonitorLocker ml(_lock, Mutex::_no_safepoint_check_flag);
2303      while (_complete_number != _dumper_number) {
2304         ml.wait();
2305      }
2306    }
2307 };
2308 
2309 // DumpMerger merges separate dump files into a complete one
2310 class DumpMerger : public StackObj {
2311 private:
2312   DumpWriter* _writer;
2313   const char* _path;
2314   bool _has_error;
2315   int _dump_seq;
2316 
2317 private:
2318   void merge_file(const char* path);
2319   void merge_done();
2320   void set_error(const char* msg);
2321 
2322 public:
2323   DumpMerger(const char* path, DumpWriter* writer, int dump_seq) :
2324     _writer(writer),
2325     _path(path),
2326     _has_error(_writer->has_error()),
2327     _dump_seq(dump_seq) {}
2328 
2329   void do_merge();
2330 
2331   // returns path for the parallel DumpWriter (resource allocated)
2332   static char* get_writer_path(const char* base_path, int seq);
2333 
2334 };
2335 
2336 char* DumpMerger::get_writer_path(const char* base_path, int seq) {
2337   // approximate required buffer size
2338   size_t buf_size = strlen(base_path)
2339                     + 2                 // ".p"
2340                     + 10                // number (that's enough for 2^32 parallel dumpers)
2341                     + 1;                // '\0'
2342 
2343   char* path = NEW_RESOURCE_ARRAY(char, buf_size);
2344   memset(path, 0, buf_size);
2345 
2346   os::snprintf_checked(path, buf_size, "%s.p%d", base_path, seq);
2347 
2348   return path;
2349 }
2350 
2351 
2352 void DumpMerger::merge_done() {
2353   // Writes the HPROF_HEAP_DUMP_END record.
2354   if (!_has_error) {
2355     DumperSupport::end_of_dump(_writer);
2356     _writer->flush();
2357   }
2358   _dump_seq = 0; //reset
2359 }
2360 
2361 void DumpMerger::set_error(const char* msg) {
2362   assert(msg != nullptr, "sanity check");
2363   log_error(heapdump)("%s (file: %s)", msg, _path);
2364   _writer->set_error(msg);
2365   _has_error = true;
2366 }
2367 
2368 #ifdef LINUX
2369 // Merge segmented heap files via sendfile, it's more efficient than the
2370 // read+write combination, which would require transferring data to and from
2371 // user space.
2372 void DumpMerger::merge_file(const char* path) {
2373   TraceTime timer("Merge segmented heap file directly", TRACETIME_LOG(Info, heapdump));
2374 
2375   int segment_fd = os::open(path, O_RDONLY, 0);
2376   if (segment_fd == -1) {
2377     set_error("Can not open segmented heap file during merging");
2378     return;
2379   }
2380 
2381   struct stat st;
2382   if (os::stat(path, &st) != 0) {
2383     ::close(segment_fd);
2384     set_error("Can not get segmented heap file size during merging");
2385     return;
2386   }
2387 
2388   // A successful call to sendfile may write fewer bytes than requested; the
2389   // caller should be prepared to retry the call if there were unsent bytes.
2390   jlong offset = 0;
2391   while (offset < st.st_size) {
2392     int ret = os::Linux::sendfile(_writer->get_fd(), segment_fd, &offset, st.st_size);
2393     if (ret == -1) {
2394       ::close(segment_fd);
2395       set_error("Failed to merge segmented heap file");
2396       return;
2397     }
2398   }
2399 
2400   // As sendfile variant does not call the write method of the global writer,
2401   // bytes_written is also incorrect for this variant, we need to explicitly
2402   // accumulate bytes_written for the global writer in this case
2403   julong accum = _writer->bytes_written() + st.st_size;
2404   _writer->set_bytes_written(accum);
2405   ::close(segment_fd);
2406 }
2407 #else
2408 // Generic implementation using read+write
2409 void DumpMerger::merge_file(const char* path) {
2410   TraceTime timer("Merge segmented heap file", TRACETIME_LOG(Info, heapdump));
2411 
2412   fileStream segment_fs(path, "rb");
2413   if (!segment_fs.is_open()) {
2414     set_error("Can not open segmented heap file during merging");
2415     return;
2416   }
2417 
2418   jlong total = 0;
2419   size_t cnt = 0;
2420 
2421   // Use _writer buffer for reading.
2422   while ((cnt = segment_fs.read(_writer->buffer(), 1, _writer->buffer_size())) != 0) {
2423     _writer->set_position(cnt);
2424     _writer->flush();
2425     total += cnt;
2426   }
2427 
2428   if (segment_fs.fileSize() != total) {
2429     set_error("Merged heap dump is incomplete");
2430   }
2431 }
2432 #endif
2433 
2434 void DumpMerger::do_merge() {
2435   TraceTime timer("Merge heap files complete", TRACETIME_LOG(Info, heapdump));
2436 
2437   // Since contents in segmented heap file were already zipped, we don't need to zip
2438   // them again during merging.
2439   AbstractCompressor* saved_compressor = _writer->compressor();
2440   _writer->set_compressor(nullptr);
2441 
2442   // Merge the content of the remaining files into base file. Regardless of whether
2443   // the merge process is successful or not, these segmented files will be deleted.
2444   for (int i = 0; i < _dump_seq; i++) {
2445     ResourceMark rm;
2446     const char* path = get_writer_path(_path, i);
2447     if (!_has_error) {
2448       merge_file(path);
2449     }
2450     // Delete selected segmented heap file nevertheless
2451     if (remove(path) != 0) {
2452       log_info(heapdump)("Removal of segment file (%d) failed (%d)", i, errno);
2453     }
2454   }
2455 
2456   // restore compressor for further use
2457   _writer->set_compressor(saved_compressor);
2458   merge_done();
2459 }
2460 
2461 // The VM operation that performs the heap dump
2462 class VM_HeapDumper : public VM_GC_Operation, public WorkerTask, public UnmountedVThreadDumper {
2463  private:
2464   DumpWriter*             _writer;
2465   JavaThread*             _oome_thread;
2466   Method*                 _oome_constructor;
2467   bool                    _gc_before_heap_dump;
2468   GrowableArray<Klass*>*  _klass_map;
2469 
2470   ThreadDumper**          _thread_dumpers; // platform, carrier and mounted virtual threads
2471   int                     _thread_dumpers_count;
2472   volatile int            _thread_serial_num;
2473   volatile int            _frame_serial_num;
2474 
2475   volatile int            _dump_seq;
2476   // parallel heap dump support
2477   uint                    _num_dumper_threads;
2478   DumperController*       _dumper_controller;
2479   ParallelObjectIterator* _poi;
2480 
2481   // flat value object support
2482   FlatObjectDumper        _flat_dumper;
2483 
2484   // Dumper id of VMDumper thread.
2485   static const int VMDumperId = 0;
2486   // VM dumper dumps both heap and non-heap data, other dumpers dump heap-only data.
2487   static bool is_vm_dumper(int dumper_id) { return dumper_id == VMDumperId; }
2488   // the 1st dumper calling get_next_dumper_id becomes VM dumper
2489   int get_next_dumper_id() {
2490     return AtomicAccess::fetch_then_add(&_dump_seq, 1);
2491   }
2492 
2493   DumpWriter* writer() const { return _writer; }
2494 
2495   bool skip_operation() const;
2496 
2497   // HPROF_GC_ROOT_THREAD_OBJ records for platform and mounted virtual threads
2498   void dump_threads(AbstractDumpWriter* writer);
2499 
2500   bool is_oom_thread(JavaThread* thread) const {
2501     return thread == _oome_thread && _oome_constructor != nullptr;
2502   }
2503 
2504   // HPROF_TRACE and HPROF_FRAME records for platform and mounted virtual threads
2505   void dump_stack_traces(AbstractDumpWriter* writer);
2506 
2507  public:
2508   VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome, uint num_dump_threads) :
2509     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
2510                     GCCause::_heap_dump /* GC Cause */,
2511                     0 /* total full collections, dummy, ignored */,
2512                     gc_before_heap_dump),
2513     WorkerTask("dump heap") {
2514     _writer = writer;
2515     _gc_before_heap_dump = gc_before_heap_dump;
2516     _klass_map = new (mtServiceability) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, mtServiceability);
2517 
2518     _thread_dumpers = nullptr;
2519     _thread_dumpers_count = 0;
2520     _thread_serial_num = 1;
2521     _frame_serial_num = 1;
2522 
2523     _dump_seq = VMDumperId;
2524     _num_dumper_threads = num_dump_threads;
2525     _dumper_controller = nullptr;
2526     _poi = nullptr;
2527     if (oome) {
2528       assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
2529       // get OutOfMemoryError zero-parameter constructor
2530       InstanceKlass* oome_ik = vmClasses::OutOfMemoryError_klass();
2531       _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
2532                                                           vmSymbols::void_method_signature());
2533       // get thread throwing OOME when generating the heap dump at OOME
2534       _oome_thread = JavaThread::current();
2535     } else {
2536       _oome_thread = nullptr;
2537       _oome_constructor = nullptr;
2538     }
2539   }
2540 
2541   ~VM_HeapDumper() {
2542     if (_thread_dumpers != nullptr) {
2543       for (int i = 0; i < _thread_dumpers_count; i++) {
2544         delete _thread_dumpers[i];
2545       }
2546       FREE_C_HEAP_ARRAY(ThreadDumper*, _thread_dumpers);
2547     }
2548 
2549     if (_dumper_controller != nullptr) {
2550       delete _dumper_controller;
2551       _dumper_controller = nullptr;
2552     }
2553     delete _klass_map;
2554   }
2555   int dump_seq()           { return _dump_seq; }
2556   bool is_parallel_dump()  { return _num_dumper_threads > 1; }
2557   void prepare_parallel_dump(WorkerThreads* workers);
2558 
2559   VMOp_Type type() const { return VMOp_HeapDumper; }
2560   virtual bool doit_prologue();
2561   void doit();
2562   void work(uint worker_id);
2563 
2564   // UnmountedVThreadDumper implementation
2565   void dump_vthread(oop vt, AbstractDumpWriter* segment_writer);
2566 };
2567 
2568 bool VM_HeapDumper::skip_operation() const {
2569   return false;
2570 }
2571 
2572 // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
2573 void DumperSupport::end_of_dump(AbstractDumpWriter* writer) {
2574   writer->finish_dump_segment();
2575 
2576   writer->write_u1(HPROF_HEAP_DUMP_END);
2577   writer->write_u4(0);
2578   writer->write_u4(0);
2579 }
2580 
2581 // Write a HPROF_GC_ROOT_THREAD_OBJ record for platform/carrier and mounted virtual threads.
2582 // Then walk the stack so that locals and JNI locals are dumped.
2583 void VM_HeapDumper::dump_threads(AbstractDumpWriter* writer) {
2584   for (int i = 0; i < _thread_dumpers_count; i++) {
2585     _thread_dumpers[i]->dump_thread_obj(writer);
2586     _thread_dumpers[i]->dump_stack_refs(writer);
2587   }
2588 }
2589 
2590 bool VM_HeapDumper::doit_prologue() {
2591   if (_gc_before_heap_dump && (UseZGC || UseShenandoahGC)) {
2592     // ZGC and Shenandoah cannot perform a synchronous GC cycle from within the VM thread.
2593     // So collect_as_vm_thread() is a noop. To respect the _gc_before_heap_dump flag a
2594     // synchronous GC cycle is performed from the caller thread in the prologue.
2595     Universe::heap()->collect(GCCause::_heap_dump);
2596   }
2597   return VM_GC_Operation::doit_prologue();
2598 }
2599 
2600 void VM_HeapDumper::prepare_parallel_dump(WorkerThreads* workers) {
2601   uint num_active_workers = workers != nullptr ? workers->active_workers() : 0;
2602   uint num_requested_dump_threads = _num_dumper_threads;
2603   // check if we can dump in parallel based on requested and active threads
2604   if (num_active_workers <= 1 || num_requested_dump_threads <= 1) {
2605     _num_dumper_threads = 1;
2606   } else {
2607     _num_dumper_threads = clamp(num_requested_dump_threads, 2U, num_active_workers);
2608   }
2609   _dumper_controller = new (std::nothrow) DumperController(_num_dumper_threads);
2610   bool can_parallel = _num_dumper_threads > 1;
2611   log_info(heapdump)("Requested dump threads %u, active dump threads %u, "
2612                      "actual dump threads %u, parallelism %s",
2613                      num_requested_dump_threads, num_active_workers,
2614                      _num_dumper_threads, can_parallel ? "true" : "false");
2615 }
2616 
2617 // The VM operation that dumps the heap. The dump consists of the following
2618 // records:
2619 //
2620 //  HPROF_HEADER
2621 //  [HPROF_UTF8]*
2622 //  [HPROF_LOAD_CLASS]*
2623 //  [[HPROF_FRAME]*|HPROF_TRACE]*
2624 //  [HPROF_GC_CLASS_DUMP]*
2625 //  [HPROF_HEAP_DUMP_SEGMENT]*
2626 //  HPROF_HEAP_DUMP_END
2627 //
2628 // The HPROF_TRACE records represent the stack traces where the heap dump
2629 // is generated and a "dummy trace" record which does not include
2630 // any frames. The dummy trace record is used to be referenced as the
2631 // unknown object alloc site.
2632 //
2633 // Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records.
2634 // To allow the heap dump be generated in a single pass we remember the position
2635 // of the dump length and fix it up after all sub-records have been written.
2636 // To generate the sub-records we iterate over the heap, writing
2637 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
2638 // records as we go. Once that is done we write records for some of the GC
2639 // roots.
2640 
2641 void VM_HeapDumper::doit() {
2642 
2643   CollectedHeap* ch = Universe::heap();
2644 
2645   ch->ensure_parsability(false); // must happen, even if collection does
2646                                  // not happen (e.g. due to GCLocker)
2647 
2648   if (_gc_before_heap_dump) {
2649     if (GCLocker::is_active()) {
2650       warning("GC locker is held; pre-heapdump GC was skipped");
2651     } else {
2652       ch->collect_as_vm_thread(GCCause::_heap_dump);
2653     }
2654   }
2655 
2656   WorkerThreads* workers = ch->safepoint_workers();
2657   prepare_parallel_dump(workers);
2658 
2659   if (!is_parallel_dump()) {
2660     work(VMDumperId);
2661   } else {
2662     ParallelObjectIterator poi(_num_dumper_threads);
2663     _poi = &poi;
2664     workers->run_task(this, _num_dumper_threads);
2665     _poi = nullptr;
2666   }
2667 }
2668 
2669 void VM_HeapDumper::work(uint worker_id) {
2670   // VM Dumper works on all non-heap data dumping and part of heap iteration.
2671   int dumper_id = get_next_dumper_id();
2672 
2673   if (is_vm_dumper(dumper_id)) {
2674     // lock global writer, it will be unlocked after VM Dumper finishes with non-heap data
2675     _dumper_controller->lock_global_writer();
2676     _dumper_controller->signal_start();
2677   } else {
2678     _dumper_controller->wait_for_start_signal();
2679   }
2680 
2681   if (is_vm_dumper(dumper_id)) {
2682     TraceTime timer("Dump non-objects", TRACETIME_LOG(Info, heapdump));
2683     // Write the file header - we always use 1.0.2
2684     const char* header = "JAVA PROFILE 1.0.2";
2685 
2686     // header is few bytes long - no chance to overflow int
2687     writer()->write_raw(header, strlen(header) + 1); // NUL terminated
2688     writer()->write_u4(oopSize);
2689     // timestamp is current time in ms
2690     writer()->write_u8(os::javaTimeMillis());
2691     // HPROF_UTF8 records
2692     SymbolTableDumper sym_dumper(writer());
2693     SymbolTable::symbols_do(&sym_dumper);
2694 
2695     // write HPROF_LOAD_CLASS records
2696     {
2697       LoadedClassDumper loaded_class_dumper(writer(), _klass_map);
2698       ClassLoaderDataGraph::classes_do(&loaded_class_dumper);
2699     }
2700 
2701     // write HPROF_FRAME and HPROF_TRACE records
2702     // this must be called after _klass_map is built when iterating the classes above.
2703     dump_stack_traces(writer());
2704 
2705     // unlock global writer, so parallel dumpers can dump stack traces of unmounted virtual threads
2706     _dumper_controller->unlock_global_writer();
2707   }
2708 
2709   // HPROF_HEAP_DUMP/HPROF_HEAP_DUMP_SEGMENT starts here
2710 
2711   ResourceMark rm;
2712   // share global compressor, local DumpWriter is not responsible for its life cycle
2713   DumpWriter segment_writer(DumpMerger::get_writer_path(writer()->get_file_path(), dumper_id),
2714                             writer()->is_overwrite(), writer()->compressor());
2715   if (!segment_writer.has_error()) {
2716     if (is_vm_dumper(dumper_id)) {
2717       // dump some non-heap subrecords to heap dump segment
2718       TraceTime timer("Dump non-objects (part 2)", TRACETIME_LOG(Info, heapdump));
2719       // Writes HPROF_GC_CLASS_DUMP records
2720       ClassDumper class_dumper(&segment_writer);
2721       ClassLoaderDataGraph::classes_do(&class_dumper);
2722 
2723       // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
2724       dump_threads(&segment_writer);
2725 
2726       // HPROF_GC_ROOT_JNI_GLOBAL
2727       JNIGlobalsDumper jni_dumper(&segment_writer);
2728       JNIHandles::oops_do(&jni_dumper);
2729       // technically not jni roots, but global roots
2730       // for things like preallocated throwable backtraces
2731       Universe::vm_global()->oops_do(&jni_dumper);
2732       // HPROF_GC_ROOT_STICKY_CLASS
2733       // These should be classes in the null class loader data, and not all classes
2734       // if !ClassUnloading
2735       StickyClassDumper stiky_class_dumper(&segment_writer);
2736       ClassLoaderData::the_null_class_loader_data()->classes_do(&stiky_class_dumper);
2737     }
2738 
2739     // Heap iteration.
2740     // writes HPROF_GC_INSTANCE_DUMP records.
2741     // After each sub-record is written check_segment_length will be invoked
2742     // to check if the current segment exceeds a threshold. If so, a new
2743     // segment is started.
2744     // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
2745     // of the heap dump.
2746 
2747     TraceTime timer(is_parallel_dump() ? "Dump heap objects in parallel" : "Dump heap objects", TRACETIME_LOG(Info, heapdump));
2748     HeapObjectDumper obj_dumper(&segment_writer, this, &_flat_dumper);
2749     if (!is_parallel_dump()) {
2750       Universe::heap()->object_iterate(&obj_dumper);
2751     } else {
2752       // == Parallel dump
2753       _poi->object_iterate(&obj_dumper, worker_id);
2754     }
2755 
2756     segment_writer.finish_dump_segment();
2757     segment_writer.flush();
2758   }
2759 
2760   _dumper_controller->dumper_complete(&segment_writer, writer());
2761 
2762   if (is_vm_dumper(dumper_id)) {
2763     _dumper_controller->wait_all_dumpers_complete();
2764 
2765     // flush global writer
2766     writer()->flush();
2767 
2768     // At this point, all fragments of the heapdump have been written to separate files.
2769     // We need to merge them into a complete heapdump and write HPROF_HEAP_DUMP_END at that time.
2770   }
2771 }
2772 
2773 void VM_HeapDumper::dump_stack_traces(AbstractDumpWriter* writer) {
2774   // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
2775   DumperSupport::write_header(writer, HPROF_TRACE, 3 * sizeof(u4));
2776   writer->write_u4((u4)STACK_TRACE_ID);
2777   writer->write_u4(0);                    // thread number
2778   writer->write_u4(0);                    // frame count
2779 
2780   // max number if every platform thread is carrier with mounted virtual thread
2781   _thread_dumpers = NEW_C_HEAP_ARRAY(ThreadDumper*, Threads::number_of_threads() * 2, mtInternal);
2782 
2783   for (JavaThreadIteratorWithHandle jtiwh; JavaThread * thread = jtiwh.next(); ) {
2784     if (ThreadDumper::should_dump_pthread(thread)) {
2785       bool add_oom_frame = is_oom_thread(thread);
2786 
2787       oop mounted_vt = thread->is_vthread_mounted() ? thread->vthread() : nullptr;
2788       if (mounted_vt != nullptr && !ThreadDumper::should_dump_vthread(mounted_vt)) {
2789         mounted_vt = nullptr;
2790       }
2791 
2792       // mounted vthread (if any)
2793       if (mounted_vt != nullptr) {
2794         ThreadDumper* thread_dumper = new ThreadDumper(ThreadDumper::ThreadType::MountedVirtual, thread, mounted_vt);
2795         _thread_dumpers[_thread_dumpers_count++] = thread_dumper;
2796         if (add_oom_frame) {
2797           thread_dumper->add_oom_frame(_oome_constructor);
2798           // we add oom frame to the VT stack, don't add it to the carrier thread stack
2799           add_oom_frame = false;
2800         }
2801         thread_dumper->init_serial_nums(&_thread_serial_num, &_frame_serial_num);
2802         thread_dumper->dump_stack_traces(writer, _klass_map);
2803       }
2804 
2805       // platform or carrier thread
2806       ThreadDumper* thread_dumper = new ThreadDumper(ThreadDumper::ThreadType::Platform, thread, thread->threadObj());
2807       _thread_dumpers[_thread_dumpers_count++] = thread_dumper;
2808       if (add_oom_frame) {
2809         thread_dumper->add_oom_frame(_oome_constructor);
2810       }
2811       thread_dumper->init_serial_nums(&_thread_serial_num, &_frame_serial_num);
2812       thread_dumper->dump_stack_traces(writer, _klass_map);
2813     }
2814   }
2815 }
2816 
2817 void VM_HeapDumper::dump_vthread(oop vt, AbstractDumpWriter* segment_writer) {
2818   // unmounted vthread has no JavaThread
2819   ThreadDumper thread_dumper(ThreadDumper::ThreadType::UnmountedVirtual, nullptr, vt);
2820   thread_dumper.init_serial_nums(&_thread_serial_num, &_frame_serial_num);
2821 
2822   // write HPROF_TRACE/HPROF_FRAME records to global writer
2823   _dumper_controller->lock_global_writer();
2824   thread_dumper.dump_stack_traces(writer(), _klass_map);
2825   _dumper_controller->unlock_global_writer();
2826 
2827   // write HPROF_GC_ROOT_THREAD_OBJ/HPROF_GC_ROOT_JAVA_FRAME/HPROF_GC_ROOT_JNI_LOCAL subrecord
2828   // to segment writer
2829   thread_dumper.dump_thread_obj(segment_writer);
2830   thread_dumper.dump_stack_refs(segment_writer);
2831 }
2832 
2833 // dump the heap to given path.
2834 int HeapDumper::dump(const char* path, outputStream* out, int compression, bool overwrite, uint num_dump_threads) {
2835   assert(path != nullptr && strlen(path) > 0, "path missing");
2836 
2837   // print message in interactive case
2838   if (out != nullptr) {
2839     out->print_cr("Dumping heap to %s ...", path);
2840     timer()->start();
2841   }
2842 
2843   if (_oome && num_dump_threads > 1) {
2844     // Each additional parallel writer requires several MB of internal memory
2845     // (DumpWriter buffer, DumperClassCacheTable, GZipCompressor buffers).
2846     // For the OOM handling we may already be limited in memory.
2847     // Lets ensure we have at least 20MB per thread.
2848     physical_memory_size_type free_memory = 0;
2849     // Return value ignored - defaulting to 0 on failure.
2850     (void)os::free_memory(free_memory);
2851     julong max_threads = free_memory / (20 * M);
2852     if (num_dump_threads > max_threads) {
2853       num_dump_threads = MAX2<uint>(1, (uint)max_threads);
2854     }
2855   }
2856 
2857   // create JFR event
2858   EventHeapDump event;
2859 
2860   AbstractCompressor* compressor = nullptr;
2861 
2862   if (compression > 0) {
2863     compressor = new (std::nothrow) GZipCompressor(compression);
2864 
2865     if (compressor == nullptr) {
2866       set_error("Could not allocate gzip compressor");
2867       return -1;
2868     }
2869   }
2870 
2871   DumpWriter writer(path, overwrite, compressor);
2872 
2873   if (writer.error() != nullptr) {
2874     set_error(writer.error());
2875     if (out != nullptr) {
2876       out->print_cr("Unable to create %s: %s", path,
2877         (error() != nullptr) ? error() : "reason unknown");
2878     }
2879     return -1;
2880   }
2881 
2882   // generate the segmented heap dump into separate files
2883   VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome, num_dump_threads);
2884   VMThread::execute(&dumper);
2885 
2886   // record any error that the writer may have encountered
2887   set_error(writer.error());
2888 
2889   // Heap dump process is done in two phases
2890   //
2891   // Phase 1: Concurrent threads directly write heap data to multiple heap files.
2892   //          This is done by VM_HeapDumper, which is performed within safepoint.
2893   //
2894   // Phase 2: Merge multiple heap files into one complete heap dump file.
2895   //          This is done by DumpMerger, which is performed outside safepoint
2896 
2897   DumpMerger merger(path, &writer, dumper.dump_seq());
2898   // Perform heapdump file merge operation in the current thread prevents us
2899   // from occupying the VM Thread, which in turn affects the occurrence of
2900   // GC and other VM operations.
2901   merger.do_merge();
2902   if (writer.error() != nullptr) {
2903     set_error(writer.error());
2904   }
2905 
2906   // emit JFR event
2907   if (error() == nullptr) {
2908     event.set_destination(path);
2909     event.set_gcBeforeDump(_gc_before_heap_dump);
2910     event.set_size(writer.bytes_written());
2911     event.set_onOutOfMemoryError(_oome);
2912     event.set_overwrite(overwrite);
2913     event.set_compression(compression);
2914     event.commit();
2915   } else {
2916     log_debug(aot, heap)("Error %s while dumping heap", error());
2917   }
2918 
2919   // print message in interactive case
2920   if (out != nullptr) {
2921     timer()->stop();
2922     if (error() == nullptr) {
2923       out->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
2924                     writer.bytes_written(), timer()->seconds());
2925     } else {
2926       out->print_cr("Dump file is incomplete: %s", writer.error());
2927     }
2928   }
2929 
2930   if (compressor != nullptr) {
2931     delete compressor;
2932   }
2933   return (writer.error() == nullptr) ? 0 : -1;
2934 }
2935 
2936 // stop timer (if still active), and free any error string we might be holding
2937 HeapDumper::~HeapDumper() {
2938   if (timer()->is_active()) {
2939     timer()->stop();
2940   }
2941   set_error(nullptr);
2942 }
2943 
2944 
2945 // returns the error string (resource allocated), or null
2946 char* HeapDumper::error_as_C_string() const {
2947   if (error() != nullptr) {
2948     char* str = ResourceArea::strdup(error());
2949     return str;
2950   } else {
2951     return nullptr;
2952   }
2953 }
2954 
2955 // set the error string
2956 void HeapDumper::set_error(char const* error) {
2957   if (_error != nullptr) {
2958     os::free(_error);
2959   }
2960   if (error == nullptr) {
2961     _error = nullptr;
2962   } else {
2963     _error = os::strdup(error);
2964     assert(_error != nullptr, "allocation failure");
2965   }
2966 }
2967 
2968 // Called by out-of-memory error reporting by a single Java thread
2969 // outside of a JVM safepoint
2970 void HeapDumper::dump_heap_from_oome() {
2971   HeapDumper::dump_heap(true);
2972 }
2973 
2974 // Called by error reporting by a single Java thread outside of a JVM safepoint,
2975 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
2976 // callers are strictly serialized and guaranteed not to interfere below. For more
2977 // general use, however, this method will need modification to prevent
2978 // inteference when updating the static variables base_path and dump_file_seq below.
2979 void HeapDumper::dump_heap() {
2980   HeapDumper::dump_heap(false);
2981 }
2982 
2983 void HeapDumper::dump_heap(bool oome) {
2984   static char base_path[JVM_MAXPATHLEN] = {'\0'};
2985   static uint dump_file_seq = 0;
2986   char my_path[JVM_MAXPATHLEN];
2987   const int max_digit_chars = 20;
2988   const char* dump_file_name = HeapDumpGzipLevel > 0 ? "java_pid%p.hprof.gz" : "java_pid%p.hprof";
2989 
2990   // The dump file defaults to java_pid<pid>.hprof in the current working
2991   // directory. HeapDumpPath=<file> can be used to specify an alternative
2992   // dump file name or a directory where dump file is created.
2993   if (dump_file_seq == 0) { // first time in, we initialize base_path
2994     // Set base path (name or directory, default or custom, without seq no), doing %p substitution.
2995     const char *path_src = (HeapDumpPath != nullptr && HeapDumpPath[0] != '\0') ? HeapDumpPath : dump_file_name;
2996     if (!Arguments::copy_expand_pid(path_src, strlen(path_src), base_path, JVM_MAXPATHLEN - max_digit_chars)) {
2997       warning("Cannot create heap dump file.  HeapDumpPath is too long.");
2998       return;
2999     }
3000     // Check if the path is an existing directory
3001     DIR* dir = os::opendir(base_path);
3002     if (dir != nullptr) {
3003       os::closedir(dir);
3004       // Path is a directory.  Append a file separator (if needed).
3005       size_t fs_len = strlen(os::file_separator());
3006       if (strlen(base_path) >= fs_len) {
3007         char* end = base_path;
3008         end += (strlen(base_path) - fs_len);
3009         if (strcmp(end, os::file_separator()) != 0) {
3010           strcat(base_path, os::file_separator());
3011         }
3012       }
3013       // Then add the default name, with %p substitution.  Use my_path temporarily.
3014       if (!Arguments::copy_expand_pid(dump_file_name, strlen(dump_file_name), my_path, JVM_MAXPATHLEN - max_digit_chars)) {
3015         warning("Cannot create heap dump file.  HeapDumpPath is too long.");
3016         return;
3017       }
3018       const size_t dlen = strlen(base_path);
3019       jio_snprintf(&base_path[dlen], sizeof(base_path) - dlen, "%s", my_path);
3020     }
3021     strncpy(my_path, base_path, JVM_MAXPATHLEN);
3022   } else {
3023     // Append a sequence number id for dumps following the first
3024     const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
3025     jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);
3026   }
3027   dump_file_seq++;   // increment seq number for next time we dump
3028 
3029   HeapDumper dumper(false /* no GC before heap dump */,
3030                     oome  /* pass along out-of-memory-error flag */);
3031   dumper.dump(my_path, tty, HeapDumpGzipLevel);
3032 }