src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54623 1126f0607c70
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    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"
   129   }
   131   }
   130   bool not_acquired() const { return !_acquired; }
   132   bool not_acquired() const { return !_acquired; }
   131 };
   133 };
   132 
   134 
   133 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
   135 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
   134   const int64_t prev_cp_offset = cw.previous_checkpoint_offset();
   136   const int64_t last_cp_offset = cw.last_checkpoint_offset();
   135   const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset();
   137   const int64_t delta_to_last_checkpoint = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset();
   136   cw.reserve(sizeof(u4));
   138   cw.reserve(sizeof(u4));
   137   cw.write<u8>(EVENT_CHECKPOINT);
   139   cw.write<u8>(EVENT_CHECKPOINT);
   138   cw.write(JfrTicks::now());
   140   cw.write(JfrTicks::now());
   139   cw.write((int64_t)0);
   141   cw.write((int64_t)0); // duration
   140   cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta
   142   cw.write(delta_to_last_checkpoint);
   141   cw.write<bool>(false); // flushpoint
   143   cw.write<bool>(false); // flushpoint
   142   cw.write((u4)1); // nof types in this checkpoint
   144   cw.write((u4)1); // nof types in this checkpoint
   143   cw.write(type_id);
   145   cw.write(type_id);
   144   const int64_t number_of_elements_offset = cw.current_offset();
   146   const int64_t number_of_elements_offset = cw.current_offset();
   145   cw.reserve(sizeof(u4));
   147   cw.reserve(sizeof(u4));
   174     assert(number_of_elements > 0, "invariant");
   176     assert(number_of_elements > 0, "invariant");
   175     assert(_cw.current_offset() > num_elements_offset, "invariant");
   177     assert(_cw.current_offset() > num_elements_offset, "invariant");
   176     _cw.write_padded_at_offset<u4>(number_of_elements, num_elements_offset);
   178     _cw.write_padded_at_offset<u4>(number_of_elements, num_elements_offset);
   177     _cw.write_padded_at_offset<u4>((u4)_cw.current_offset() - current_cp_offset, current_cp_offset);
   179     _cw.write_padded_at_offset<u4>((u4)_cw.current_offset() - current_cp_offset, current_cp_offset);
   178     // update writer with last checkpoint position
   180     // update writer with last checkpoint position
   179     _cw.set_previous_checkpoint_offset(current_cp_offset);
   181     _cw.set_last_checkpoint_offset(current_cp_offset);
   180     return true;
   182     return true;
   181   }
   183   }
   182 };
   184 };
   183 
   185 
   184 template <typename Instance, size_t(Instance::*func)()>
   186 template <typename Instance, size_t(Instance::*func)()>
   313   static bool vm_error = false;
   315   static bool vm_error = false;
   314   if (msgs & MSGBIT(MSG_VM_ERROR)) {
   316   if (msgs & MSGBIT(MSG_VM_ERROR)) {
   315     vm_error = true;
   317     vm_error = true;
   316     prepare_for_vm_error_rotation();
   318     prepare_for_vm_error_rotation();
   317   }
   319   }
       
   320   if (!_storage.control().to_disk()) {
       
   321     in_memory_rotation();
       
   322   } else if (vm_error) {
       
   323     vm_error_rotation();
       
   324   } else {
       
   325     chunk_rotation();
       
   326   }
   318   if (msgs & (MSGBIT(MSG_STOP))) {
   327   if (msgs & (MSGBIT(MSG_STOP))) {
   319     stop();
   328     stop();
   320   }
   329   }
   321   // action determined by chunkwriter state
       
   322   if (!_chunkwriter.is_valid()) {
       
   323     in_memory_rotation();
       
   324     return;
       
   325   }
       
   326   if (vm_error) {
       
   327     vm_error_rotation();
       
   328     return;
       
   329   }
       
   330   chunk_rotation();
       
   331 }
   330 }
   332 
   331 
   333 void JfrRecorderService::prepare_for_vm_error_rotation() {
   332 void JfrRecorderService::prepare_for_vm_error_rotation() {
   334   if (!_chunkwriter.is_valid()) {
   333   if (!_chunkwriter.is_valid()) {
   335     open_new_chunk(true);
   334     open_new_chunk(true);
   336   }
   335   }
   337   _checkpoint_manager.register_service_thread(Thread::current());
   336   _checkpoint_manager.register_service_thread(Thread::current());
       
   337   JfrMetadataEvent::lock();
   338 }
   338 }
   339 
   339 
   340 void JfrRecorderService::open_new_chunk(bool vm_error) {
   340 void JfrRecorderService::open_new_chunk(bool vm_error) {
   341   assert(!_chunkwriter.is_valid(), "invariant");
   341   assert(!_chunkwriter.is_valid(), "invariant");
   342   assert(!JfrStream_lock->owned_by_self(), "invariant");
   342   assert(!JfrStream_lock->owned_by_self(), "invariant");
   395 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) {
   395 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) {
   396   WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear);
   396   WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear);
   397   WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo);
   397   WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo);
   398   write_stack_trace_checkpoint.process();
   398   write_stack_trace_checkpoint.process();
   399 }
   399 }
   400 
       
   401 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
   400 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
   402   WriteStringPool write_string_pool(string_pool);
   401   WriteStringPool write_string_pool(string_pool);
   403   WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
   402   WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
   404   write_string_pool_checkpoint.process();
   403   write_string_pool_checkpoint.process();
   405 }
   404 }
   416 //  lock stream lock ->
   415 //  lock stream lock ->
   417 //    write non-safepoint dependent types ->
   416 //    write non-safepoint dependent types ->
   418 //      write checkpoint epoch transition list->
   417 //      write checkpoint epoch transition list->
   419 //        write stack trace checkpoint ->
   418 //        write stack trace checkpoint ->
   420 //          write string pool checkpoint ->
   419 //          write string pool checkpoint ->
   421 //            write storage ->
   420 //            write object sample stacktraces ->
   422 //              release stream lock
   421 //              write storage ->
       
   422 //                release stream lock
   423 //
   423 //
   424 void JfrRecorderService::pre_safepoint_write() {
   424 void JfrRecorderService::pre_safepoint_write() {
   425   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   425   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   426   assert(_chunkwriter.is_valid(), "invariant");
   426   assert(_chunkwriter.is_valid(), "invariant");
   427   _checkpoint_manager.write_types();
   427   _checkpoint_manager.write_types();
   428   _checkpoint_manager.write_epoch_transition_mspace();
   428   _checkpoint_manager.write_epoch_transition_mspace();
   429   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
   429   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
   430   write_stringpool_checkpoint(_string_pool, _chunkwriter);
   430   write_stringpool_checkpoint(_string_pool, _chunkwriter);
       
   431   if (LeakProfiler::is_running()) {
       
   432     // Exclusive access to the object sampler instance.
       
   433     // The sampler is released (unlocked) later in post_safepoint_write.
       
   434     ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository);
       
   435   }
   431   _storage.write();
   436   _storage.write();
   432 }
   437 }
   433 
   438 
   434 void JfrRecorderService::invoke_safepoint_write() {
   439 void JfrRecorderService::invoke_safepoint_write() {
   435   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
   440   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
   436   VMThread::execute(&safepoint_task);
   441   VMThread::execute(&safepoint_task);
   437 }
   442 }
   438 
   443 
   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 //
   444 //
   445 // safepoint write sequence
   445 // safepoint write sequence
   446 //
   446 //
   447 //   lock stream lock ->
   447 //   lock stream lock ->
   448 //     write object sample stacktraces ->
       
   449 //       write stacktrace repository ->
   448 //       write stacktrace repository ->
   450 //         write string pool ->
   449 //         write string pool ->
   451 //           write safepoint dependent types ->
   450 //           write safepoint dependent types ->
   452 //             write storage ->
   451 //             write storage ->
   453 //                 shift_epoch ->
   452 //                 shift_epoch ->
   456 //                       release stream lock
   455 //                       release stream lock
   457 //
   456 //
   458 void JfrRecorderService::safepoint_write() {
   457 void JfrRecorderService::safepoint_write() {
   459   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   458   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   460   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   459   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);
   460   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true);
   463   write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
   461   write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
   464   _checkpoint_manager.write_safepoint_types();
   462   _checkpoint_manager.write_safepoint_types();
   465   _storage.write_at_safepoint();
   463   _storage.write_at_safepoint();
   466   _checkpoint_manager.shift_epoch();
   464   _checkpoint_manager.shift_epoch();
   476 }
   474 }
   477 
   475 
   478 //
   476 //
   479 // post-safepoint write sequence
   477 // post-safepoint write sequence
   480 //
   478 //
   481 //  lock stream lock ->
   479 //   write type set ->
   482 //    write type set ->
   480 //     release object sampler ->
   483 //      write checkpoints ->
   481 //       lock stream lock ->
   484 //        write metadata event ->
   482 //         write checkpoints ->
   485 //          write chunk header ->
   483 //           write metadata event ->
   486 //            close chunk fd ->
   484 //             write chunk header ->
   487 //              release stream lock
   485 //               close chunk fd ->
       
   486 //                 release stream lock
   488 //
   487 //
   489 void JfrRecorderService::post_safepoint_write() {
   488 void JfrRecorderService::post_safepoint_write() {
   490   assert(_chunkwriter.is_valid(), "invariant");
   489   assert(_chunkwriter.is_valid(), "invariant");
   491   // During the safepoint tasks just completed, the system transitioned to a new epoch.
   490   // 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
   491   // 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
   492   // 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.
   493   // 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();
   494   _checkpoint_manager.write_type_set();
       
   495   if (LeakProfiler::is_running()) {
       
   496     // The object sampler instance was exclusively acquired and locked in pre_safepoint_write.
       
   497     // Note: There is a dependency on write_type_set() above, ensure the release is subsequent.
       
   498     ObjectSampler::release();
       
   499   }
   496   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   500   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   497   // serialize any outstanding checkpoint memory
   501   // serialize any outstanding checkpoint memory
   498   _checkpoint_manager.write();
   502   _checkpoint_manager.write();
   499   // serialize the metadata descriptor event and close out the chunk
   503   // serialize the metadata descriptor event and close out the chunk
   500   _repository.close_chunk(write_metadata_event(_chunkwriter));
   504   _repository.close_chunk(write_metadata_event(_chunkwriter));
   510 }
   514 }
   511 
   515 
   512 void JfrRecorderService::finalize_current_chunk_on_vm_error() {
   516 void JfrRecorderService::finalize_current_chunk_on_vm_error() {
   513   assert(_chunkwriter.is_valid(), "invariant");
   517   assert(_chunkwriter.is_valid(), "invariant");
   514   pre_safepoint_write();
   518   pre_safepoint_write();
   515   JfrMetadataEvent::lock();
       
   516   // Do not attempt safepoint dependent operations during emergency dump.
   519   // Do not attempt safepoint dependent operations during emergency dump.
   517   // Optimistically write tagged artifacts.
   520   // Optimistically write tagged artifacts.
   518   _checkpoint_manager.shift_epoch();
   521   _checkpoint_manager.shift_epoch();
   519   _checkpoint_manager.write_type_set();
       
   520   // update time
   522   // update time
   521   _chunkwriter.time_stamp_chunk_now();
   523   _chunkwriter.time_stamp_chunk_now();
   522   post_safepoint_write();
   524   post_safepoint_write();
   523   assert(!_chunkwriter.is_valid(), "invariant");
   525   assert(!_chunkwriter.is_valid(), "invariant");
   524 }
   526 }