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(®_map);
2097 vframe* vf = vframe::new_vframe(&fr, ®_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(®_map)
2112 : _java_thread->platform_thread_last_java_vframe(®_map);
2113
2114 case ThreadType::MountedVirtual:
2115 return _java_thread->last_java_vframe(®_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 }