2244 // the stack so that locals and JNI locals are dumped.
2245 void VM_HeapDumper::do_threads() {
2246 for (int i=0; i < _num_threads; i++) {
2247 JavaThread* thread = _stack_traces[i]->thread();
2248 oop threadObj = thread->threadObj();
2249 u4 thread_serial_num = i+1;
2250 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;
2251 u4 size = 1 + sizeof(address) + 4 + 4;
2252 writer()->start_sub_record(HPROF_GC_ROOT_THREAD_OBJ, size);
2253 writer()->write_objectID(threadObj);
2254 writer()->write_u4(thread_serial_num); // thread number
2255 writer()->write_u4(stack_serial_num); // stack trace serial number
2256 writer()->end_sub_record();
2257 int num_frames = do_thread(thread, thread_serial_num);
2258 assert(num_frames == _stack_traces[i]->get_stack_depth(),
2259 "total number of Java frames not matched");
2260 }
2261 }
2262
2263 bool VM_HeapDumper::doit_prologue() {
2264 if (_gc_before_heap_dump && UseZGC) {
2265 // ZGC cannot perform a synchronous GC cycle from within the VM thread.
2266 // So ZCollectedHeap::collect_as_vm_thread() is a noop. To respect the
2267 // _gc_before_heap_dump flag a synchronous GC cycle is performed from
2268 // the caller thread in the prologue.
2269 Universe::heap()->collect(GCCause::_heap_dump);
2270 }
2271 return VM_GC_Operation::doit_prologue();
2272 }
2273
2274
2275 // The VM operation that dumps the heap. The dump consists of the following
2276 // records:
2277 //
2278 // HPROF_HEADER
2279 // [HPROF_UTF8]*
2280 // [HPROF_LOAD_CLASS]*
2281 // [[HPROF_FRAME]*|HPROF_TRACE]*
2282 // [HPROF_GC_CLASS_DUMP]*
2283 // [HPROF_HEAP_DUMP_SEGMENT]*
2284 // HPROF_HEAP_DUMP_END
2285 //
2286 // The HPROF_TRACE records represent the stack traces where the heap dump
2287 // is generated and a "dummy trace" record which does not include
2288 // any frames. The dummy trace record is used to be referenced as the
|
2244 // the stack so that locals and JNI locals are dumped.
2245 void VM_HeapDumper::do_threads() {
2246 for (int i=0; i < _num_threads; i++) {
2247 JavaThread* thread = _stack_traces[i]->thread();
2248 oop threadObj = thread->threadObj();
2249 u4 thread_serial_num = i+1;
2250 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;
2251 u4 size = 1 + sizeof(address) + 4 + 4;
2252 writer()->start_sub_record(HPROF_GC_ROOT_THREAD_OBJ, size);
2253 writer()->write_objectID(threadObj);
2254 writer()->write_u4(thread_serial_num); // thread number
2255 writer()->write_u4(stack_serial_num); // stack trace serial number
2256 writer()->end_sub_record();
2257 int num_frames = do_thread(thread, thread_serial_num);
2258 assert(num_frames == _stack_traces[i]->get_stack_depth(),
2259 "total number of Java frames not matched");
2260 }
2261 }
2262
2263 bool VM_HeapDumper::doit_prologue() {
2264 if (_gc_before_heap_dump && (UseZGC || UseShenandoahGC)) {
2265 // ZGC and Shenandoah cannot perform a synchronous GC cycle from within the VM thread.
2266 // So collect_as_vm_thread() is a noop. To respect the _gc_before_heap_dump flag a
2267 // synchronous GC cycle is performed from the caller thread in the prologue.
2268 Universe::heap()->collect(GCCause::_heap_dump);
2269 }
2270 return VM_GC_Operation::doit_prologue();
2271 }
2272
2273
2274 // The VM operation that dumps the heap. The dump consists of the following
2275 // records:
2276 //
2277 // HPROF_HEADER
2278 // [HPROF_UTF8]*
2279 // [HPROF_LOAD_CLASS]*
2280 // [[HPROF_FRAME]*|HPROF_TRACE]*
2281 // [HPROF_GC_CLASS_DUMP]*
2282 // [HPROF_HEAP_DUMP_SEGMENT]*
2283 // HPROF_HEAP_DUMP_END
2284 //
2285 // The HPROF_TRACE records represent the stack traces where the heap dump
2286 // is generated and a "dummy trace" record which does not include
2287 // any frames. The dummy trace record is used to be referenced as the
|