diff -r 2c3cc4b01880 -r c16ac7a2eba4 src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Wed Oct 30 16:14:56 2019 +0100 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Wed Oct 30 19:43:52 2019 +0100 @@ -37,11 +37,14 @@ #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp" #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp" #include "jfr/utilities/jfrBigEndian.hpp" +#include "jfr/utilities/jfrIterator.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" #include "jfr/utilities/jfrTypes.hpp" +#include "jfr/writers/jfrJavaEventWriter.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/handles.inline.hpp" -#include "runtime/mutexLocker.hpp" +#include "runtime/mutex.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.inline.hpp" #include "runtime/safepoint.hpp" @@ -168,7 +171,7 @@ } bool JfrCheckpointManager::use_epoch_transition_mspace(const Thread* thread) const { - return _service_thread != thread && OrderAccess::load_acquire(&_checkpoint_epoch_state) != JfrTraceIdEpoch::epoch(); + return _service_thread != thread && _checkpoint_epoch_state != JfrTraceIdEpoch::epoch(); } static const size_t lease_retry = 10; @@ -181,12 +184,24 @@ return lease_free(size, manager._free_list_mspace, lease_retry, thread); } +JfrCheckpointMspace* JfrCheckpointManager::lookup(BufferPtr old) const { + assert(old != NULL, "invariant"); + return _free_list_mspace->in_free_list(old) ? _free_list_mspace : _epoch_transition_mspace; +} + +BufferPtr JfrCheckpointManager::lease_buffer(BufferPtr old, Thread* thread, size_t size /* 0 */) { + assert(old != NULL, "invariant"); + JfrCheckpointMspace* mspace = instance().lookup(old); + assert(mspace != NULL, "invariant"); + return lease_free(size, mspace, lease_retry, thread); +} + /* -* If the buffer was a "lease" from the free list, release back. -* -* The buffer is effectively invalidated for the thread post-return, -* and the caller should take means to ensure that it is not referenced. -*/ + * If the buffer was a lease, release back. + * + * The buffer is effectively invalidated for the thread post-return, + * and the caller should take means to ensure that it is not referenced. + */ static void release(BufferPtr const buffer, Thread* thread) { DEBUG_ONLY(assert_release(buffer);) buffer->clear_lease(); @@ -202,7 +217,7 @@ return NULL; } // migration of in-flight information - BufferPtr const new_buffer = lease_buffer(thread, used + requested); + BufferPtr const new_buffer = lease_buffer(old, thread, used + requested); if (new_buffer != NULL) { migrate_outstanding_writes(old, new_buffer, used, requested); } @@ -213,8 +228,8 @@ // offsets into the JfrCheckpointEntry static const juint starttime_offset = sizeof(jlong); static const juint duration_offset = starttime_offset + sizeof(jlong); -static const juint flushpoint_offset = duration_offset + sizeof(jlong); -static const juint types_offset = flushpoint_offset + sizeof(juint); +static const juint checkpoint_type_offset = duration_offset + sizeof(jlong); +static const juint types_offset = checkpoint_type_offset + sizeof(juint); static const juint payload_offset = types_offset + sizeof(juint); template @@ -234,21 +249,21 @@ return read_data(data + duration_offset); } -static bool is_flushpoint(const u1* data) { - return read_data(data + flushpoint_offset) == (juint)1; +static u1 checkpoint_type(const u1* data) { + return read_data(data + checkpoint_type_offset); } static juint number_of_types(const u1* data) { return read_data(data + types_offset); } -static void write_checkpoint_header(JfrChunkWriter& cw, int64_t offset_prev_cp_event, const u1* data) { +static void write_checkpoint_header(JfrChunkWriter& cw, int64_t delta_to_last_checkpoint, const u1* data) { cw.reserve(sizeof(u4)); cw.write(EVENT_CHECKPOINT); cw.write(starttime(data)); cw.write(duration(data)); - cw.write(offset_prev_cp_event); - cw.write(is_flushpoint(data)); + cw.write(delta_to_last_checkpoint); + cw.write(checkpoint_type(data)); cw.write(number_of_types(data)); } @@ -261,9 +276,9 @@ assert(data != NULL, "invariant"); const int64_t event_begin = cw.current_offset(); const int64_t last_checkpoint_event = cw.last_checkpoint_offset(); - const int64_t delta = last_checkpoint_event == 0 ? 0 : last_checkpoint_event - event_begin; + const int64_t delta_to_last_checkpoint = last_checkpoint_event == 0 ? 0 : last_checkpoint_event - event_begin; const int64_t checkpoint_size = total_size(data); - write_checkpoint_header(cw, delta, data); + write_checkpoint_header(cw, delta_to_last_checkpoint, data); write_checkpoint_content(cw, data, checkpoint_size); const int64_t event_size = cw.current_offset() - event_begin; cw.write_padded_at_offset(event_size, event_begin); @@ -305,13 +320,13 @@ typedef CheckpointWriteOp WriteOperation; typedef ReleaseOp CheckpointReleaseOperation; -template