On Tue, 14 Nov 2023 21:54:06 GMT, Alex Menkov <amen...@openjdk.org> wrote:

> The change impelements dumping of unmounted virtual threads data (stack 
> traces and stack references).
> Unmounted vthreads can be detected only by iterating over the heap, but hprof 
> stack trace records (HPROF_FRAME/HPROF_TRACE) should be written before 
> HPROF_HEAP_DUMP/HPROF_HEAP_DUMP_SEGMENT.
> HeapDumper supports segment dump (parallel dump to separate files with 
> subsequent file merge outside of safepoint), the fix switches HeapDumper  to 
> always use segment dump: 1st segment contains only non-heap data, other 
> segments are used for dumping heap objects. For serial dumping 
> single-threaded dumping is performed, but 2 segments are created anyway.
> When HeapObjectDumper detects unmounted virtual thread, it writes 
> HPROF_FRAME/HPROF_TRACE records to the 1st segment ("global writer"), and 
> writes thread object (HPROF_GC_ROOT_JAVA_FRAME) and stack references 
> (HPROF_GC_ROOT_JAVA_FRAME/HPROF_GC_ROOT_JNI_LOCAL) to the HeapObjectDumper 
> segment.
> As parallel dumpers may write HPROF_FRAME/HPROF_TRACE concurrently and 
> VMDumper needs to write non-heap data before heap object dumpers can write 
> virtual threads data, writing to global writer is protected with 
> DumperController::_global_writer_lock.
> 
> Testing: run tests which perform heap dump (in different scenarios):
>  - test/hotspot/jtreg/serviceability
>  - test/hotspot/jtreg/runtime/ErrorHandling
>  - test/hotspot/jtreg/gc/epsilon
>  - test/jdk/sun/tools/jhsdb

src/hotspot/share/services/heapDumper.cpp line 1896:

> 1894: 
> 1895:  public:
> 1896:   HeapObjectDumper(AbstractDumpWriter* writer, UnmountedVThreadDumper* 
> vthread_dumper)

Maybe we can pass global writer to HeapObjectDumper and thus simplify the 
implementation? We can remove `class VM_HeapDumper : public VM_GC_Operation, 
public WorkerTask, public UnmountedVThreadDumper {` and 
`UnmountedVThreadDumper` then.

src/hotspot/share/services/heapDumper.cpp line 2024:

> 2022: char* DumpMerger::get_writer_path(const char* base_path, int seq) {
> 2023:   // calculate required buffer size
> 2024:     size_t buf_size = strlen(base_path)

Format

src/hotspot/share/services/heapDumper.cpp line 2411:

> 2409: 
> 2410:   WorkerThreads* workers = ch->safepoint_workers();
> 2411:   update_parallel_dump_count(workers);

Maybe consolidate them together

  update_parallel_dump_count(workers);


=>

prepare_parallel_dump(workers){
 ...  // copy from update_parallel_dump_count
 _dumper_controller = new (std::nothrow) DumperController(_num_dumper_threads);
}

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/16665#discussion_r1395079535
PR Review Comment: https://git.openjdk.org/jdk/pull/16665#discussion_r1395071539
PR Review Comment: https://git.openjdk.org/jdk/pull/16665#discussion_r1395084194

Reply via email to