comparison src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp @ 55571:49102ba8cf14

8214542: JFR: Old Object Sample event slow on a deep heap in debug builds Reviewed-by: egahlin, rwestberg
author mgronlun
date Wed, 03 Jul 2019 11:34:46 +0200
parents 1126f0607c70
children caa25ab47aca
comparison
equal deleted inserted replaced
6:d9626cef06a4 7:0fdd4e1bc422
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "jfr/jni/jfrJavaSupport.hpp" 26 #include "jfr/jni/jfrJavaSupport.hpp"
27 #include "jfr/leakprofiler/leakProfiler.hpp"
27 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" 28 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
29 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
28 #include "jfr/recorder/jfrRecorder.hpp" 30 #include "jfr/recorder/jfrRecorder.hpp"
29 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" 31 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
30 #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp" 32 #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp"
31 #include "jfr/recorder/repository/jfrChunkRotation.hpp" 33 #include "jfr/recorder/repository/jfrChunkRotation.hpp"
32 #include "jfr/recorder/repository/jfrChunkWriter.hpp" 34 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
333 void JfrRecorderService::prepare_for_vm_error_rotation() { 335 void JfrRecorderService::prepare_for_vm_error_rotation() {
334 if (!_chunkwriter.is_valid()) { 336 if (!_chunkwriter.is_valid()) {
335 open_new_chunk(true); 337 open_new_chunk(true);
336 } 338 }
337 _checkpoint_manager.register_service_thread(Thread::current()); 339 _checkpoint_manager.register_service_thread(Thread::current());
340 JfrMetadataEvent::lock();
338 } 341 }
339 342
340 void JfrRecorderService::open_new_chunk(bool vm_error) { 343 void JfrRecorderService::open_new_chunk(bool vm_error) {
341 assert(!_chunkwriter.is_valid(), "invariant"); 344 assert(!_chunkwriter.is_valid(), "invariant");
342 assert(!JfrStream_lock->owned_by_self(), "invariant"); 345 assert(!JfrStream_lock->owned_by_self(), "invariant");
396 WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear); 399 WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear);
397 WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo); 400 WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo);
398 write_stack_trace_checkpoint.process(); 401 write_stack_trace_checkpoint.process();
399 } 402 }
400 403
404 static void write_object_sample_stacktrace(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repository) {
405 WriteObjectSampleStacktrace object_sample_stacktrace(sampler, stack_trace_repository);
406 object_sample_stacktrace.process();
407 }
408
401 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { 409 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
402 WriteStringPool write_string_pool(string_pool); 410 WriteStringPool write_string_pool(string_pool);
403 WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool); 411 WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
404 write_string_pool_checkpoint.process(); 412 write_string_pool_checkpoint.process();
405 } 413 }
416 // lock stream lock -> 424 // lock stream lock ->
417 // write non-safepoint dependent types -> 425 // write non-safepoint dependent types ->
418 // write checkpoint epoch transition list-> 426 // write checkpoint epoch transition list->
419 // write stack trace checkpoint -> 427 // write stack trace checkpoint ->
420 // write string pool checkpoint -> 428 // write string pool checkpoint ->
421 // write storage -> 429 // write object sample stacktraces ->
422 // release stream lock 430 // write storage ->
431 // release stream lock
423 // 432 //
424 void JfrRecorderService::pre_safepoint_write() { 433 void JfrRecorderService::pre_safepoint_write() {
425 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); 434 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
426 assert(_chunkwriter.is_valid(), "invariant"); 435 assert(_chunkwriter.is_valid(), "invariant");
427 _checkpoint_manager.write_types(); 436 _checkpoint_manager.write_types();
428 _checkpoint_manager.write_epoch_transition_mspace(); 437 _checkpoint_manager.write_epoch_transition_mspace();
429 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); 438 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
430 write_stringpool_checkpoint(_string_pool, _chunkwriter); 439 write_stringpool_checkpoint(_string_pool, _chunkwriter);
440 if (LeakProfiler::is_running()) {
441 // Exclusive access to the object sampler instance.
442 // The sampler is released (unlocked) later in post_safepoint_write.
443 ObjectSampler* const sampler = ObjectSampler::acquire();
444 assert(sampler != NULL, "invariant");
445 write_object_sample_stacktrace(sampler, _stack_trace_repository);
446 }
431 _storage.write(); 447 _storage.write();
432 } 448 }
433 449
434 void JfrRecorderService::invoke_safepoint_write() { 450 void JfrRecorderService::invoke_safepoint_write() {
435 JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this); 451 JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
436 VMThread::execute(&safepoint_task); 452 VMThread::execute(&safepoint_task);
437 } 453 }
438 454
439 static void write_object_sample_stacktrace(JfrStackTraceRepository& stack_trace_repository) {
440 WriteObjectSampleStacktrace object_sample_stacktrace(stack_trace_repository);
441 object_sample_stacktrace.process();
442 }
443
444 // 455 //
445 // safepoint write sequence 456 // safepoint write sequence
446 // 457 //
447 // lock stream lock -> 458 // lock stream lock ->
448 // write object sample stacktraces ->
449 // write stacktrace repository -> 459 // write stacktrace repository ->
450 // write string pool -> 460 // write string pool ->
451 // write safepoint dependent types -> 461 // write safepoint dependent types ->
452 // write storage -> 462 // write storage ->
453 // shift_epoch -> 463 // shift_epoch ->
456 // release stream lock 466 // release stream lock
457 // 467 //
458 void JfrRecorderService::safepoint_write() { 468 void JfrRecorderService::safepoint_write() {
459 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 469 assert(SafepointSynchronize::is_at_safepoint(), "invariant");
460 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); 470 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
461 write_object_sample_stacktrace(_stack_trace_repository);
462 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); 471 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true);
463 write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); 472 write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
464 _checkpoint_manager.write_safepoint_types(); 473 _checkpoint_manager.write_safepoint_types();
465 _storage.write_at_safepoint(); 474 _storage.write_at_safepoint();
466 _checkpoint_manager.shift_epoch(); 475 _checkpoint_manager.shift_epoch();
476 } 485 }
477 486
478 // 487 //
479 // post-safepoint write sequence 488 // post-safepoint write sequence
480 // 489 //
481 // lock stream lock -> 490 // write type set ->
482 // write type set -> 491 // release object sampler ->
483 // write checkpoints -> 492 // lock stream lock ->
484 // write metadata event -> 493 // write checkpoints ->
485 // write chunk header -> 494 // write metadata event ->
486 // close chunk fd -> 495 // write chunk header ->
487 // release stream lock 496 // close chunk fd ->
497 // release stream lock
488 // 498 //
489 void JfrRecorderService::post_safepoint_write() { 499 void JfrRecorderService::post_safepoint_write() {
490 assert(_chunkwriter.is_valid(), "invariant"); 500 assert(_chunkwriter.is_valid(), "invariant");
491 // During the safepoint tasks just completed, the system transitioned to a new epoch. 501 // During the safepoint tasks just completed, the system transitioned to a new epoch.
492 // Type tagging is epoch relative which entails we are able to write out the 502 // Type tagging is epoch relative which entails we are able to write out the
493 // already tagged artifacts for the previous epoch. We can accomplish this concurrently 503 // already tagged artifacts for the previous epoch. We can accomplish this concurrently
494 // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. 504 // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint.
495 _checkpoint_manager.write_type_set(); 505 _checkpoint_manager.write_type_set();
506 if (LeakProfiler::is_running()) {
507 // The object sampler instance was exclusively acquired and locked in pre_safepoint_write.
508 // Note: There is a dependency on write_type_set() above, ensure the release is subsequent.
509 ObjectSampler::release();
510 }
496 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); 511 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
497 // serialize any outstanding checkpoint memory 512 // serialize any outstanding checkpoint memory
498 _checkpoint_manager.write(); 513 _checkpoint_manager.write();
499 // serialize the metadata descriptor event and close out the chunk 514 // serialize the metadata descriptor event and close out the chunk
500 _repository.close_chunk(write_metadata_event(_chunkwriter)); 515 _repository.close_chunk(write_metadata_event(_chunkwriter));
510 } 525 }
511 526
512 void JfrRecorderService::finalize_current_chunk_on_vm_error() { 527 void JfrRecorderService::finalize_current_chunk_on_vm_error() {
513 assert(_chunkwriter.is_valid(), "invariant"); 528 assert(_chunkwriter.is_valid(), "invariant");
514 pre_safepoint_write(); 529 pre_safepoint_write();
515 JfrMetadataEvent::lock();
516 // Do not attempt safepoint dependent operations during emergency dump. 530 // Do not attempt safepoint dependent operations during emergency dump.
517 // Optimistically write tagged artifacts. 531 // Optimistically write tagged artifacts.
518 _checkpoint_manager.shift_epoch(); 532 _checkpoint_manager.shift_epoch();
519 _checkpoint_manager.write_type_set();
520 // update time 533 // update time
521 _chunkwriter.time_stamp_chunk_now(); 534 _chunkwriter.time_stamp_chunk_now();
522 post_safepoint_write(); 535 post_safepoint_write();
523 assert(!_chunkwriter.is_valid(), "invariant"); 536 assert(!_chunkwriter.is_valid(), "invariant");
524 } 537 }