1 /* 2 * Copyright (c) 2016, 2019, 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/leakProfiler.hpp" 28 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" 29 #include "jfr/leakprofiler/sampling/objectSampler.hpp" 30 #include "jfr/recorder/jfrRecorder.hpp" 31 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" 32 #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp" 33 #include "jfr/recorder/repository/jfrChunkRotation.hpp" 34 #include "jfr/recorder/repository/jfrChunkWriter.hpp" 35 #include "jfr/recorder/repository/jfrRepository.hpp" 36 #include "jfr/recorder/service/jfrPostBox.hpp" 37 #include "jfr/recorder/service/jfrRecorderService.hpp" 38 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" 39 #include "jfr/recorder/storage/jfrStorage.hpp" 40 #include "jfr/recorder/storage/jfrStorageControl.hpp" 41 #include "jfr/recorder/stringpool/jfrStringPool.hpp" 42 #include "jfr/utilities/jfrAllocation.hpp" 43 #include "jfr/utilities/jfrTime.hpp" 44 #include "jfr/writers/jfrJavaEventWriter.hpp" 45 #include "jfr/utilities/jfrTypes.hpp" 46 #include "logging/log.hpp" 47 #include "memory/resourceArea.hpp" 48 #include "runtime/atomic.hpp" 49 #include "runtime/handles.inline.hpp" 50 #include "runtime/mutexLocker.inline.hpp" 51 #include "runtime/orderAccess.hpp" 52 #include "runtime/os.hpp" 53 #include "runtime/safepoint.hpp" 54 #include "runtime/thread.inline.hpp" 55 #include "runtime/vmOperations.hpp" 56 #include "runtime/vmThread.hpp" 57 58 // set data iff *dest == NULL 59 static bool try_set(void* const data, void** dest, bool clear) { 60 assert(data != NULL, "invariant"); 61 const void* const current = OrderAccess::load_acquire(dest); 62 if (current != NULL) { 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: 82 Thread* const _thread; 83 bool _acquired; 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: 98 RotationLock(Thread* thread) : _thread(thread), _acquired(false) { 99 assert(_thread != NULL, "invariant"); 100 if (_thread == rotation_thread) { 101 // recursion not supported 102 log(true); 103 return; 104 } 105 106 // limited to not spin indefinitely 107 for (int i = 0; i < rotation_try_limit; ++i) { 108 if (try_set(_thread, &rotation_thread, false)) { 109 _acquired = true; 110 assert(_thread == rotation_thread, "invariant"); 111 return; 112 } 113 if (_thread->is_Java_thread()) { 114 // in order to allow the system to move to a safepoint 115 MutexLocker msg_lock(JfrMsg_lock); 116 JfrMsg_lock->wait(rotation_retry_sleep_millis); 117 } 118 else { 119 os::naked_short_sleep(rotation_retry_sleep_millis); 120 } 121 } 122 log(false); 123 } 124 125 ~RotationLock() { 126 assert(_thread != NULL, "invariant"); 127 if (_acquired) { 128 assert(_thread == rotation_thread, "invariant"); 129 while (!try_set(_thread, &rotation_thread, true)); 130 } 131 } 132 bool not_acquired() const { return !_acquired; } 133 }; 134 135 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { 136 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(); 138 cw.reserve(sizeof(u4)); 139 cw.write<u8>(EVENT_CHECKPOINT); 140 cw.write(JfrTicks::now()); 141 cw.write((int64_t)0); // duration 142 cw.write(delta_to_last_checkpoint); 143 cw.write<bool>(false); // flushpoint 144 cw.write((u4)1); // nof types in this checkpoint 145 cw.write(type_id); 146 const int64_t number_of_elements_offset = cw.current_offset(); 147 cw.reserve(sizeof(u4)); 148 return number_of_elements_offset; 149 } 150 151 template <typename ContentFunctor> 152 class WriteCheckpointEvent : public StackObj { 153 private: 154 JfrChunkWriter& _cw; 155 u8 _type_id; 156 ContentFunctor& _content_functor; 157 public: 158 WriteCheckpointEvent(JfrChunkWriter& cw, u8 type_id, ContentFunctor& functor) : 159 _cw(cw), 160 _type_id(type_id), 161 _content_functor(functor) { 162 assert(_cw.is_valid(), "invariant"); 163 } 164 bool process() { 165 // current_cp_offset is also offset for the event size header field 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; 183 } 184 }; 185 186 template <typename Instance, size_t(Instance::*func)()> 187 class ServiceFunctor { 188 private: 189 Instance& _instance; 190 size_t _processed; 191 public: 192 ServiceFunctor(Instance& instance) : _instance(instance), _processed(0) {} 193 bool process() { 194 _processed = (_instance.*func)(); 195 return true; 196 } 197 size_t processed() const { return _processed; } 198 }; 199 200 template <typename Instance, void(Instance::*func)()> 201 class JfrVMOperation : public VM_Operation { 202 private: 203 Instance& _instance; 204 public: 205 JfrVMOperation(Instance& instance) : _instance(instance) {} 206 void doit() { (_instance.*func)(); } 207 VMOp_Type type() const { return VMOp_JFRCheckpoint; } 208 Mode evaluation_mode() const { return _safepoint; } // default 209 }; 210 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() : 241 _checkpoint_manager(JfrCheckpointManager::instance()), 242 _chunkwriter(JfrRepository::chunkwriter()), 243 _repository(JfrRepository::instance()), 244 _stack_trace_repository(JfrStackTraceRepository::instance()), 245 _storage(JfrStorage::instance()), 246 _string_pool(JfrStringPool::instance()) {} 247 248 void JfrRecorderService::start() { 249 RotationLock rl(Thread::current()); 250 if (rl.not_acquired()) { 251 return; 252 } 253 log_debug(jfr, system)("Request to START recording"); 254 assert(!is_recording(), "invariant"); 255 clear(); 256 set_recording_state(true); 257 assert(is_recording(), "invariant"); 258 open_new_chunk(); 259 log_debug(jfr, system)("Recording STARTED"); 260 } 261 262 void JfrRecorderService::clear() { 263 ResourceMark rm; 264 HandleMark hm; 265 pre_safepoint_clear(); 266 invoke_safepoint_clear(); 267 post_safepoint_clear(); 268 } 269 270 void JfrRecorderService::pre_safepoint_clear() { 271 _stack_trace_repository.clear(); 272 _string_pool.clear(); 273 _storage.clear(); 274 } 275 276 void JfrRecorderService::invoke_safepoint_clear() { 277 JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_clear> safepoint_task(*this); 278 VMThread::execute(&safepoint_task); 279 } 280 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() { 291 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 292 _stack_trace_repository.clear(); 293 _string_pool.clear(); 294 _storage.clear(); 295 _checkpoint_manager.shift_epoch(); 296 _chunkwriter.time_stamp_chunk_now(); 297 } 298 299 void JfrRecorderService::post_safepoint_clear() { 300 _checkpoint_manager.clear(); 301 } 302 303 static void stop() { 304 assert(JfrRecorderService::is_recording(), "invariant"); 305 log_debug(jfr, system)("Recording STOPPED"); 306 set_recording_state(false); 307 assert(!JfrRecorderService::is_recording(), "invariant"); 308 } 309 310 void JfrRecorderService::rotate(int msgs) { 311 RotationLock rl(Thread::current()); 312 if (rl.not_acquired()) { 313 return; 314 } 315 static bool vm_error = false; 316 if (msgs & MSGBIT(MSG_VM_ERROR)) { 317 vm_error = true; 318 prepare_for_vm_error_rotation(); 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 } 327 if (msgs & (MSGBIT(MSG_STOP))) { 328 stop(); 329 } 330 } 331 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() { 355 assert(!_chunkwriter.is_valid(), "invariant"); 356 // currently running an in-memory recording 357 open_new_chunk(); 358 if (_chunkwriter.is_valid()) { 359 // dump all in-memory buffer data to the newly created chunk 360 serialize_storage_from_in_memory_recording(); 361 } 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 } 369 370 void JfrRecorderService::chunk_rotation() { 371 finalize_current_chunk(); 372 open_new_chunk(); 373 } 374 375 void JfrRecorderService::finalize_current_chunk() { 376 assert(_chunkwriter.is_valid(), "invariant"); 377 write(); 378 assert(!_chunkwriter.is_valid(), "invariant"); 379 } 380 381 void JfrRecorderService::write() { 382 ResourceMark rm; 383 HandleMark hm; 384 pre_safepoint_write(); 385 invoke_safepoint_write(); 386 post_safepoint_write(); 387 } 388 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() { 425 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); 426 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()) { 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 } 436 _storage.write(); 437 } 438 439 void JfrRecorderService::invoke_safepoint_write() { 440 JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this); 441 VMThread::execute(&safepoint_task); 442 } 443 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() { 458 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 459 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); 460 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); 461 write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); 462 _checkpoint_manager.write_safepoint_types(); 463 _storage.write_at_safepoint(); 464 _checkpoint_manager.shift_epoch(); 465 _chunkwriter.time_stamp_chunk_now(); 466 JfrMetadataEvent::lock(); 467 } 468 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() { 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 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 } 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 504 _repository.close_chunk(write_metadata_event(_chunkwriter)); 505 assert(!_chunkwriter.is_valid(), "invariant"); 506 } 507 508 void JfrRecorderService::vm_error_rotation() { 509 if (_chunkwriter.is_valid()) { 510 finalize_current_chunk_on_vm_error(); 511 assert(!_chunkwriter.is_valid(), "invariant"); 512 _repository.on_vm_error(); 513 } 514 } 515 516 void JfrRecorderService::finalize_current_chunk_on_vm_error() { 517 assert(_chunkwriter.is_valid(), "invariant"); 518 pre_safepoint_write(); 519 // Do not attempt safepoint dependent operations during emergency dump. 520 // Optimistically write tagged artifacts. 521 _checkpoint_manager.shift_epoch(); 522 // update time 523 _chunkwriter.time_stamp_chunk_now(); 524 post_safepoint_write(); 525 assert(!_chunkwriter.is_valid(), "invariant"); 526 } 527 528 void JfrRecorderService::process_full_buffers() { 529 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(); 533 } 534 } 535 536 void JfrRecorderService::scavenge() { 537 _storage.scavenge(); 538 } 539 540 void JfrRecorderService::evaluate_chunk_size_for_rotation() { 541 JfrChunkRotation::evaluate(_chunkwriter); 542 }