# HG changeset patch # User mgronlun # Date 1568114076 -7200 # Node ID 22dab580786c4cc77b3f927284b2cff2b884adf4 # Parent 10ecdb5d3574c8794a2dd57d50df0886b54a6dc8 restructuring in JfrRecorderService diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp Tue Sep 10 13:14:36 2019 +0200 @@ -174,10 +174,6 @@ return 0 == _generation; } -bool JfrChunk::is_initial_flush() const { - return 0 == _last_metadata_offset; -} - int64_t JfrChunk::duration() const { assert(_last_update_nanos >= _start_nanos, "invariant"); return _last_update_nanos - _start_nanos; diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/repository/jfrChunk.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunk.hpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunk.hpp Tue Sep 10 13:14:36 2019 +0200 @@ -78,7 +78,6 @@ bool is_started() const; bool is_finished() const; - bool is_initial_flush() const; int64_t duration() const; u1 generation() const; diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp Tue Sep 10 13:14:36 2019 +0200 @@ -258,13 +258,6 @@ _chunk->set_last_checkpoint_offset(offset); } -bool JfrChunkWriter::is_initial_flushpoint_for_chunk() const { - assert(_chunk != NULL, "invariant"); - assert(_chunk->is_started(), "invariant"); - assert(!_chunk->is_finished(), "invariant"); - return _chunk->is_initial_flush(); -} - void JfrChunkWriter::set_last_metadata_offset(int64_t offset) { assert(_chunk != NULL, "invariant"); _chunk->set_last_metadata_offset(offset); diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp Tue Sep 10 13:14:36 2019 +0200 @@ -56,7 +56,6 @@ int64_t last_checkpoint_offset() const; void set_last_checkpoint_offset(int64_t offset); void set_last_metadata_offset(int64_t offset); - bool is_initial_flushpoint_for_chunk() const; bool has_metadata() const; void set_time_stamp(); }; diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp Tue Sep 10 13:14:36 2019 +0200 @@ -171,7 +171,7 @@ if (!_chunkwriter->is_valid()) { return; } - instance()._post_box.post((metadata || _chunkwriter->is_initial_flushpoint_for_chunk()) ? MSG_FLUSHPOINT_METADATA : MSG_FLUSHPOINT); + instance()._post_box.post((metadata || !_chunkwriter->has_metadata()) ? MSG_FLUSHPOINT_METADATA : MSG_FLUSHPOINT); } size_t JfrRepository::flush_chunk() { diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Tue Sep 10 13:14:36 2019 +0200 @@ -137,13 +137,13 @@ }; template -class ServiceFunctor { +class Content { private: Instance& _instance; u4 _elements; public: typedef E EventType; - ServiceFunctor(Instance& instance) : _instance(instance), _elements(0) {} + Content(Instance& instance) : _instance(instance), _elements(0) {} bool process() { _elements = (u4)(_instance.*func)(); return true; @@ -151,31 +151,31 @@ u4 elements() const { return _elements; } }; -template -class WriteSubsystem : public StackObj { +template +class WriteContent : public StackObj { protected: const JfrTicks _start_time; JfrTicks _end_time; JfrChunkWriter& _cw; - ContentFunctor& _content_functor; + Content& _content; const int64_t _start_offset; public: - typedef typename ContentFunctor::EventType EventType; + typedef typename Content::EventType EventType; - WriteSubsystem(JfrChunkWriter& cw, ContentFunctor& functor) : + WriteContent(JfrChunkWriter& cw, Content& content) : _start_time(JfrTicks::now()), _end_time(), _cw(cw), - _content_functor(functor), + _content(content), _start_offset(_cw.current_offset()) { assert(_cw.is_valid(), "invariant"); } bool process() { // invocation - _content_functor.process(); + _content.process(); _end_time = JfrTicks::now(); - return 0 != _content_functor.elements(); + return 0 != _content.elements(); } const JfrTicks& start_time() const { @@ -199,7 +199,7 @@ } u4 elements() const { - return (u4) _content_functor.elements(); + return (u4) _content.elements(); } u4 size() const { @@ -229,7 +229,6 @@ void rewind() { _cw.seek(start_offset()); } - }; static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { @@ -248,17 +247,17 @@ return number_of_elements_offset; } -template -class WriteSubsystemCheckpointEvent : public WriteSubsystem { +template +class WriteCheckpointEvent : public WriteContent { private: const u8 _type_id; public: - WriteSubsystemCheckpointEvent(JfrChunkWriter& cw, ContentFunctor& functor, u8 type_id) : - WriteSubsystem(cw, functor), _type_id(type_id) {} + WriteCheckpointEvent(JfrChunkWriter& cw, Content& content, u8 type_id) : + WriteContent(cw, content), _type_id(type_id) {} bool process() { const int64_t num_elements_offset = write_checkpoint_event_prologue(this->_cw, _type_id); - if (!WriteSubsystem::process()) { + if (!WriteContent::process()) { // nothing to do, rewind writer to start this->rewind(); assert(this->current_offset() == this->start_offset(), "invariant"); @@ -274,6 +273,12 @@ }; template +static u4 invoke(Functor& f) { + f.process(); + return f.elements(); +} + +template static void write_flush_event(Functor& f) { if (Functor::is_event_enabled()) { typename Functor::EventType e(UNTIMED); @@ -287,18 +292,123 @@ } template -static u4 invoke(Functor& f) { - f.process(); - return f.elements(); -} - -template static u4 invoke_with_flush_event(Functor& f) { const u4 elements = invoke(f); write_flush_event(f); return elements; } +class StackTraceRepository : public StackObj { + private: + JfrStackTraceRepository& _repo; + JfrChunkWriter& _cw; + size_t _elements; + bool _clear; + + public: + typedef EventFlushStacktrace EventType; + StackTraceRepository(JfrStackTraceRepository& repo, JfrChunkWriter& cw, bool clear) : + _repo(repo), _cw(cw), _elements(0), _clear(clear) {} + bool process() { + _elements = _repo.write(_cw, _clear); + return true; + } + size_t elements() const { return _elements; } + void reset() { _elements = 0; } +}; + +typedef WriteCheckpointEvent WriteStackTrace; + +static u4 flush_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter) { + StackTraceRepository str(stack_trace_repo, chunkwriter, false); + WriteStackTrace wst(chunkwriter, str, TYPE_STACKTRACE); + return invoke_with_flush_event(wst); +} + +static u4 write_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) { + StackTraceRepository str(stack_trace_repo, chunkwriter, clear); + WriteStackTrace wst(chunkwriter, str, TYPE_STACKTRACE); + return invoke(wst); +} + +typedef Content Storage; +typedef WriteContent WriteStorage; + +static size_t flush_storage(JfrStorage& storage, JfrChunkWriter& chunkwriter) { + assert(chunkwriter.is_valid(), "invariant"); + Storage fsf(storage); + WriteStorage fs(chunkwriter, fsf); + return invoke_with_flush_event(fs); +} + +static size_t write_storage(JfrStorage& storage, JfrChunkWriter& chunkwriter) { + assert(chunkwriter.is_valid(), "invariant"); + Storage fsf(storage); + WriteStorage fs(chunkwriter, fsf); + return invoke(fs); +} + +typedef Content StringPool; +typedef Content StringPoolSafepoint; +typedef WriteCheckpointEvent WriteStringPool; +typedef WriteCheckpointEvent WriteStringPoolSafepoint; + +static u4 flush_stringpool(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { + StringPool sp(string_pool); + WriteStringPool wsp(chunkwriter, sp, TYPE_STRING); + return invoke_with_flush_event(wsp); +} + +static u4 write_stringpool(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { + StringPool sp(string_pool); + WriteStringPool wsp(chunkwriter, sp, TYPE_STRING); + return invoke(wsp); +} + +static u4 write_stringpool_safepoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { + StringPoolSafepoint sps(string_pool); + WriteStringPoolSafepoint wsps(chunkwriter, sps, TYPE_STRING); + return invoke(wsps); +} + +typedef Content FlushTypeSetFunctor; +typedef WriteContent FlushTypeSet; + +static u4 flush_typeset(JfrCheckpointManager& checkpoint_manager, JfrChunkWriter& chunkwriter) { + FlushTypeSetFunctor flush_type_set(checkpoint_manager); + FlushTypeSet fts(chunkwriter, flush_type_set); + return invoke_with_flush_event(fts); +} + +class MetadataEvent : public StackObj { + private: + JfrChunkWriter& _cw; + public: + typedef EventFlushMetadata EventType; + MetadataEvent(JfrChunkWriter& cw) : _cw(cw) {} + bool process() { + JfrMetadataEvent::write(_cw); + return true; + } + size_t elements() const { return 1; } +}; + +typedef WriteContent WriteMetadata; + +static u4 flush_metadata(JfrChunkWriter& chunkwriter) { + assert(chunkwriter.is_valid(), "invariant"); + MetadataEvent me(chunkwriter); + WriteMetadata wm(chunkwriter, me); + return invoke_with_flush_event(wm); +} + +static u4 write_metadata(JfrChunkWriter& chunkwriter) { + assert(chunkwriter.is_valid(), "invariant"); + MetadataEvent me(chunkwriter); + WriteMetadata wm(chunkwriter, me); + return invoke(wm); +} + template class JfrVMOperation : public VM_Operation { private: @@ -310,37 +420,13 @@ Mode evaluation_mode() const { return _safepoint; } // default }; -class FlushStackTraceRepository : public StackObj { - private: - JfrStackTraceRepository& _repo; - JfrChunkWriter& _cw; - size_t _elements; - bool _clear; - - public: - typedef EventFlushStacktrace EventType; - FlushStackTraceRepository(JfrStackTraceRepository& repo, JfrChunkWriter& cw, bool clear) : - _repo(repo), _cw(cw), _elements(0), _clear(clear) {} - bool process() { - _elements = _repo.write(_cw, _clear); - return true; - } - size_t elements() const { return _elements; } - void reset() { _elements = 0; } -}; - -class FlushMetadataEvent : public StackObj { - private: - JfrChunkWriter& _cw; - public: - typedef EventFlushMetadata EventType; - FlushMetadataEvent(JfrChunkWriter& cw) : _cw(cw) {} - bool process() { - JfrMetadataEvent::write(_cw); - return true; - } - size_t elements() const { return 1; } -}; +JfrRecorderService::JfrRecorderService() : + _checkpoint_manager(JfrCheckpointManager::instance()), + _chunkwriter(JfrRepository::chunkwriter()), + _repository(JfrRepository::instance()), + _stack_trace_repository(JfrStackTraceRepository::instance()), + _storage(JfrStorage::instance()), + _string_pool(JfrStringPool::instance()) {} static bool recording = false; @@ -353,14 +439,6 @@ return recording; } -JfrRecorderService::JfrRecorderService() : - _checkpoint_manager(JfrCheckpointManager::instance()), - _chunkwriter(JfrRepository::chunkwriter()), - _repository(JfrRepository::instance()), - _stack_trace_repository(JfrStackTraceRepository::instance()), - _storage(JfrStorage::instance()), - _string_pool(JfrStringPool::instance()) {} - void JfrRecorderService::start() { RotationLock rl(Thread::current()); if (rl.not_acquired()) { @@ -394,15 +472,6 @@ VMThread::execute(&safepoint_task); } -// -// safepoint clear sequence -// -// clear stacktrace repository -> -// clear string pool -> -// clear storage -> -// shift epoch -> -// update time -// void JfrRecorderService::safepoint_clear() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); _stack_trace_repository.clear(); @@ -416,6 +485,15 @@ _checkpoint_manager.clear(); } +void JfrRecorderService::open_new_chunk(bool vm_error) { + JfrChunkRotation::on_rotation(); + const bool valid_chunk = _repository.open_chunk(vm_error); + _storage.control().set_to_disk(valid_chunk); + if (valid_chunk) { + _checkpoint_manager.write_constants(); + } +} + static void stop() { assert(JfrRecorderService::is_recording(), "invariant"); log_debug(jfr, system)("Recording STOPPED"); @@ -423,6 +501,27 @@ assert(!JfrRecorderService::is_recording(), "invariant"); } +void JfrRecorderService::prepare_for_vm_error_rotation() { + if (!_chunkwriter.is_valid()) { + open_new_chunk(true); + } + _checkpoint_manager.register_service_thread(Thread::current()); +} + +void JfrRecorderService::vm_error_rotation() { + if (_chunkwriter.is_valid()) { + pre_safepoint_write(); + // Do not attempt safepoint dependent operations during emergency dump. + // Optimistically write tagged artifacts. + _checkpoint_manager.shift_epoch(); + // update time + _chunkwriter.set_time_stamp(); + post_safepoint_write(); + assert(!_chunkwriter.is_valid(), "invariant"); + _repository.on_vm_error(); + } +} + void JfrRecorderService::rotate(int msgs) { RotationLock rl(Thread::current()); if (rl.not_acquired()) { @@ -445,36 +544,16 @@ } } -void JfrRecorderService::prepare_for_vm_error_rotation() { - if (!_chunkwriter.is_valid()) { - open_new_chunk(true); - } - _checkpoint_manager.register_service_thread(Thread::current()); -} - -void JfrRecorderService::open_new_chunk(bool vm_error) { - JfrChunkRotation::on_rotation(); - const bool valid_chunk = _repository.open_chunk(vm_error); - _storage.control().set_to_disk(valid_chunk); - if (valid_chunk) { - _checkpoint_manager.write_constants(); - } -} - void JfrRecorderService::in_memory_rotation() { // currently running an in-memory recording assert(!_storage.control().to_disk(), "invariant"); open_new_chunk(); if (_chunkwriter.is_valid()) { // dump all in-memory buffer data to the newly created chunk - serialize_storage_from_in_memory_recording(); + write_storage(_storage, _chunkwriter); } } -void JfrRecorderService::serialize_storage_from_in_memory_recording() { - _storage.write(); -} - void JfrRecorderService::chunk_rotation() { finalize_current_chunk(); open_new_chunk(); @@ -493,69 +572,57 @@ post_safepoint_write(); } -typedef ServiceFunctor FlushStringPoolFunctor; -typedef ServiceFunctor FlushStringPoolSafepointFunctor; -typedef WriteSubsystemCheckpointEvent FlushStackTraceCheckpoint; -typedef WriteSubsystemCheckpointEvent FlushStringPoolCheckpoint; -typedef WriteSubsystemCheckpointEvent FlushStringPoolCheckpointSafepoint; - -static u4 flush_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) { - FlushStackTraceRepository flush_stacktrace_repo(stack_trace_repo, chunkwriter, clear); - FlushStackTraceCheckpoint flush_stack_trace_checkpoint(chunkwriter, flush_stacktrace_repo, TYPE_STACKTRACE); - return invoke_with_flush_event(flush_stack_trace_checkpoint); +void JfrRecorderService::pre_safepoint_write() { + assert(_chunkwriter.is_valid(), "invariant"); + if (_stack_trace_repository.is_modified()) { + write_stacktrace(_stack_trace_repository, _chunkwriter, false); + } + if (_string_pool.is_modified()) { + write_stringpool(_string_pool, _chunkwriter); + } + if (LeakProfiler::is_running()) { + // Exclusive access to the object sampler instance. + // The sampler is released (unlocked) later in post_safepoint_write. + ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository); + } + _checkpoint_manager.notify_types_on_rotation(); + write_storage(_storage, _chunkwriter); } -static u4 flush_stacktrace(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter) { - return flush_stacktrace(stack_trace_repo, chunkwriter, false); -} - -static u4 flush_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) { - FlushStackTraceRepository flush_stacktrace_repo(stack_trace_repo, chunkwriter, clear); - FlushStackTraceCheckpoint flush_stack_trace_checkpoint(chunkwriter, flush_stacktrace_repo, TYPE_STACKTRACE); - return invoke(flush_stack_trace_checkpoint); -} - -static u4 flush_stringpool(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { - FlushStringPoolFunctor flush_string_pool(string_pool); - FlushStringPoolCheckpoint flush_string_pool_checkpoint(chunkwriter, flush_string_pool, TYPE_STRING); - return invoke_with_flush_event(flush_string_pool_checkpoint); +void JfrRecorderService::invoke_safepoint_write() { + JfrVMOperation safepoint_task(*this); + VMThread::execute(&safepoint_task); } -static u4 flush_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { - FlushStringPoolFunctor flush_string_pool(string_pool); - FlushStringPoolCheckpoint flush_string_pool_checkpoint(chunkwriter, flush_string_pool, TYPE_STRING); - return invoke(flush_string_pool_checkpoint); -} - -static u4 flush_stringpool_checkpoint_safepoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { - FlushStringPoolSafepointFunctor flush_string_pool(string_pool); - FlushStringPoolCheckpointSafepoint flush_string_pool_checkpoint(chunkwriter, flush_string_pool, TYPE_STRING); - return invoke(flush_string_pool_checkpoint); +void JfrRecorderService::safepoint_write() { + assert(SafepointSynchronize::is_at_safepoint(), "invariant"); + write_stacktrace(_stack_trace_repository, _chunkwriter, true); + if (_string_pool.is_modified()) { + write_stringpool_safepoint(_string_pool, _chunkwriter); + } + _storage.write_at_safepoint(); + _checkpoint_manager.notify_threads(); + _checkpoint_manager.shift_epoch(); + _chunkwriter.set_time_stamp(); } -typedef ServiceFunctor FlushTypeSetFunctor; -typedef WriteSubsystem FlushTypeSet; - -static u4 flush_typeset(JfrCheckpointManager& checkpoint_manager, JfrChunkWriter& chunkwriter) { - FlushTypeSetFunctor flush_type_set(checkpoint_manager); - FlushTypeSet fts(chunkwriter, flush_type_set); - return invoke_with_flush_event(fts); -} - -typedef WriteSubsystem FlushMetadata; - -static u4 flush_metadata_event(JfrChunkWriter& chunkwriter) { - assert(chunkwriter.is_valid(), "invariant"); - FlushMetadataEvent fme(chunkwriter); - FlushMetadata fm(chunkwriter, fme); - return invoke_with_flush_event(fm); -} - -static u4 flush_metadata_event_checkpoint(JfrChunkWriter& chunkwriter) { - assert(chunkwriter.is_valid(), "invariant"); - FlushMetadataEvent wme(chunkwriter); - FlushMetadata wm(chunkwriter, wme); - return invoke(wm); +void JfrRecorderService::post_safepoint_write() { + assert(_chunkwriter.is_valid(), "invariant"); + // During the safepoint tasks just completed, the system transitioned to a new epoch. + // Type tagging is epoch relative which entails we are able to write out the + // already tagged artifacts for the previous epoch. We can accomplish this concurrently + // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. + _checkpoint_manager.write_type_set(); + if (LeakProfiler::is_running()) { + // The object sampler instance was exclusively acquired and locked in pre_safepoint_write. + // Note: There is a dependency on write_type_set() above, ensure the release is subsequent. + ObjectSampler::release(); + } + // serialize any outstanding checkpoint memory + _checkpoint_manager.write(); + // serialize the metadata descriptor event and close out the chunk + write_metadata(_chunkwriter); + _repository.close_chunk(); } static JfrBuffer* thread_local_buffer() { @@ -583,25 +650,12 @@ assert(buffer->empty(), "invariant"); } -typedef ServiceFunctor FlushStorageFunctor; -typedef WriteSubsystem FlushStorage; - -static size_t flush_storage(JfrStorage& storage, JfrChunkWriter& chunkwriter) { - assert(chunkwriter.is_valid(), "invariant"); - FlushStorageFunctor fsf(storage); - FlushStorage fs(chunkwriter, fsf); - return invoke_with_flush_event(fs); -} - -typedef ServiceFunctor FlushFunctor; -typedef WriteSubsystem Flush; - static bool write_metadata_in_flushpoint = false; size_t JfrRecorderService::flush() { size_t total_elements = 0; if (write_metadata_in_flushpoint) { - total_elements = flush_metadata_event(_chunkwriter); + total_elements = flush_metadata(_chunkwriter); } const size_t storage_elements = flush_storage(_storage, _chunkwriter); if (0 == storage_elements) { @@ -623,6 +677,9 @@ return total_elements; } +typedef Content FlushFunctor; +typedef WriteContent Flush; + void JfrRecorderService::flush(int msgs) { assert(_chunkwriter.is_valid(), "invariant"); ResourceMark rm; @@ -637,105 +694,6 @@ _repository.flush_chunk(); } -// -// pre-safepoint write sequence -// -// write stack trace checkpoint -> -// write string pool checkpoint -> -// notify about pending rotation -> -// write storage -// -void JfrRecorderService::pre_safepoint_write() { - assert(_chunkwriter.is_valid(), "invariant"); - if (_stack_trace_repository.is_modified()) { - flush_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); - } - if (_string_pool.is_modified()) { - flush_stringpool_checkpoint(_string_pool, _chunkwriter); - } - if (LeakProfiler::is_running()) { - // Exclusive access to the object sampler instance. - // The sampler is released (unlocked) later in post_safepoint_write. - ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository); - } - _checkpoint_manager.notify_types_on_rotation(); - _storage.write(); -} - -void JfrRecorderService::invoke_safepoint_write() { - JfrVMOperation safepoint_task(*this); - VMThread::execute(&safepoint_task); -} - -// -// safepoint write sequence -// -// write object sample stacktraces -> -// write stacktrace repository -> -// write string pool -> -// write storage -> -// notify java threads -> -// shift_epoch -> -// update time -// -void JfrRecorderService::safepoint_write() { - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - flush_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); - if (_string_pool.is_modified()) { - flush_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); - } - _storage.write_at_safepoint(); - _checkpoint_manager.notify_threads(); - _checkpoint_manager.shift_epoch(); - _chunkwriter.set_time_stamp(); -} - -// -// post-safepoint write sequence -// -// write type set -> -// write checkpoints -> -// write metadata event -> -// close chunk -// -void JfrRecorderService::post_safepoint_write() { - assert(_chunkwriter.is_valid(), "invariant"); - // During the safepoint tasks just completed, the system transitioned to a new epoch. - // Type tagging is epoch relative which entails we are able to write out the - // already tagged artifacts for the previous epoch. We can accomplish this concurrently - // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. - _checkpoint_manager.write_type_set(); - if (LeakProfiler::is_running()) { - // The object sampler instance was exclusively acquired and locked in pre_safepoint_write. - // Note: There is a dependency on write_type_set() above, ensure the release is subsequent. - ObjectSampler::release(); - } - // serialize any outstanding checkpoint memory - _checkpoint_manager.write(); - // serialize the metadata descriptor event and close out the chunk - flush_metadata_event_checkpoint(_chunkwriter); - _repository.close_chunk(); -} - -void JfrRecorderService::vm_error_rotation() { - if (_chunkwriter.is_valid()) { - finalize_current_chunk_on_vm_error(); - assert(!_chunkwriter.is_valid(), "invariant"); - _repository.on_vm_error(); - } -} - -void JfrRecorderService::finalize_current_chunk_on_vm_error() { - assert(_chunkwriter.is_valid(), "invariant"); - pre_safepoint_write(); - // Do not attempt safepoint dependent operations during emergency dump. - // Optimistically write tagged artifacts. - _checkpoint_manager.shift_epoch(); - // update time - _chunkwriter.set_time_stamp(); - post_safepoint_write(); -} - void JfrRecorderService::process_full_buffers() { if (_chunkwriter.is_valid()) { _storage.write_full(); diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/service/jfrRecorderService.hpp --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.hpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.hpp Tue Sep 10 13:14:36 2019 +0200 @@ -46,9 +46,7 @@ void open_new_chunk(bool vm_error = false); void chunk_rotation(); void in_memory_rotation(); - void serialize_storage_from_in_memory_recording(); void finalize_current_chunk(); - void finalize_current_chunk_on_vm_error(); void prepare_for_vm_error_rotation(); void vm_error_rotation(); diff -r 10ecdb5d3574 -r 22dab580786c src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Mon Sep 09 13:26:35 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Tue Sep 10 13:14:36 2019 +0200 @@ -34,13 +34,13 @@ class JfrChunkWriter; class JfrStackTraceRepository : public JfrCHeapObj { - friend class FlushStackTraceRepository; friend class JfrRecorder; friend class JfrRecorderService; friend class JfrThreadSampleClosure; friend class ObjectSampleCheckpoint; friend class ObjectSampler; friend class StackTraceBlobInstaller; + friend class StackTraceRepository; private: static const u4 TABLE_SIZE = 2053;