@@ -441,6 +441,8 @@ class AbstractDumpWriter : public CHeapObj<mtInternal> {
441441 void write_symbolID (Symbol* o);
442442 void write_classID (Klass* k);
443443 void write_id (u4 x);
444+ // SapMachine 2026-05-06: Writes zeros to the buffer.
445+ void write_zero (size_t len);
444446
445447 // Start a new sub-record. Starts a new heap dump segment if needed.
446448 void start_sub_record (u1 tag, u4 len);
@@ -539,6 +541,26 @@ void AbstractDumpWriter::write_id(u4 x) {
539541#endif
540542}
541543
544+ // SapMachine 2026-05-06: Writes zeros to the buffer.
545+ void AbstractDumpWriter::write_zero (size_t len) {
546+ assert (!_in_dump_segment || (_sub_record_left >= len), " sub-record too large" );
547+ DEBUG_ONLY (_sub_record_left -= len);
548+
549+ // flush buffer to make room.
550+ while (len > buffer_size () - position ()) {
551+ assert (!_in_dump_segment || _is_huge_sub_record,
552+ " Cannot overflow in non-huge sub-record." );
553+ size_t to_write = buffer_size () - position ();
554+ memset (buffer () + position (), 0 , to_write);
555+ len -= to_write;
556+ set_position (position () + to_write);
557+ flush ();
558+ }
559+
560+ memset (buffer () + position (), 0 , len);
561+ set_position (position () + len);
562+ }
563+
542564// We use java mirror as the class ID
543565void AbstractDumpWriter::write_classID (Klass* k) {
544566 write_objectID (k->java_mirror ());
@@ -1372,6 +1394,24 @@ void DumperSupport::dump_prim_array(AbstractDumpWriter* writer, typeArrayOop arr
13721394 return ;
13731395 }
13741396
1397+ // SapMachine 2026-05-06: If enabled, we don't dump the whole content of large arrays, but just the start
1398+ // and fill the rest with zeroes.
1399+ int fill_with_zero = 0 ;
1400+
1401+ if (LimitPrimitiveArrayContentInHeapDump) {
1402+ int limit = ArrayContentSizeLimitInHeapDump;
1403+
1404+ if (type == T_BYTE || type == T_CHAR ) {
1405+ limit = StringLikeContentSizeLimitInHeapDump;
1406+ }
1407+
1408+ if (length > limit) {
1409+ fill_with_zero = length - limit;
1410+ length = limit;
1411+ length_in_bytes = (u4) length * type_size;
1412+ }
1413+ }
1414+
13751415 // If the byte ordering is big endian then we can copy most types directly
13761416
13771417 switch (type) {
@@ -1439,6 +1479,11 @@ void DumperSupport::dump_prim_array(AbstractDumpWriter* writer, typeArrayOop arr
14391479 default : ShouldNotReachHere ();
14401480 }
14411481
1482+ // SapMachine 2026-05-06: Fill with zeros, if we don't dump the whole content of the array.
1483+ if (fill_with_zero > 0 ) {
1484+ writer->write_zero ((u4) fill_with_zero * type_size);
1485+ }
1486+
14421487 writer->end_sub_record ();
14431488}
14441489
@@ -2433,7 +2478,8 @@ void VM_HeapDumper::doit() {
24332478
24342479void VM_HeapDumper::work (uint worker_id) {
24352480 // VM Dumper works on all non-heap data dumping and part of heap iteration.
2436- int dumper_id = get_next_dumper_id ();
2481+ // SapMachine 2026-07-06: Don't create a segment for non-parallel dumps.
2482+ int dumper_id = is_parallel_dump () ? get_next_dumper_id () : VMDumperId;
24372483
24382484 if (is_vm_dumper (dumper_id)) {
24392485 // lock global writer, it will be unlocked after VM Dumper finishes with non-heap data
@@ -2475,8 +2521,11 @@ void VM_HeapDumper::work(uint worker_id) {
24752521
24762522 ResourceMark rm;
24772523 // share global compressor, local DumpWriter is not responsible for its life cycle
2478- DumpWriter segment_writer (DumpMerger::get_writer_path (writer ()->get_file_path (), dumper_id),
2479- writer ()->is_overwrite (), writer ()->compressor ());
2524+ // SapMachine 2026-05-06: Don't use segments if the dump is not parallel. This makes it
2525+ // possible to not use any disk space if dumping to a named pipe or a tty.
2526+ DumpWriter* parallel_writer = is_parallel_dump () ? new DumpWriter (DumpMerger::get_writer_path (writer ()->get_file_path (), dumper_id),
2527+ writer ()->is_overwrite (), writer ()->compressor ()) : nullptr ;
2528+ DumpWriter& segment_writer = parallel_writer == nullptr ? *writer () : *parallel_writer;
24802529 if (!segment_writer.has_error ()) {
24812530 if (is_vm_dumper (dumper_id)) {
24822531 // dump some non-heap subrecords to heap dump segment
@@ -2533,6 +2582,8 @@ void VM_HeapDumper::work(uint worker_id) {
25332582 // At this point, all fragments of the heapdump have been written to separate files.
25342583 // We need to merge them into a complete heapdump and write HPROF_HEAP_DUMP_END at that time.
25352584 }
2585+ // SapMachine 2026-05-06
2586+ delete parallel_writer;
25362587}
25372588
25382589void VM_HeapDumper::dump_stack_traces (AbstractDumpWriter* writer) {
@@ -2584,6 +2635,17 @@ void VM_HeapDumper::dump_vthread(oop vt, AbstractDumpWriter* segment_writer) {
25842635 ThreadDumper thread_dumper (ThreadDumper::ThreadType::UnmountedVirtual, nullptr , vt);
25852636 thread_dumper.init_serial_nums (&_thread_serial_num, &_frame_serial_num);
25862637
2638+ // SapMachine 2026-05-06: If we don't do a parallel dump, we don't need the lock
2639+ // but have to end the current heap dump segment.
2640+ if (!is_parallel_dump ()) {
2641+ segment_writer->finish_dump_segment ();
2642+ thread_dumper.dump_stack_traces (writer (), _klass_map);
2643+ thread_dumper.dump_thread_obj (segment_writer);
2644+ thread_dumper.dump_stack_refs (segment_writer);
2645+
2646+ return ;
2647+ }
2648+
25872649 // write HPROF_TRACE/HPROF_FRAME records to global writer
25882650 _dumper_controller->lock_global_writer ();
25892651 thread_dumper.dump_stack_traces (writer (), _klass_map);
@@ -2734,7 +2796,9 @@ void HeapDumper::set_error(char const* error) {
27342796// outside of a JVM safepoint
27352797void HeapDumper::dump_heap_from_oome () {
27362798 // SapMachine 2024-05-10: HeapDumpPath for jcmd
2737- HeapDumper::dump_heap (false , true );
2799+ // SapMachine 2026-05-06: Handle HeapDumpOverwrite and HeapDumpParallelism.
2800+ HeapDumper::dump_heap (false , true , tty, -1 , HeapDumpOverwrite, HeapDumpParallelism == 0 ?
2801+ HeapDumper::default_num_of_dump_threads (): HeapDumpParallelism);
27382802}
27392803
27402804// Called by error reporting by a single Java thread outside of a JVM safepoint,
@@ -2744,7 +2808,9 @@ void HeapDumper::dump_heap_from_oome() {
27442808// inteference when updating the static variables base_path and dump_file_seq below.
27452809void HeapDumper::dump_heap () {
27462810 // SapMachine 2024-05-10: HeapDumpPath for jcmd
2747- HeapDumper::dump_heap (false , false );
2811+ // SapMachine 2026-05-06: Handle HeapDumpOverwrite and HeapDumpParallelism.
2812+ HeapDumper::dump_heap (false , false , tty, -1 , HeapDumpOverwrite, HeapDumpParallelism == 0 ?
2813+ HeapDumper::default_num_of_dump_threads () : HeapDumpParallelism);
27482814}
27492815
27502816// SapMachine 2024-05-10: HeapDumpPath for jcmd
0 commit comments