diff -r 84ef29ccac56 -r 00860d9caf4d src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Fri Aug 23 18:47:55 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Sat Aug 24 14:30:27 2019 +0200 @@ -25,7 +25,9 @@ #include "precompiled.hpp" #include "jfrfiles/jfrEventClasses.hpp" #include "jfr/jni/jfrJavaSupport.hpp" +#include "jfr/leakprofiler/leakProfiler.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" +#include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp" @@ -273,16 +275,15 @@ template static void write_flush_event(Functor& f) { - if (!Functor::is_event_enabled()) { - return; + if (Functor::is_event_enabled()) { + typename Functor::EventType e(UNTIMED); + e.set_starttime(f.start_time()); + e.set_endtime(f.end_time()); + e.set_flushId(flushpoint_id); + e.set_elements(f.elements()); + e.set_size(f.size()); + e.commit(); } - typename Functor::EventType e(UNTIMED); - e.set_starttime(f.start_time()); - e.set_endtime(f.end_time()); - e.set_flushId(flushpoint_id); - e.set_elements(f.elements()); - e.set_size(f.size()); - e.commit(); } template @@ -434,18 +435,16 @@ vm_error = true; prepare_for_vm_error_rotation(); } + if (!_storage.control().to_disk()) { + in_memory_rotation(); + } else if (vm_error) { + vm_error_rotation(); + } else { + chunk_rotation(); + } if (msgs & (MSGBIT(MSG_STOP))) { stop(); } - if (!_storage.control().to_disk()) { - in_memory_rotation(); - return; - } - if (vm_error) { - vm_error_rotation(); - return; - } - chunk_rotation(); } void JfrRecorderService::prepare_for_vm_error_rotation() { @@ -630,25 +629,29 @@ Flush fl(_chunkwriter, flushpoint); invoke_with_flush_event(fl); write_thread_local_buffer(_chunkwriter); + _checkpoint_manager.flush(); _repository.flush_chunk(); } // // pre-safepoint write sequence // -// write checkpoint epoch transition list-> -// write stack trace checkpoint -> -// write string pool checkpoint -> -// notify about pending rotation -> -// write storage +// write stack trace checkpoint -> +// write string pool checkpoint -> +// notify about pending rotation -> +// write storage // void JfrRecorderService::pre_safepoint_write() { assert(_chunkwriter.is_valid(), "invariant"); - _checkpoint_manager.write_epoch_transition_mspace(); flush_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); if (_string_pool.modified()) { flush_stringpool_checkpoint(_string_pool, _chunkwriter); } + if (LeakProfiler::is_running()) { + // Exclusive access to the object sampler instance. + // The sampler is released (unlocked) later in post_safepoint_write. + ObjectSampleCheckpoint::rotate(ObjectSampler::acquire(), _stack_trace_repository); + } _checkpoint_manager.notify_types_on_rotation(); _storage.write(); } @@ -658,11 +661,6 @@ VMThread::execute(&safepoint_task); } -static void write_object_sample_stacktrace(JfrStackTraceRepository& stack_trace_repository) { - WriteObjectSampleStacktrace object_sample_stacktrace(stack_trace_repository); - object_sample_stacktrace.process(); -} - // // safepoint write sequence // @@ -676,11 +674,14 @@ // void JfrRecorderService::safepoint_write() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - write_object_sample_stacktrace(_stack_trace_repository); + flush_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); if (_string_pool.modified()) { flush_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); } + if (LeakProfiler::is_running()) { + ObjectSampleCheckpoint::resolve_sampled_objects(); + } _storage.write_at_safepoint(); _checkpoint_manager.notify_threads(); _checkpoint_manager.shift_epoch(); @@ -702,6 +703,11 @@ // already tagged artifacts for the previous epoch. We can accomplish this concurrently // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. _checkpoint_manager.write_type_set(); + if (LeakProfiler::is_running()) { + // The object sampler instance was exclusively acquired and locked in pre_safepoint_write. + // Note: There is a dependency on write_type_set() above, ensure the release is subsequent. + ObjectSampler::release(); + } // serialize any outstanding checkpoint memory _checkpoint_manager.write(); // serialize the metadata descriptor event and close out the chunk @@ -723,7 +729,6 @@ // Do not attempt safepoint dependent operations during emergency dump. // Optimistically write tagged artifacts. _checkpoint_manager.shift_epoch(); - _checkpoint_manager.write_type_set(); // update time _chunkwriter.time_stamp_chunk_now(); post_safepoint_write();