1 /*
   2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jfr/jni/jfrJavaSupport.hpp"
  27 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
  28 #include "jfr/recorder/jfrRecorder.hpp"
  29 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
  30 #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp"
  31 #include "jfr/recorder/repository/jfrChunkSizeNotifier.hpp"
  32 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
  33 #include "jfr/recorder/repository/jfrRepository.hpp"
  34 #include "jfr/recorder/service/jfrPostBox.hpp"
  35 #include "jfr/recorder/service/jfrRecorderService.hpp"
  36 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
  37 #include "jfr/recorder/storage/jfrStorage.hpp"
  38 #include "jfr/recorder/storage/jfrStorageControl.hpp"
  39 #include "jfr/recorder/stringpool/jfrStringPool.hpp"
  40 #include "jfr/utilities/jfrAllocation.hpp"
  41 #include "jfr/utilities/jfrTime.hpp"
  42 #include "jfr/writers/jfrJavaEventWriter.hpp"
  43 #include "jfr/utilities/jfrTypes.hpp"
  44 #include "logging/log.hpp"
  45 #include "memory/resourceArea.hpp"
  46 #include "runtime/atomic.hpp"
  47 #include "runtime/handles.inline.hpp"
  48 #include "runtime/mutexLocker.hpp"
  49 #include "runtime/orderAccess.hpp"
  50 #include "runtime/os.hpp"
  51 #include "runtime/safepoint.hpp"
  52 #include "runtime/thread.inline.hpp"
  53 #include "runtime/vmOperations.hpp"
  54 #include "runtime/vmThread.hpp"
  55 
  56 // set data iff *dest == NULL
  57 static bool try_set(void* const data, void** dest, bool clear) {
  58   assert(data != NULL, "invariant");
  59   const void* const current = OrderAccess::load_acquire(dest);
  60   if (current != NULL) {
  61     if (current != data) {
  62       // already set
  63       return false;
  64     }
  65     assert(current == data, "invariant");
  66     if (!clear) {
  67       // recursion disallowed
  68       return false;
  69     }
  70   }
  71   return Atomic::cmpxchg(clear ? NULL : data, dest, current) == current;
  72 }
  73 
  74 static void* rotation_thread = NULL;
  75 static const int rotation_try_limit = 1000;
  76 static const int rotation_retry_sleep_millis = 10;
  77 
  78 class RotationLock : public StackObj {
  79  private:
  80   Thread* const _thread;
  81   bool _acquired;
  82 
  83   void log(bool recursion) {
  84     assert(!_acquired, "invariant");
  85     const char* error_msg = NULL;
  86     if (recursion) {
  87       error_msg = "Unable to issue rotation due to recursive calls.";
  88     }
  89     else {
  90       error_msg = "Unable to issue rotation due to wait timeout.";
  91     }
  92     log_info(jfr)( // For user, should not be "jfr, system"
  93       "%s", error_msg);
  94   }
  95  public:
  96   RotationLock(Thread* thread) : _thread(thread), _acquired(false) {
  97     assert(_thread != NULL, "invariant");
  98     if (_thread == rotation_thread) {
  99       // recursion not supported
 100       log(true);
 101       return;
 102     }
 103 
 104     // limited to not spin indefinitely
 105     for (int i = 0; i < rotation_try_limit; ++i) {
 106       if (try_set(_thread, &rotation_thread, false)) {
 107         _acquired = true;
 108         assert(_thread == rotation_thread, "invariant");
 109         return;
 110       }
 111       if (_thread->is_Java_thread()) {
 112         // in order to allow the system to move to a safepoint
 113         MutexLockerEx msg_lock(JfrMsg_lock);
 114         JfrMsg_lock->wait(false, rotation_retry_sleep_millis);
 115       }
 116       else {
 117         os::naked_short_sleep(rotation_retry_sleep_millis);
 118       }
 119     }
 120     log(false);
 121   }
 122 
 123   ~RotationLock() {
 124     assert(_thread != NULL, "invariant");
 125     if (_acquired) {
 126       assert(_thread == rotation_thread, "invariant");
 127       while (!try_set(_thread, &rotation_thread, true));
 128     }
 129   }
 130   bool not_acquired() const { return !_acquired; }
 131 };
 132 
 133 static intptr_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
 134   const intptr_t prev_cp_offset = cw.previous_checkpoint_offset();
 135   const intptr_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset();
 136   cw.reserve(sizeof(u4));
 137   cw.write<u8>(EVENT_CHECKPOINT);
 138   cw.write(JfrTicks::now());
 139   cw.write<jlong>((jlong)0);
 140   cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta
 141   cw.write<bool>(false); // flushpoint
 142   cw.write<u4>((u4)1); // nof types in this checkpoint
 143   cw.write<u8>(type_id);
 144   const intptr_t number_of_elements_offset = cw.current_offset();
 145   cw.reserve(sizeof(u4));
 146   return number_of_elements_offset;
 147 }
 148 
 149 template <typename ContentFunctor>
 150 class WriteCheckpointEvent : public StackObj {
 151  private:
 152   JfrChunkWriter& _cw;
 153   u8 _type_id;
 154   ContentFunctor& _content_functor;
 155  public:
 156   WriteCheckpointEvent(JfrChunkWriter& cw, u8 type_id, ContentFunctor& functor) :
 157     _cw(cw),
 158     _type_id(type_id),
 159     _content_functor(functor) {
 160     assert(_cw.is_valid(), "invariant");
 161   }
 162   bool process() {
 163     // current_cp_offset is also offset for the event size header field
 164     const intptr_t current_cp_offset = _cw.current_offset();
 165     const intptr_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id);
 166     // invocation
 167     _content_functor.process();
 168     const u4 number_of_elements = (u4)_content_functor.processed();
 169     if (number_of_elements == 0) {
 170       // nothing to do, rewind writer to start
 171       _cw.seek(current_cp_offset);
 172       return true;
 173     }
 174     assert(number_of_elements > 0, "invariant");
 175     assert(_cw.current_offset() > num_elements_offset, "invariant");
 176     _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);
 178     // update writer with last checkpoint position
 179     _cw.set_previous_checkpoint_offset(current_cp_offset);
 180     return true;
 181   }
 182 };
 183 
 184 template <typename Instance, size_t(Instance::*func)()>
 185 class ServiceFunctor {
 186  private:
 187   Instance& _instance;
 188   size_t _processed;
 189  public:
 190   ServiceFunctor(Instance& instance) : _instance(instance), _processed(0) {}
 191   bool process() {
 192     _processed = (_instance.*func)();
 193     return true;
 194   }
 195   size_t processed() const { return _processed; }
 196 };
 197 
 198 template <typename Instance, void(Instance::*func)()>
 199 class JfrVMOperation : public VM_Operation {
 200  private:
 201   Instance& _instance;
 202  public:
 203   JfrVMOperation(Instance& instance) : _instance(instance) {}
 204   void doit() { (_instance.*func)(); }
 205   VMOp_Type type() const { return VMOp_JFRCheckpoint; }
 206   Mode evaluation_mode() const { return _safepoint; } // default
 207 };
 208 
 209 class WriteStackTraceRepository : public StackObj {
 210  private:
 211   JfrStackTraceRepository& _repo;
 212   JfrChunkWriter& _cw;
 213   size_t _elements_processed;
 214   bool _clear;
 215 
 216  public:
 217   WriteStackTraceRepository(JfrStackTraceRepository& repo, JfrChunkWriter& cw, bool clear) :
 218     _repo(repo), _cw(cw), _elements_processed(0), _clear(clear) {}
 219   bool process() {
 220     _elements_processed = _repo.write(_cw, _clear);
 221     return true;
 222   }
 223   size_t processed() const { return _elements_processed; }
 224   void reset() { _elements_processed = 0; }
 225 };
 226 
 227 static bool recording = false;
 228 
 229 static void set_recording_state(bool is_recording) {
 230   OrderAccess::storestore();
 231   recording = is_recording;
 232 }
 233 
 234 bool JfrRecorderService::is_recording() {
 235   return recording;
 236 }
 237 
 238 JfrRecorderService::JfrRecorderService() :
 239   _checkpoint_manager(JfrCheckpointManager::instance()),
 240   _chunkwriter(JfrRepository::chunkwriter()),
 241   _repository(JfrRepository::instance()),
 242   _stack_trace_repository(JfrStackTraceRepository::instance()),
 243   _storage(JfrStorage::instance()),
 244   _string_pool(JfrStringPool::instance()) {}
 245 
 246 void JfrRecorderService::start() {
 247   RotationLock rl(Thread::current());
 248   if (rl.not_acquired()) {
 249     return;
 250   }
 251   log_debug(jfr, system)("Request to START recording");
 252   assert(!is_recording(), "invariant");
 253   clear();
 254   set_recording_state(true);
 255   assert(is_recording(), "invariant");
 256   open_new_chunk();
 257   log_debug(jfr, system)("Recording STARTED");
 258 }
 259 
 260 void JfrRecorderService::clear() {
 261   ResourceMark rm;
 262   HandleMark hm;
 263   pre_safepoint_clear();
 264   invoke_safepoint_clear();
 265   post_safepoint_clear();
 266 }
 267 
 268 void JfrRecorderService::pre_safepoint_clear() {
 269   _stack_trace_repository.clear();
 270   _string_pool.clear();
 271   _storage.clear();
 272 }
 273 
 274 void JfrRecorderService::invoke_safepoint_clear() {
 275   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_clear> safepoint_task(*this);
 276   VMThread::execute(&safepoint_task);
 277 }
 278 
 279 //
 280 // safepoint clear sequence
 281 //
 282 //  clear stacktrace repository ->
 283 //    clear string pool ->
 284 //      clear storage ->
 285 //        shift epoch ->
 286 //          update time
 287 //
 288 void JfrRecorderService::safepoint_clear() {
 289   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
 290   _stack_trace_repository.clear();
 291   _string_pool.clear();
 292   _storage.clear();
 293   _checkpoint_manager.shift_epoch();
 294   _chunkwriter.time_stamp_chunk_now();
 295 }
 296 
 297 void JfrRecorderService::post_safepoint_clear() {
 298   _checkpoint_manager.clear();
 299 }
 300 
 301 static void stop() {
 302   assert(JfrRecorderService::is_recording(), "invariant");
 303   log_debug(jfr, system)("Recording STOPPED");
 304   set_recording_state(false);
 305   assert(!JfrRecorderService::is_recording(), "invariant");
 306 }
 307 
 308 void JfrRecorderService::rotate(int msgs) {
 309   RotationLock rl(Thread::current());
 310   if (rl.not_acquired()) {
 311     return;
 312   }
 313   static bool vm_error = false;
 314   if (msgs & MSGBIT(MSG_VM_ERROR)) {
 315     vm_error = true;
 316     prepare_for_vm_error_rotation();
 317   }
 318   if (msgs & (MSGBIT(MSG_STOP))) {
 319     stop();
 320   }
 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 }
 332 
 333 void JfrRecorderService::prepare_for_vm_error_rotation() {
 334   if (!_chunkwriter.is_valid()) {
 335     open_new_chunk(true);
 336   }
 337   _checkpoint_manager.register_service_thread(Thread::current());
 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   MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 344   if (!_repository.open_chunk(vm_error)) {
 345     assert(!_chunkwriter.is_valid(), "invariant");
 346     _storage.control().set_to_disk(false);
 347     return;
 348   }
 349   assert(_chunkwriter.is_valid(), "invariant");
 350   _storage.control().set_to_disk(true);
 351 }
 352 
 353 void JfrRecorderService::in_memory_rotation() {
 354   assert(!_chunkwriter.is_valid(), "invariant");
 355   // currently running an in-memory recording
 356   open_new_chunk();
 357   if (_chunkwriter.is_valid()) {
 358     // dump all in-memory buffer data to the newly created chunk
 359     serialize_storage_from_in_memory_recording();
 360   }
 361 }
 362 
 363 void JfrRecorderService::serialize_storage_from_in_memory_recording() {
 364   assert(!JfrStream_lock->owned_by_self(), "not holding stream lock!");
 365   MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 366   _storage.write();
 367 }
 368 
 369 void JfrRecorderService::chunk_rotation() {
 370   finalize_current_chunk();
 371   open_new_chunk();
 372 }
 373 
 374 void JfrRecorderService::finalize_current_chunk() {
 375   assert(_chunkwriter.is_valid(), "invariant");
 376   write();
 377   assert(!_chunkwriter.is_valid(), "invariant");
 378 }
 379 
 380 void JfrRecorderService::write() {
 381   ResourceMark rm;
 382   HandleMark hm;
 383   pre_safepoint_write();
 384   invoke_safepoint_write();
 385   post_safepoint_write();
 386 }
 387 
 388 typedef ServiceFunctor<JfrStringPool, &JfrStringPool::write> WriteStringPool;
 389 typedef ServiceFunctor<JfrStringPool, &JfrStringPool::write_at_safepoint> WriteStringPoolSafepoint;
 390 typedef WriteCheckpointEvent<WriteStackTraceRepository> WriteStackTraceCheckpoint;
 391 typedef WriteCheckpointEvent<WriteStringPool> WriteStringPoolCheckpoint;
 392 typedef WriteCheckpointEvent<WriteStringPoolSafepoint> WriteStringPoolCheckpointSafepoint;
 393 
 394 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) {
 395   WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear);
 396   WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo);
 397   write_stack_trace_checkpoint.process();
 398 }
 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 storage ->
 421 //              release stream lock
 422 //
 423 void JfrRecorderService::pre_safepoint_write() {
 424   MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 425   assert(_chunkwriter.is_valid(), "invariant");
 426   _checkpoint_manager.write_types();
 427   _checkpoint_manager.write_epoch_transition_mspace();
 428   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false);
 429   write_stringpool_checkpoint(_string_pool, _chunkwriter);
 430   _storage.write();
 431 }
 432 
 433 void JfrRecorderService::invoke_safepoint_write() {
 434   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
 435   VMThread::execute(&safepoint_task);
 436 }
 437 
 438 static void write_object_sample_stacktrace(JfrStackTraceRepository& stack_trace_repository) {
 439   WriteObjectSampleStacktrace object_sample_stacktrace(stack_trace_repository);
 440   object_sample_stacktrace.process();
 441 }
 442 
 443 //
 444 // safepoint write sequence
 445 //
 446 //   lock stream lock ->
 447 //     write object sample stacktraces ->
 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() {
 458   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
 459   MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 460   write_object_sample_stacktrace(_stack_trace_repository);
 461   write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true);
 462   write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter);
 463   _checkpoint_manager.write_safepoint_types();
 464   _storage.write_at_safepoint();
 465   _checkpoint_manager.shift_epoch();
 466   _chunkwriter.time_stamp_chunk_now();
 467   JfrMetadataEvent::lock();
 468 }
 469 
 470 static jlong write_metadata_event(JfrChunkWriter& chunkwriter) {
 471   assert(chunkwriter.is_valid(), "invariant");
 472   const jlong metadata_offset = chunkwriter.current_offset();
 473   JfrMetadataEvent::write(chunkwriter, metadata_offset);
 474   return metadata_offset;
 475 }
 476 
 477 //
 478 // post-safepoint write sequence
 479 //
 480 //  lock stream lock ->
 481 //    write type set ->
 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() {
 489   assert(_chunkwriter.is_valid(), "invariant");
 490   // 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
 492   // already tagged artifacts for the previous epoch. We can accomplish this concurrently
 493   // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint.
 494   _checkpoint_manager.write_type_set();
 495   MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 496   // serialize any outstanding checkpoint memory
 497   _checkpoint_manager.write();
 498   // serialize the metadata descriptor event and close out the chunk
 499   _repository.close_chunk(write_metadata_event(_chunkwriter));
 500   assert(!_chunkwriter.is_valid(), "invariant");
 501 }
 502 
 503 void JfrRecorderService::vm_error_rotation() {
 504   if (_chunkwriter.is_valid()) {
 505     finalize_current_chunk_on_vm_error();
 506     assert(!_chunkwriter.is_valid(), "invariant");
 507     _repository.on_vm_error();
 508   }
 509 }
 510 
 511 void JfrRecorderService::finalize_current_chunk_on_vm_error() {
 512   assert(_chunkwriter.is_valid(), "invariant");
 513   pre_safepoint_write();
 514   JfrMetadataEvent::lock();
 515   // Do not attempt safepoint dependent operations during emergency dump.
 516   // Optimistically write tagged artifacts.
 517   _checkpoint_manager.shift_epoch();
 518   _checkpoint_manager.write_type_set();
 519   // update time
 520   _chunkwriter.time_stamp_chunk_now();
 521   post_safepoint_write();
 522   assert(!_chunkwriter.is_valid(), "invariant");
 523 }
 524 
 525 void JfrRecorderService::process_full_buffers() {
 526   if (_chunkwriter.is_valid()) {
 527     assert(!JfrStream_lock->owned_by_self(), "invariant");
 528     MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
 529     _storage.write_full();
 530   }
 531 }
 532 
 533 void JfrRecorderService::scavenge() {
 534   _storage.scavenge();
 535 }
 536 
 537 void JfrRecorderService::evaluate_chunk_size_for_rotation() {
 538   const size_t size_written = _chunkwriter.size_written();
 539   if (size_written > JfrChunkSizeNotifier::chunk_size_threshold()) {
 540     JfrChunkSizeNotifier::notify();
 541   }
 542 }