src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
changeset 58863 c16ac7a2eba4
parent 58132 caa25ab47aca
child 59226 a0f39cc47387
equal deleted inserted replaced
58861:2c3cc4b01880 58863:c16ac7a2eba4
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "jfrfiles/jfrEventClasses.hpp"
    26 #include "jfr/jni/jfrJavaSupport.hpp"
    27 #include "jfr/jni/jfrJavaSupport.hpp"
    27 #include "jfr/leakprofiler/leakProfiler.hpp"
    28 #include "jfr/leakprofiler/leakProfiler.hpp"
    28 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
    29 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
    29 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    30 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    30 #include "jfr/recorder/jfrRecorder.hpp"
    31 #include "jfr/recorder/jfrRecorder.hpp"
    53 #include "runtime/safepoint.hpp"
    54 #include "runtime/safepoint.hpp"
    54 #include "runtime/thread.inline.hpp"
    55 #include "runtime/thread.inline.hpp"
    55 #include "runtime/vmOperations.hpp"
    56 #include "runtime/vmOperations.hpp"
    56 #include "runtime/vmThread.hpp"
    57 #include "runtime/vmThread.hpp"
    57 
    58 
    58 // set data iff *dest == NULL
    59 // incremented on each flushpoint
    59 static bool try_set(void* const data, void** dest, bool clear) {
    60 static u8 flushpoint_id = 0;
    60   assert(data != NULL, "invariant");
    61 
    61   const void* const current = OrderAccess::load_acquire(dest);
    62 template <typename E, typename Instance, size_t(Instance::*func)()>
    62   if (current != NULL) {
    63 class Content {
    63     if (current != data) {
       
    64       // already set
       
    65       return false;
       
    66     }
       
    67     assert(current == data, "invariant");
       
    68     if (!clear) {
       
    69       // recursion disallowed
       
    70       return false;
       
    71     }
       
    72   }
       
    73   return Atomic::cmpxchg(clear ? NULL : data, dest, current) == current;
       
    74 }
       
    75 
       
    76 static void* rotation_thread = NULL;
       
    77 static const int rotation_try_limit = 1000;
       
    78 static const int rotation_retry_sleep_millis = 10;
       
    79 
       
    80 class RotationLock : public StackObj {
       
    81  private:
    64  private:
    82   Thread* const _thread;
    65   Instance& _instance;
    83   bool _acquired;
    66   u4 _elements;
    84 
       
    85   void log(bool recursion) {
       
    86     assert(!_acquired, "invariant");
       
    87     const char* error_msg = NULL;
       
    88     if (recursion) {
       
    89       error_msg = "Unable to issue rotation due to recursive calls.";
       
    90     }
       
    91     else {
       
    92       error_msg = "Unable to issue rotation due to wait timeout.";
       
    93     }
       
    94     log_info(jfr)( // For user, should not be "jfr, system"
       
    95       "%s", error_msg);
       
    96   }
       
    97  public:
    67  public:
    98   RotationLock(Thread* thread) : _thread(thread), _acquired(false) {
    68   typedef E EventType;
    99     assert(_thread != NULL, "invariant");
    69   Content(Instance& instance) : _instance(instance), _elements(0) {}
   100     if (_thread == rotation_thread) {
    70   bool process() {
   101       // recursion not supported
    71     _elements = (u4)(_instance.*func)();
   102       log(true);
    72     return true;
   103       return;
    73   }
   104     }
    74   u4 elements() const { return _elements; }
   105 
    75 };
   106     // limited to not spin indefinitely
    76 
   107     for (int i = 0; i < rotation_try_limit; ++i) {
    77 template <typename Content>
   108       if (try_set(_thread, &rotation_thread, false)) {
    78 class WriteContent : public StackObj {
   109         _acquired = true;
    79  protected:
   110         assert(_thread == rotation_thread, "invariant");
    80   const JfrTicks _start_time;
   111         return;
    81   JfrTicks _end_time;
   112       }
    82   JfrChunkWriter& _cw;
   113       if (_thread->is_Java_thread()) {
    83   Content& _content;
   114         // in order to allow the system to move to a safepoint
    84   const int64_t _start_offset;
   115         MutexLocker msg_lock(JfrMsg_lock);
    85  public:
   116         JfrMsg_lock->wait(rotation_retry_sleep_millis);
    86   typedef typename Content::EventType EventType;
   117       }
    87 
   118       else {
    88   WriteContent(JfrChunkWriter& cw, Content& content) :
   119         os::naked_short_sleep(rotation_retry_sleep_millis);
    89     _start_time(JfrTicks::now()),
   120       }
    90     _end_time(),
   121     }
    91     _cw(cw),
   122     log(false);
    92     _content(content),
   123   }
    93     _start_offset(_cw.current_offset()) {
   124 
    94     assert(_cw.is_valid(), "invariant");
   125   ~RotationLock() {
    95   }
   126     assert(_thread != NULL, "invariant");
    96 
   127     if (_acquired) {
    97   bool process() {
   128       assert(_thread == rotation_thread, "invariant");
    98     // invocation
   129       while (!try_set(_thread, &rotation_thread, true));
    99     _content.process();
   130     }
   100     _end_time = JfrTicks::now();
   131   }
   101     return 0 != _content.elements();
   132   bool not_acquired() const { return !_acquired; }
   102   }
       
   103 
       
   104   const JfrTicks& start_time() const {
       
   105     return _start_time;
       
   106   }
       
   107 
       
   108   const JfrTicks& end_time() const {
       
   109     return _end_time;
       
   110   }
       
   111 
       
   112   int64_t start_offset() const {
       
   113     return _start_offset;
       
   114   }
       
   115 
       
   116   int64_t end_offset() const {
       
   117     return current_offset();
       
   118   }
       
   119 
       
   120   int64_t current_offset() const {
       
   121     return _cw.current_offset();
       
   122   }
       
   123 
       
   124   u4 elements() const {
       
   125     return (u4) _content.elements();
       
   126   }
       
   127 
       
   128   u4 size() const {
       
   129     return (u4)(end_offset() - start_offset());
       
   130   }
       
   131 
       
   132   static bool is_event_enabled() {
       
   133     return EventType::is_enabled();
       
   134   }
       
   135 
       
   136   static u8 event_id() {
       
   137     return EventType::eventId;
       
   138   }
       
   139 
       
   140   void write_elements(int64_t offset) {
       
   141     _cw.write_padded_at_offset<u4>(elements(), offset);
       
   142   }
       
   143 
       
   144   void write_size() {
       
   145     _cw.write_padded_at_offset<u4>(size(), start_offset());
       
   146   }
       
   147 
       
   148   void set_last_checkpoint() {
       
   149     _cw.set_last_checkpoint_offset(start_offset());
       
   150   }
       
   151 
       
   152   void rewind() {
       
   153     _cw.seek(start_offset());
       
   154   }
   133 };
   155 };
   134 
   156 
   135 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
   157 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
   136   const int64_t last_cp_offset = cw.last_checkpoint_offset();
   158   const int64_t last_cp_offset = cw.last_checkpoint_offset();
   137   const int64_t delta_to_last_checkpoint = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset();
   159   const int64_t delta_to_last_checkpoint = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset();
   138   cw.reserve(sizeof(u4));
   160   cw.reserve(sizeof(u4));
   139   cw.write<u8>(EVENT_CHECKPOINT);
   161   cw.write<u8>(EVENT_CHECKPOINT);
   140   cw.write(JfrTicks::now());
   162   cw.write(JfrTicks::now());
   141   cw.write((int64_t)0); // duration
   163   cw.write<u8>(0); // duration
   142   cw.write(delta_to_last_checkpoint);
   164   cw.write(delta_to_last_checkpoint);
   143   cw.write<bool>(false); // flushpoint
   165   cw.write<u4>(GENERIC); // checkpoint type
   144   cw.write((u4)1); // nof types in this checkpoint
   166   cw.write<u4>(1); // nof types in this checkpoint
   145   cw.write(type_id);
   167   cw.write(type_id);
   146   const int64_t number_of_elements_offset = cw.current_offset();
   168   return cw.reserve(sizeof(u4));
   147   cw.reserve(sizeof(u4));
   169 }
   148   return number_of_elements_offset;
   170 
   149 }
   171 template <typename Content>
   150 
   172 class WriteCheckpointEvent : public WriteContent<Content> {
   151 template <typename ContentFunctor>
   173  private:
   152 class WriteCheckpointEvent : public StackObj {
   174   const u8 _type_id;
       
   175  public:
       
   176   WriteCheckpointEvent(JfrChunkWriter& cw, Content& content, u8 type_id) :
       
   177     WriteContent<Content>(cw, content), _type_id(type_id) {}
       
   178 
       
   179   bool process() {
       
   180     const int64_t num_elements_offset = write_checkpoint_event_prologue(this->_cw, _type_id);
       
   181     if (!WriteContent<Content>::process()) {
       
   182       // nothing to do, rewind writer to start
       
   183       this->rewind();
       
   184       assert(this->current_offset() == this->start_offset(), "invariant");
       
   185       return false;
       
   186     }
       
   187     assert(this->elements() > 0, "invariant");
       
   188     assert(this->current_offset() > num_elements_offset, "invariant");
       
   189     this->write_elements(num_elements_offset);
       
   190     this->write_size();
       
   191     this->set_last_checkpoint();
       
   192     return true;
       
   193   }
       
   194 };
       
   195 
       
   196 template <typename Functor>
       
   197 static u4 invoke(Functor& f) {
       
   198   f.process();
       
   199   return f.elements();
       
   200 }
       
   201 
       
   202 template <typename Functor>
       
   203 static void write_flush_event(Functor& f) {
       
   204   if (Functor::is_event_enabled()) {
       
   205     typename Functor::EventType e(UNTIMED);
       
   206     e.set_starttime(f.start_time());
       
   207     e.set_endtime(f.end_time());
       
   208     e.set_flushId(flushpoint_id);
       
   209     e.set_elements(f.elements());
       
   210     e.set_size(f.size());
       
   211     e.commit();
       
   212   }
       
   213 }
       
   214 
       
   215 template <typename Functor>
       
   216 static u4 invoke_with_flush_event(Functor& f) {
       
   217   const u4 elements = invoke(f);
       
   218   write_flush_event(f);
       
   219   return elements;
       
   220 }
       
   221 
       
   222 class StackTraceRepository : public StackObj {
       
   223  private:
       
   224   JfrStackTraceRepository& _repo;
       
   225   JfrChunkWriter& _cw;
       
   226   size_t _elements;
       
   227   bool _clear;
       
   228 
       
   229  public:
       
   230   typedef EventFlushStacktrace EventType;
       
   231   StackTraceRepository(JfrStackTraceRepository& repo, JfrChunkWriter& cw, bool clear) :
       
   232     _repo(repo), _cw(cw), _elements(0), _clear(clear) {}
       
   233   bool process() {
       
   234     _elements = _repo.write(_cw, _clear);
       
   235     return true;
       
   236   }
       
   237   size_t elements() const { return _elements; }
       
   238   void reset() { _elements = 0; }
       
   239 };
       
   240 
       
   241 typedef WriteCheckpointEvent<StackTraceRepository> WriteStackTrace;
       
   242 
       
   243 static u4 flush_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter) {
       
   244   StackTraceRepository str(stack_trace_repo, chunkwriter, false);
       
   245   WriteStackTrace wst(chunkwriter, str, TYPE_STACKTRACE);
       
   246   return invoke_with_flush_event(wst);
       
   247 }
       
   248 
       
   249 static u4 write_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) {
       
   250   StackTraceRepository str(stack_trace_repo, chunkwriter, clear);
       
   251   WriteStackTrace wst(chunkwriter, str, TYPE_STACKTRACE);
       
   252   return invoke(wst);
       
   253 }
       
   254 
       
   255 typedef Content<EventFlushStorage, JfrStorage, &JfrStorage::write> Storage;
       
   256 typedef WriteContent<Storage> WriteStorage;
       
   257 
       
   258 static size_t flush_storage(JfrStorage& storage, JfrChunkWriter& chunkwriter) {
       
   259   assert(chunkwriter.is_valid(), "invariant");
       
   260   Storage fsf(storage);
       
   261   WriteStorage fs(chunkwriter, fsf);
       
   262   return invoke_with_flush_event(fs);
       
   263 }
       
   264 
       
   265 static size_t write_storage(JfrStorage& storage, JfrChunkWriter& chunkwriter) {
       
   266   assert(chunkwriter.is_valid(), "invariant");
       
   267   Storage fsf(storage);
       
   268   WriteStorage fs(chunkwriter, fsf);
       
   269   return invoke(fs);
       
   270 }
       
   271 
       
   272 typedef Content<EventFlushStringPool, JfrStringPool, &JfrStringPool::write> StringPool;
       
   273 typedef Content<EventFlushStringPool, JfrStringPool, &JfrStringPool::write_at_safepoint> StringPoolSafepoint;
       
   274 typedef WriteCheckpointEvent<StringPool> WriteStringPool;
       
   275 typedef WriteCheckpointEvent<StringPoolSafepoint> WriteStringPoolSafepoint;
       
   276 
       
   277 static u4 flush_stringpool(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
       
   278   StringPool sp(string_pool);
       
   279   WriteStringPool wsp(chunkwriter, sp, TYPE_STRING);
       
   280   return invoke_with_flush_event(wsp);
       
   281 }
       
   282 
       
   283 static u4 write_stringpool(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
       
   284   StringPool sp(string_pool);
       
   285   WriteStringPool wsp(chunkwriter, sp, TYPE_STRING);
       
   286   return invoke(wsp);
       
   287 }
       
   288 
       
   289 static u4 write_stringpool_safepoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
       
   290   StringPoolSafepoint sps(string_pool);
       
   291   WriteStringPoolSafepoint wsps(chunkwriter, sps, TYPE_STRING);
       
   292   return invoke(wsps);
       
   293 }
       
   294 
       
   295 typedef Content<EventFlushTypeSet, JfrCheckpointManager, &JfrCheckpointManager::flush_type_set> FlushTypeSetFunctor;
       
   296 typedef WriteContent<FlushTypeSetFunctor> FlushTypeSet;
       
   297 
       
   298 static u4 flush_typeset(JfrCheckpointManager& checkpoint_manager, JfrChunkWriter& chunkwriter) {
       
   299   FlushTypeSetFunctor flush_type_set(checkpoint_manager);
       
   300   FlushTypeSet fts(chunkwriter, flush_type_set);
       
   301   return invoke_with_flush_event(fts);
       
   302 }
       
   303 
       
   304 class MetadataEvent : public StackObj {
   153  private:
   305  private:
   154   JfrChunkWriter& _cw;
   306   JfrChunkWriter& _cw;
   155   u8 _type_id;
       
   156   ContentFunctor& _content_functor;
       
   157  public:
   307  public:
   158   WriteCheckpointEvent(JfrChunkWriter& cw, u8 type_id, ContentFunctor& functor) :
   308   typedef EventFlushMetadata EventType;
   159     _cw(cw),
   309   MetadataEvent(JfrChunkWriter& cw) : _cw(cw) {}
   160     _type_id(type_id),
       
   161     _content_functor(functor) {
       
   162     assert(_cw.is_valid(), "invariant");
       
   163   }
       
   164   bool process() {
   310   bool process() {
   165     // current_cp_offset is also offset for the event size header field
   311     JfrMetadataEvent::write(_cw);
   166     const int64_t current_cp_offset = _cw.current_offset();
       
   167     const int64_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id);
       
   168     // invocation
       
   169     _content_functor.process();
       
   170     const u4 number_of_elements = (u4)_content_functor.processed();
       
   171     if (number_of_elements == 0) {
       
   172       // nothing to do, rewind writer to start
       
   173       _cw.seek(current_cp_offset);
       
   174       return true;
       
   175     }
       
   176     assert(number_of_elements > 0, "invariant");
       
   177     assert(_cw.current_offset() > num_elements_offset, "invariant");
       
   178     _cw.write_padded_at_offset<u4>(number_of_elements, num_elements_offset);
       
   179     _cw.write_padded_at_offset<u4>((u4)_cw.current_offset() - current_cp_offset, current_cp_offset);
       
   180     // update writer with last checkpoint position
       
   181     _cw.set_last_checkpoint_offset(current_cp_offset);
       
   182     return true;
   312     return true;
   183   }
   313   }
       
   314   size_t elements() const { return 1; }
   184 };
   315 };
   185 
   316 
   186 template <typename Instance, size_t(Instance::*func)()>
   317 typedef WriteContent<MetadataEvent> WriteMetadata;
   187 class ServiceFunctor {
   318 
   188  private:
   319 static u4 flush_metadata(JfrChunkWriter& chunkwriter) {
   189   Instance& _instance;
   320   assert(chunkwriter.is_valid(), "invariant");
   190   size_t _processed;
   321   MetadataEvent me(chunkwriter);
   191  public:
   322   WriteMetadata wm(chunkwriter, me);
   192   ServiceFunctor(Instance& instance) : _instance(instance), _processed(0) {}
   323   return invoke_with_flush_event(wm);
   193   bool process() {
   324 }
   194     _processed = (_instance.*func)();
   325 
   195     return true;
   326 static u4 write_metadata(JfrChunkWriter& chunkwriter) {
   196   }
   327   assert(chunkwriter.is_valid(), "invariant");
   197   size_t processed() const { return _processed; }
   328   MetadataEvent me(chunkwriter);
   198 };
   329   WriteMetadata wm(chunkwriter, me);
       
   330   return invoke(wm);
       
   331 }
   199 
   332 
   200 template <typename Instance, void(Instance::*func)()>
   333 template <typename Instance, void(Instance::*func)()>
   201 class JfrVMOperation : public VM_Operation {
   334 class JfrVMOperation : public VM_Operation {
   202  private:
   335  private:
   203   Instance& _instance;
   336   Instance& _instance;
   206   void doit() { (_instance.*func)(); }
   339   void doit() { (_instance.*func)(); }
   207   VMOp_Type type() const { return VMOp_JFRCheckpoint; }
   340   VMOp_Type type() const { return VMOp_JFRCheckpoint; }
   208   Mode evaluation_mode() const { return _safepoint; } // default
   341   Mode evaluation_mode() const { return _safepoint; } // default
   209 };
   342 };
   210 
   343 
   211 class WriteStackTraceRepository : public StackObj {
       
   212  private:
       
   213   JfrStackTraceRepository& _repo;
       
   214   JfrChunkWriter& _cw;
       
   215   size_t _elements_processed;
       
   216   bool _clear;
       
   217 
       
   218  public:
       
   219   WriteStackTraceRepository(JfrStackTraceRepository& repo, JfrChunkWriter& cw, bool clear) :
       
   220     _repo(repo), _cw(cw), _elements_processed(0), _clear(clear) {}
       
   221   bool process() {
       
   222     _elements_processed = _repo.write(_cw, _clear);
       
   223     return true;
       
   224   }
       
   225   size_t processed() const { return _elements_processed; }
       
   226   void reset() { _elements_processed = 0; }
       
   227 };
       
   228 
       
   229 static bool recording = false;
       
   230 
       
   231 static void set_recording_state(bool is_recording) {
       
   232   OrderAccess::storestore();
       
   233   recording = is_recording;
       
   234 }
       
   235 
       
   236 bool JfrRecorderService::is_recording() {
       
   237   return recording;
       
   238 }
       
   239 
       
   240 JfrRecorderService::JfrRecorderService() :
   344 JfrRecorderService::JfrRecorderService() :
   241   _checkpoint_manager(JfrCheckpointManager::instance()),
   345   _checkpoint_manager(JfrCheckpointManager::instance()),
   242   _chunkwriter(JfrRepository::chunkwriter()),
   346   _chunkwriter(JfrRepository::chunkwriter()),
   243   _repository(JfrRepository::instance()),
   347   _repository(JfrRepository::instance()),
   244   _stack_trace_repository(JfrStackTraceRepository::instance()),
   348   _stack_trace_repository(JfrStackTraceRepository::instance()),
   245   _storage(JfrStorage::instance()),
   349   _storage(JfrStorage::instance()),
   246   _string_pool(JfrStringPool::instance()) {}
   350   _string_pool(JfrStringPool::instance()) {}
   247 
   351 
       
   352 static bool recording = false;
       
   353 
       
   354 static void set_recording_state(bool is_recording) {
       
   355   OrderAccess::storestore();
       
   356   recording = is_recording;
       
   357 }
       
   358 
       
   359 bool JfrRecorderService::is_recording() {
       
   360   return recording;
       
   361 }
       
   362 
   248 void JfrRecorderService::start() {
   363 void JfrRecorderService::start() {
   249   RotationLock rl(Thread::current());
   364   MutexLocker lock(JfrStream_lock);
   250   if (rl.not_acquired()) {
       
   251     return;
       
   252   }
       
   253   log_debug(jfr, system)("Request to START recording");
   365   log_debug(jfr, system)("Request to START recording");
   254   assert(!is_recording(), "invariant");
   366   assert(!is_recording(), "invariant");
   255   clear();
   367   clear();
   256   set_recording_state(true);
   368   set_recording_state(true);
   257   assert(is_recording(), "invariant");
   369   assert(is_recording(), "invariant");
   266   invoke_safepoint_clear();
   378   invoke_safepoint_clear();
   267   post_safepoint_clear();
   379   post_safepoint_clear();
   268 }
   380 }
   269 
   381 
   270 void JfrRecorderService::pre_safepoint_clear() {
   382 void JfrRecorderService::pre_safepoint_clear() {
   271   _stack_trace_repository.clear();
       
   272   _string_pool.clear();
   383   _string_pool.clear();
   273   _storage.clear();
   384   _storage.clear();
       
   385   _stack_trace_repository.clear();
   274 }
   386 }
   275 
   387 
   276 void JfrRecorderService::invoke_safepoint_clear() {
   388 void JfrRecorderService::invoke_safepoint_clear() {
   277   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_clear> safepoint_task(*this);
   389   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_clear> safepoint_task(*this);
   278   VMThread::execute(&safepoint_task);
   390   VMThread::execute(&safepoint_task);
   279 }
   391 }
   280 
   392 
   281 //
       
   282 // safepoint clear sequence
       
   283 //
       
   284 //  clear stacktrace repository ->
       
   285 //    clear string pool ->
       
   286 //      clear storage ->
       
   287 //        shift epoch ->
       
   288 //          update time
       
   289 //
       
   290 void JfrRecorderService::safepoint_clear() {
   393 void JfrRecorderService::safepoint_clear() {
   291   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   394   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   292   _stack_trace_repository.clear();
       
   293   _string_pool.clear();
   395   _string_pool.clear();
   294   _storage.clear();
   396   _storage.clear();
   295   _checkpoint_manager.shift_epoch();
   397   _checkpoint_manager.shift_epoch();
   296   _chunkwriter.time_stamp_chunk_now();
   398   _chunkwriter.set_time_stamp();
       
   399   _stack_trace_repository.clear();
   297 }
   400 }
   298 
   401 
   299 void JfrRecorderService::post_safepoint_clear() {
   402 void JfrRecorderService::post_safepoint_clear() {
   300   _checkpoint_manager.clear();
   403   _checkpoint_manager.clear();
       
   404 }
       
   405 
       
   406 void JfrRecorderService::open_new_chunk(bool vm_error) {
       
   407   JfrChunkRotation::on_rotation();
       
   408   const bool valid_chunk = _repository.open_chunk(vm_error);
       
   409   _storage.control().set_to_disk(valid_chunk);
       
   410   if (valid_chunk) {
       
   411     _checkpoint_manager.write_static_type_set_and_threads();
       
   412   }
   301 }
   413 }
   302 
   414 
   303 static void stop() {
   415 static void stop() {
   304   assert(JfrRecorderService::is_recording(), "invariant");
   416   assert(JfrRecorderService::is_recording(), "invariant");
   305   log_debug(jfr, system)("Recording STOPPED");
   417   log_debug(jfr, system)("Recording STOPPED");
   306   set_recording_state(false);
   418   set_recording_state(false);
   307   assert(!JfrRecorderService::is_recording(), "invariant");
   419   assert(!JfrRecorderService::is_recording(), "invariant");
   308 }
   420 }
   309 
   421 
       
   422 void JfrRecorderService::prepare_for_vm_error_rotation() {
       
   423   assert(JfrStream_lock->owned_by_self(), "invariant");
       
   424   if (!_chunkwriter.is_valid()) {
       
   425     open_new_chunk(true);
       
   426   }
       
   427   _checkpoint_manager.register_service_thread(Thread::current());
       
   428 }
       
   429 
       
   430 void JfrRecorderService::vm_error_rotation() {
       
   431   assert(JfrStream_lock->owned_by_self(), "invariant");
       
   432   if (_chunkwriter.is_valid()) {
       
   433     Thread* const t = Thread::current();
       
   434     _storage.flush_regular_buffer(t->jfr_thread_local()->native_buffer(), t);
       
   435     invoke_flush();
       
   436     _chunkwriter.set_time_stamp();
       
   437     _repository.close_chunk();
       
   438     assert(!_chunkwriter.is_valid(), "invariant");
       
   439     _repository.on_vm_error();
       
   440   }
       
   441 }
       
   442 
   310 void JfrRecorderService::rotate(int msgs) {
   443 void JfrRecorderService::rotate(int msgs) {
   311   RotationLock rl(Thread::current());
   444   assert(!JfrStream_lock->owned_by_self(), "invariant");
   312   if (rl.not_acquired()) {
   445   MutexLocker lock(JfrStream_lock);
   313     return;
       
   314   }
       
   315   static bool vm_error = false;
   446   static bool vm_error = false;
   316   if (msgs & MSGBIT(MSG_VM_ERROR)) {
   447   if (msgs & MSGBIT(MSG_VM_ERROR)) {
   317     vm_error = true;
   448     vm_error = true;
   318     prepare_for_vm_error_rotation();
   449     prepare_for_vm_error_rotation();
   319   }
   450   }
   327   if (msgs & (MSGBIT(MSG_STOP))) {
   458   if (msgs & (MSGBIT(MSG_STOP))) {
   328     stop();
   459     stop();
   329   }
   460   }
   330 }
   461 }
   331 
   462 
   332 void JfrRecorderService::prepare_for_vm_error_rotation() {
       
   333   if (!_chunkwriter.is_valid()) {
       
   334     open_new_chunk(true);
       
   335   }
       
   336   _checkpoint_manager.register_service_thread(Thread::current());
       
   337   JfrMetadataEvent::lock();
       
   338 }
       
   339 
       
   340 void JfrRecorderService::open_new_chunk(bool vm_error) {
       
   341   assert(!_chunkwriter.is_valid(), "invariant");
       
   342   assert(!JfrStream_lock->owned_by_self(), "invariant");
       
   343   JfrChunkRotation::on_rotation();
       
   344   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
       
   345   if (!_repository.open_chunk(vm_error)) {
       
   346     assert(!_chunkwriter.is_valid(), "invariant");
       
   347     _storage.control().set_to_disk(false);
       
   348     return;
       
   349   }
       
   350   assert(_chunkwriter.is_valid(), "invariant");
       
   351   _storage.control().set_to_disk(true);
       
   352 }
       
   353 
       
   354 void JfrRecorderService::in_memory_rotation() {
   463 void JfrRecorderService::in_memory_rotation() {
   355   assert(!_chunkwriter.is_valid(), "invariant");
   464   assert(JfrStream_lock->owned_by_self(), "invariant");
   356   // currently running an in-memory recording
   465   // currently running an in-memory recording
       
   466   assert(!_storage.control().to_disk(), "invariant");
   357   open_new_chunk();
   467   open_new_chunk();
   358   if (_chunkwriter.is_valid()) {
   468   if (_chunkwriter.is_valid()) {
   359     // dump all in-memory buffer data to the newly created chunk
   469     // dump all in-memory buffer data to the newly created chunk
   360     serialize_storage_from_in_memory_recording();
   470     write_storage(_storage, _chunkwriter);
   361   }
   471   }
   362 }
       
   363 
       
   364 void JfrRecorderService::serialize_storage_from_in_memory_recording() {
       
   365   assert(!JfrStream_lock->owned_by_self(), "not holding stream lock!");
       
   366   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
       
   367   _storage.write();
       
   368 }
   472 }
   369 
   473 
   370 void JfrRecorderService::chunk_rotation() {
   474 void JfrRecorderService::chunk_rotation() {
       
   475   assert(JfrStream_lock->owned_by_self(), "invariant");
   371   finalize_current_chunk();
   476   finalize_current_chunk();
   372   open_new_chunk();
   477   open_new_chunk();
   373 }
   478 }
   374 
   479 
   375 void JfrRecorderService::finalize_current_chunk() {
   480 void JfrRecorderService::finalize_current_chunk() {
   376   assert(_chunkwriter.is_valid(), "invariant");
   481   assert(_chunkwriter.is_valid(), "invariant");
   377   write();
   482   write();
   378   assert(!_chunkwriter.is_valid(), "invariant");
       
   379 }
   483 }
   380 
   484 
   381 void JfrRecorderService::write() {
   485 void JfrRecorderService::write() {
   382   ResourceMark rm;
   486   ResourceMark rm;
   383   HandleMark hm;
   487   HandleMark hm;
   384   pre_safepoint_write();
   488   pre_safepoint_write();
   385   invoke_safepoint_write();
   489   invoke_safepoint_write();
   386   post_safepoint_write();
   490   post_safepoint_write();
   387 }
   491 }
   388 
   492 
   389 typedef ServiceFunctor<JfrStringPool, &JfrStringPool::write> WriteStringPool;
       
   390 typedef ServiceFunctor<JfrStringPool, &JfrStringPool::write_at_safepoint> WriteStringPoolSafepoint;
       
   391 typedef WriteCheckpointEvent<WriteStackTraceRepository> WriteStackTraceCheckpoint;
       
   392 typedef WriteCheckpointEvent<WriteStringPool> WriteStringPoolCheckpoint;
       
   393 typedef WriteCheckpointEvent<WriteStringPoolSafepoint> WriteStringPoolCheckpointSafepoint;
       
   394 
       
   395 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) {
       
   396   WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear);
       
   397   WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo);
       
   398   write_stack_trace_checkpoint.process();
       
   399 }
       
   400 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
       
   401   WriteStringPool write_string_pool(string_pool);
       
   402   WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
       
   403   write_string_pool_checkpoint.process();
       
   404 }
       
   405 
       
   406 static void write_stringpool_checkpoint_safepoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) {
       
   407   WriteStringPoolSafepoint write_string_pool(string_pool);
       
   408   WriteStringPoolCheckpointSafepoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool);
       
   409   write_string_pool_checkpoint.process();
       
   410 }
       
   411 
       
   412 //
       
   413 // pre-safepoint write sequence
       
   414 //
       
   415 //  lock stream lock ->
       
   416 //    write non-safepoint dependent types ->
       
   417 //      write checkpoint epoch transition list->
       
   418 //        write stack trace checkpoint ->
       
   419 //          write string pool checkpoint ->
       
   420 //            write object sample stacktraces ->
       
   421 //              write storage ->
       
   422 //                release stream lock
       
   423 //
       
   424 void JfrRecorderService::pre_safepoint_write() {
   493 void JfrRecorderService::pre_safepoint_write() {
   425   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
       
   426   assert(_chunkwriter.is_valid(), "invariant");
   494   assert(_chunkwriter.is_valid(), "invariant");
   427   _checkpoint_manager.write_types();
       
   428   _checkpoint_manager.write_epoch_transition_mspace();
       
   429   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
       
   430   write_stringpool_checkpoint(_string_pool, _chunkwriter);
       
   431   if (LeakProfiler::is_running()) {
   495   if (LeakProfiler::is_running()) {
   432     // Exclusive access to the object sampler instance.
   496     // Exclusive access to the object sampler instance.
   433     // The sampler is released (unlocked) later in post_safepoint_write.
   497     // The sampler is released (unlocked) later in post_safepoint_write.
   434     ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository);
   498     ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository);
   435   }
   499   }
   436   _storage.write();
   500   if (_string_pool.is_modified()) {
       
   501     write_stringpool(_string_pool, _chunkwriter);
       
   502   }
       
   503   write_storage(_storage, _chunkwriter);
       
   504   if (_stack_trace_repository.is_modified()) {
       
   505     write_stacktrace(_stack_trace_repository, _chunkwriter, false);
       
   506   }
   437 }
   507 }
   438 
   508 
   439 void JfrRecorderService::invoke_safepoint_write() {
   509 void JfrRecorderService::invoke_safepoint_write() {
   440   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
   510   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
   441   VMThread::execute(&safepoint_task);
   511   VMThread::execute(&safepoint_task);
   442 }
   512 }
   443 
   513 
   444 //
       
   445 // safepoint write sequence
       
   446 //
       
   447 //   lock stream lock ->
       
   448 //       write stacktrace repository ->
       
   449 //         write string pool ->
       
   450 //           write safepoint dependent types ->
       
   451 //             write storage ->
       
   452 //                 shift_epoch ->
       
   453 //                   update time ->
       
   454 //                     lock metadata descriptor ->
       
   455 //                       release stream lock
       
   456 //
       
   457 void JfrRecorderService::safepoint_write() {
   514 void JfrRecorderService::safepoint_write() {
   458   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   515   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   459   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
   516   if (_string_pool.is_modified()) {
   460   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true);
   517     write_stringpool_safepoint(_string_pool, _chunkwriter);
   461   write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
   518   }
   462   _checkpoint_manager.write_safepoint_types();
   519   _checkpoint_manager.on_rotation();
   463   _storage.write_at_safepoint();
   520   _storage.write_at_safepoint();
   464   _checkpoint_manager.shift_epoch();
   521   _checkpoint_manager.shift_epoch();
   465   _chunkwriter.time_stamp_chunk_now();
   522   _chunkwriter.set_time_stamp();
   466   JfrMetadataEvent::lock();
   523   write_stacktrace(_stack_trace_repository, _chunkwriter, true);
   467 }
   524 }
   468 
   525 
   469 static int64_t write_metadata_event(JfrChunkWriter& chunkwriter) {
       
   470   assert(chunkwriter.is_valid(), "invariant");
       
   471   const int64_t metadata_offset = chunkwriter.current_offset();
       
   472   JfrMetadataEvent::write(chunkwriter, metadata_offset);
       
   473   return metadata_offset;
       
   474 }
       
   475 
       
   476 //
       
   477 // post-safepoint write sequence
       
   478 //
       
   479 //   write type set ->
       
   480 //     release object sampler ->
       
   481 //       lock stream lock ->
       
   482 //         write checkpoints ->
       
   483 //           write metadata event ->
       
   484 //             write chunk header ->
       
   485 //               close chunk fd ->
       
   486 //                 release stream lock
       
   487 //
       
   488 void JfrRecorderService::post_safepoint_write() {
   526 void JfrRecorderService::post_safepoint_write() {
   489   assert(_chunkwriter.is_valid(), "invariant");
   527   assert(_chunkwriter.is_valid(), "invariant");
   490   // During the safepoint tasks just completed, the system transitioned to a new epoch.
   528   // During the safepoint tasks just completed, the system transitioned to a new epoch.
   491   // Type tagging is epoch relative which entails we are able to write out the
   529   // Type tagging is epoch relative which entails we are able to write out the
   492   // already tagged artifacts for the previous epoch. We can accomplish this concurrently
   530   // already tagged artifacts for the previous epoch. We can accomplish this concurrently
   495   if (LeakProfiler::is_running()) {
   533   if (LeakProfiler::is_running()) {
   496     // The object sampler instance was exclusively acquired and locked in pre_safepoint_write.
   534     // 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.
   535     // Note: There is a dependency on write_type_set() above, ensure the release is subsequent.
   498     ObjectSampler::release();
   536     ObjectSampler::release();
   499   }
   537   }
   500   MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
       
   501   // serialize any outstanding checkpoint memory
       
   502   _checkpoint_manager.write();
       
   503   // serialize the metadata descriptor event and close out the chunk
   538   // serialize the metadata descriptor event and close out the chunk
   504   _repository.close_chunk(write_metadata_event(_chunkwriter));
   539   write_metadata(_chunkwriter);
   505   assert(!_chunkwriter.is_valid(), "invariant");
   540   _repository.close_chunk();
   506 }
   541 }
   507 
   542 
   508 void JfrRecorderService::vm_error_rotation() {
   543 static JfrBuffer* thread_local_buffer(Thread* t) {
   509   if (_chunkwriter.is_valid()) {
   544   assert(t != NULL, "invariant");
   510     finalize_current_chunk_on_vm_error();
   545   return t->jfr_thread_local()->native_buffer();
   511     assert(!_chunkwriter.is_valid(), "invariant");
   546 }
   512     _repository.on_vm_error();
   547 
   513   }
   548 static void reset_buffer(JfrBuffer* buffer, Thread* t) {
   514 }
   549   assert(buffer != NULL, "invariant");
   515 
   550   assert(t != NULL, "invariant");
   516 void JfrRecorderService::finalize_current_chunk_on_vm_error() {
   551   assert(buffer == thread_local_buffer(t), "invariant");
       
   552   buffer->set_pos(const_cast<u1*>(buffer->top()));
       
   553 }
       
   554 
       
   555 static void reset_thread_local_buffer(Thread* t) {
       
   556   reset_buffer(thread_local_buffer(t), t);
       
   557 }
       
   558 
       
   559 static void write_thread_local_buffer(JfrChunkWriter& chunkwriter, Thread* t) {
       
   560   JfrBuffer * const buffer = thread_local_buffer(t);
       
   561   assert(buffer != NULL, "invariant");
       
   562   if (!buffer->empty()) {
       
   563     chunkwriter.write_unbuffered(buffer->top(), buffer->pos() - buffer->top());
       
   564     reset_buffer(buffer, t);
       
   565   }
       
   566 }
       
   567 
       
   568 size_t JfrRecorderService::flush() {
       
   569   assert(JfrStream_lock->owned_by_self(), "invariant");
       
   570   size_t total_elements = flush_metadata(_chunkwriter);
       
   571   const size_t storage_elements = flush_storage(_storage, _chunkwriter);
       
   572   if (0 == storage_elements) {
       
   573     return total_elements;
       
   574   }
       
   575   total_elements += storage_elements;
       
   576   if (_string_pool.is_modified()) {
       
   577     total_elements += flush_stringpool(_string_pool, _chunkwriter);
       
   578   }
       
   579   if (_stack_trace_repository.is_modified()) {
       
   580     total_elements += flush_stacktrace(_stack_trace_repository, _chunkwriter);
       
   581   }
       
   582   if (_checkpoint_manager.is_type_set_required()) {
       
   583     total_elements += flush_typeset(_checkpoint_manager, _chunkwriter);
       
   584   } else if (_checkpoint_manager.is_static_type_set_required()) {
       
   585     // don't tally this, it is only in order to flush the waiting constants
       
   586     _checkpoint_manager.flush_static_type_set();
       
   587   }
       
   588   return total_elements;
       
   589 }
       
   590 
       
   591 typedef Content<EventFlush, JfrRecorderService, &JfrRecorderService::flush> FlushFunctor;
       
   592 typedef WriteContent<FlushFunctor> Flush;
       
   593 
       
   594 void JfrRecorderService::invoke_flush() {
       
   595   assert(JfrStream_lock->owned_by_self(), "invariant");
   517   assert(_chunkwriter.is_valid(), "invariant");
   596   assert(_chunkwriter.is_valid(), "invariant");
   518   pre_safepoint_write();
   597   Thread* const t = Thread::current();
   519   // Do not attempt safepoint dependent operations during emergency dump.
   598   ResourceMark rm(t);
   520   // Optimistically write tagged artifacts.
   599   HandleMark hm(t);
   521   _checkpoint_manager.shift_epoch();
   600   ++flushpoint_id;
   522   // update time
   601   reset_thread_local_buffer(t);
   523   _chunkwriter.time_stamp_chunk_now();
   602   FlushFunctor flushpoint(*this);
   524   post_safepoint_write();
   603   Flush fl(_chunkwriter, flushpoint);
   525   assert(!_chunkwriter.is_valid(), "invariant");
   604   invoke_with_flush_event(fl);
       
   605   write_thread_local_buffer(_chunkwriter, t);
       
   606   _repository.flush_chunk();
       
   607 }
       
   608 
       
   609 void JfrRecorderService::flushpoint() {
       
   610   MutexLocker lock(JfrStream_lock);
       
   611   invoke_flush();
   526 }
   612 }
   527 
   613 
   528 void JfrRecorderService::process_full_buffers() {
   614 void JfrRecorderService::process_full_buffers() {
   529   if (_chunkwriter.is_valid()) {
   615   if (_chunkwriter.is_valid()) {
   530     assert(!JfrStream_lock->owned_by_self(), "invariant");
       
   531     MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
       
   532     _storage.write_full();
   616     _storage.write_full();
   533   }
   617   }
   534 }
   618 }
   535 
   619 
   536 void JfrRecorderService::scavenge() {
   620 void JfrRecorderService::scavenge() {