506 _checkpoint_manager.register_service_thread(Thread::current()); |
506 _checkpoint_manager.register_service_thread(Thread::current()); |
507 } |
507 } |
508 |
508 |
509 void JfrRecorderService::vm_error_rotation() { |
509 void JfrRecorderService::vm_error_rotation() { |
510 if (_chunkwriter.is_valid()) { |
510 if (_chunkwriter.is_valid()) { |
511 pre_safepoint_write(); |
511 Thread* const t = Thread::current(); |
512 // Do not attempt safepoint dependent operations during emergency dump. |
512 _storage.flush_regular_buffer(t->jfr_thread_local()->native_buffer(), t); |
513 // Optimistically write tagged artifacts. |
513 invoke_flush(t); |
514 _checkpoint_manager.shift_epoch(); |
|
515 // update time |
|
516 _chunkwriter.set_time_stamp(); |
514 _chunkwriter.set_time_stamp(); |
517 post_safepoint_write(); |
515 _repository.close_chunk(); |
518 assert(!_chunkwriter.is_valid(), "invariant"); |
516 assert(!_chunkwriter.is_valid(), "invariant"); |
519 _repository.on_vm_error(); |
517 _repository.on_vm_error(); |
520 } |
518 } |
521 } |
519 } |
522 |
520 |
617 // serialize the metadata descriptor event and close out the chunk |
615 // serialize the metadata descriptor event and close out the chunk |
618 write_metadata(_chunkwriter); |
616 write_metadata(_chunkwriter); |
619 _repository.close_chunk(); |
617 _repository.close_chunk(); |
620 } |
618 } |
621 |
619 |
622 static JfrBuffer* thread_local_buffer() { |
620 static JfrBuffer* thread_local_buffer(Thread* t) { |
623 return Thread::current()->jfr_thread_local()->native_buffer(); |
621 assert(t != NULL, "invariant"); |
624 } |
622 return t->jfr_thread_local()->native_buffer(); |
625 |
623 } |
626 static void reset_buffer(JfrBuffer* buffer) { |
624 |
|
625 static void reset_buffer(JfrBuffer* buffer, Thread* t) { |
627 assert(buffer != NULL, "invariant"); |
626 assert(buffer != NULL, "invariant"); |
628 assert(buffer == thread_local_buffer(), "invariant"); |
627 assert(t != NULL, "invariant"); |
|
628 assert(buffer == thread_local_buffer(t), "invariant"); |
629 buffer->set_pos(const_cast<u1*>(buffer->top())); |
629 buffer->set_pos(const_cast<u1*>(buffer->top())); |
630 assert(buffer->empty(), "invariant"); |
630 } |
631 } |
631 |
632 |
632 static void reset_thread_local_buffer(Thread* t) { |
633 static void reset_thread_local_buffer() { |
633 reset_buffer(thread_local_buffer(t), t); |
634 reset_buffer(thread_local_buffer()); |
634 } |
635 } |
635 |
636 |
636 static void write_thread_local_buffer(JfrChunkWriter& chunkwriter, Thread* t) { |
637 static void write_thread_local_buffer(JfrChunkWriter& chunkwriter) { |
637 JfrBuffer * const buffer = thread_local_buffer(t); |
638 JfrBuffer * const buffer = thread_local_buffer(); |
|
639 assert(buffer != NULL, "invariant"); |
638 assert(buffer != NULL, "invariant"); |
640 if (!buffer->empty()) { |
639 if (!buffer->empty()) { |
641 chunkwriter.write_unbuffered(buffer->top(), buffer->pos() - buffer->top()); |
640 chunkwriter.write_unbuffered(buffer->top(), buffer->pos() - buffer->top()); |
642 reset_buffer(buffer); |
641 reset_buffer(buffer, t); |
643 } |
642 } |
644 assert(buffer->empty(), "invariant"); |
643 } |
645 } |
|
646 |
|
647 static bool write_metadata_in_flushpoint = false; |
|
648 |
644 |
649 size_t JfrRecorderService::flush() { |
645 size_t JfrRecorderService::flush() { |
650 size_t total_elements = flush_metadata(_chunkwriter); |
646 size_t total_elements = flush_metadata(_chunkwriter); |
651 const size_t storage_elements = flush_storage(_storage, _chunkwriter); |
647 const size_t storage_elements = flush_storage(_storage, _chunkwriter); |
652 if (0 == storage_elements) { |
648 if (0 == storage_elements) { |
669 } |
665 } |
670 |
666 |
671 typedef Content<EventFlush, JfrRecorderService, &JfrRecorderService::flush> FlushFunctor; |
667 typedef Content<EventFlush, JfrRecorderService, &JfrRecorderService::flush> FlushFunctor; |
672 typedef WriteContent<FlushFunctor> Flush; |
668 typedef WriteContent<FlushFunctor> Flush; |
673 |
669 |
674 void JfrRecorderService::flushpoint() { |
670 void JfrRecorderService::invoke_flush(Thread* t) { |
|
671 assert(t != NULL, "invariant"); |
675 assert(_chunkwriter.is_valid(), "invariant"); |
672 assert(_chunkwriter.is_valid(), "invariant"); |
676 ResourceMark rm; |
673 ResourceMark rm(t); |
677 HandleMark hm; |
674 HandleMark hm(t); |
678 ++flushpoint_id; |
675 ++flushpoint_id; |
679 reset_thread_local_buffer(); |
676 reset_thread_local_buffer(t); |
680 FlushFunctor flushpoint(*this); |
677 FlushFunctor flushpoint(*this); |
681 Flush fl(_chunkwriter, flushpoint); |
678 Flush fl(_chunkwriter, flushpoint); |
682 invoke_with_flush_event(fl); |
679 invoke_with_flush_event(fl); |
683 write_thread_local_buffer(_chunkwriter); |
680 write_thread_local_buffer(_chunkwriter, t); |
684 _repository.flush_chunk(); |
681 _repository.flush_chunk(); |
|
682 } |
|
683 |
|
684 void JfrRecorderService::flushpoint() { |
|
685 Thread* const t = Thread::current(); |
|
686 RotationLock rl(t); |
|
687 if (rl.not_acquired() || !_chunkwriter.is_valid()) { |
|
688 return; |
|
689 } |
|
690 invoke_flush(t); |
685 } |
691 } |
686 |
692 |
687 void JfrRecorderService::process_full_buffers() { |
693 void JfrRecorderService::process_full_buffers() { |
688 if (_chunkwriter.is_valid()) { |
694 if (_chunkwriter.is_valid()) { |
689 _storage.write_full(); |
695 _storage.write_full(); |