# HG changeset patch # User mgronlun # Date 1567075985 -7200 # Node ID 9c150f2b1fea211bb92e10dd9aae13afe860f987 # Parent 6598f2825b1f8ad2a9e3d9fc509a243d73e85a3d optimizations for old object sample metadata diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -106,28 +106,28 @@ return unloaded_thread_id_set != NULL && predicate(unloaded_thread_id_set, tid); } -static GrowableArray* unloaded_set = NULL; +static GrowableArray* unloaded_klass_set = NULL; -static void sort_unloaded_set() { - if (unloaded_set != NULL) { - sort_array(unloaded_set); +static void sort_unloaded_klass_set() { + if (unloaded_klass_set != NULL) { + sort_array(unloaded_klass_set); } } -static void add_to_unloaded_set(traceid klass_id) { - if (unloaded_set == NULL) { - unloaded_set = c_heap_allocate_array(); +static void add_to_unloaded_klass_set(traceid klass_id) { + if (unloaded_klass_set == NULL) { + unloaded_klass_set = c_heap_allocate_array(); } - unloaded_set->append(klass_id); + unloaded_klass_set->append(klass_id); } void ObjectSampleCheckpoint::on_klass_unload(const Klass* k) { assert(k != NULL, "invariant"); - add_to_unloaded_set(TRACE_ID(k)); + add_to_unloaded_klass_set(TRACE_ID(k)); } static bool is_klass_unloaded(traceid klass_id) { - return unloaded_set != NULL && predicate(unloaded_set, klass_id); + return unloaded_klass_set != NULL && predicate(unloaded_klass_set, klass_id); } static GrowableArray* id_set = NULL; @@ -164,15 +164,12 @@ } template -static void iterate_samples(Processor& processor, bool all = false, bool update_last_resolved = false) { +static void iterate_samples(Processor& processor, bool all = false) { ObjectSampler* const sampler = ObjectSampler::sampler(); assert(sampler != NULL, "invariant"); ObjectSample* const last = sampler->last(); assert(last != NULL, "invariant"); do_samples(last, all ? NULL : sampler->last_resolved(), processor); - if (update_last_resolved) { - sampler->set_last_resolved(last); - } } void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) { @@ -182,66 +179,41 @@ } } -class CheckpointInstall { +class CheckpointBlobInstaller { private: const JfrCheckpointBlobHandle& _cp; public: - CheckpointInstall(const JfrCheckpointBlobHandle& cp) : _cp(cp) {} + CheckpointBlobInstaller(const JfrCheckpointBlobHandle& cp) : _cp(cp) {} void sample_do(ObjectSample* sample) { - assert(sample != NULL, "invariant"); if (!sample->is_dead()) { sample->set_klass_checkpoint(_cp); } } }; -static void install_blob(JfrCheckpointWriter& writer) { +static void install_checkpoint_blob(JfrCheckpointWriter& writer) { assert(writer.has_data(), "invariant"); const JfrCheckpointBlobHandle h_cp = writer.copy(); - CheckpointInstall install(h_cp); - iterate_samples(install, true, false); + CheckpointBlobInstaller installer(h_cp); + iterate_samples(installer, true); } void ObjectSampleCheckpoint::on_type_set_unload(JfrCheckpointWriter& writer) { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); assert(LeakProfiler::is_running(), "invariant"); if (writer.has_data() && ObjectSampler::sampler()->last() != NULL) { - install_blob(writer); + install_checkpoint_blob(writer); } } -class ObjectResolver { - public: - ObjectResolver() {} - void sample_do(ObjectSample* sample) { - assert(sample != NULL, "invariant"); - const traceid klass_id = sample->_klass_id; - if (klass_id != 0 || sample->is_dead() || is_klass_unloaded(klass_id)) { - return; - } - sample->_klass_id = JfrTraceId::use(sample->klass()); - } -}; - -void ObjectSampleCheckpoint::resolve_sampled_objects() { - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - assert(LeakProfiler::is_running(), "invariant"); - if (ObjectSampler::sampler()->last() == NULL) { - return; - } - ObjectResolver resolver; - iterate_samples(resolver, false, true); -} - -class SampleMark { +class SampleMarker { private: ObjectSampleMarker& _marker; jlong _last_sweep; int _count; public: - SampleMark(ObjectSampleMarker& marker, jlong last_sweep) : _marker(marker), _last_sweep(last_sweep), _count(0) {} + SampleMarker(ObjectSampleMarker& marker, jlong last_sweep) : _marker(marker), _last_sweep(last_sweep), _count(0) {} void sample_do(ObjectSample* sample) { - assert(sample != NULL, "invariant"); if (sample->is_alive_and_older_than(_last_sweep)) { _marker.mark(sample->object()); ++_count; @@ -257,17 +229,9 @@ if (sampler->last() == NULL) { return 0; } - SampleMark mark(marker, emit_all ? max_jlong : sampler->last_sweep().value()); - iterate_samples(mark, true, false); - return mark.count(); -} - -void ObjectSampleCheckpoint::tag(const ObjectSample* sample) { - assert(sample != NULL, "invariant"); - const traceid klass_id = sample->_klass_id; - if (should_process(sample->_klass_id)) { - JfrTraceId::use(sample->klass()); - } + SampleMarker sample_marker(marker, emit_all ? max_jlong : sampler->last_sweep().value()); + iterate_samples(sample_marker, true); + return sample_marker.count(); } #ifdef ASSERT @@ -368,13 +332,12 @@ return sample->has_stack_trace_id() && !sample->is_dead(); } -class Tagger { +class StackTraceTagger { private: JfrStackTraceRepository& _stack_trace_repo; public: - Tagger(JfrStackTraceRepository& stack_trace_repo) : _stack_trace_repo(stack_trace_repo) {} + StackTraceTagger(JfrStackTraceRepository& stack_trace_repo) : _stack_trace_repo(stack_trace_repo) {} void sample_do(ObjectSample* sample) { - ObjectSampleCheckpoint::tag(sample); if (stack_trace_precondition(sample)) { assert(sample->stack_trace_id() == sample->stack_trace()->id(), "invariant"); ObjectSampleCheckpoint::tag(sample->stack_trace(), NULL); @@ -382,22 +345,21 @@ } }; -static void tag_old_traces(ObjectSample* last_resolved, JfrStackTraceRepository& stack_trace_repo) { +static void tag_old_stack_traces(ObjectSample* last_resolved, JfrStackTraceRepository& stack_trace_repo) { assert(last_resolved != NULL, "invariant"); assert(stack_trace_id_set != NULL, "invariant"); assert(stack_trace_id_set->is_empty(), "invariant"); - Tagger tagger(stack_trace_repo); + StackTraceTagger tagger(stack_trace_repo); do_samples(last_resolved, NULL, tagger); } -class StackTraceInstall { +class StackTraceResolver { private: JfrStackTraceRepository& _stack_trace_repo; public: - StackTraceInstall(JfrStackTraceRepository& stack_trace_repo) : _stack_trace_repo(stack_trace_repo) {} + StackTraceResolver(JfrStackTraceRepository& stack_trace_repo) : _stack_trace_repo(stack_trace_repo) {} void install_to_sample(ObjectSample* sample, const JfrStackTrace* stack_trace); void sample_do(ObjectSample* sample) { - ObjectSampleCheckpoint::tag(sample); if (stack_trace_precondition(sample)) { install_to_sample(sample, _stack_trace_repo.lookup(sample->stack_trace_hash(), sample->stack_trace_id())); } @@ -405,53 +367,57 @@ }; #ifdef ASSERT -static void validate_stack_trace(const ObjectSample* sample, const JfrStackTrace* trace) { +static void validate_stack_trace(const ObjectSample* sample, const JfrStackTrace* stack_trace) { assert(sample != NULL, "invariant"); - assert(trace != NULL, "invariant"); - assert(trace->hash() == sample->stack_trace_hash(), "invariant"); - assert(trace->id() == sample->stack_trace_id(), "invariant"); + assert(!sample->is_dead(), "invariant"); + assert(stack_trace != NULL, "invariant"); + assert(stack_trace->hash() == sample->stack_trace_hash(), "invariant"); + assert(stack_trace->id() == sample->stack_trace_id(), "invariant"); } #endif -void StackTraceInstall::install_to_sample(ObjectSample* sample, const JfrStackTrace* stack_trace) { - assert(sample != NULL, "invariant"); - assert(stack_trace != NULL, "invariant"); +void StackTraceResolver::install_to_sample(ObjectSample* sample, const JfrStackTrace* stack_trace) { DEBUG_ONLY(validate_stack_trace(sample, stack_trace)); - JfrStackTrace* const sample_trace = const_cast(sample->stack_trace()); - if (sample_trace != NULL && sample_trace->id() != stack_trace->id()) { - *sample_trace = *stack_trace; // copy + JfrStackTrace* const sample_stack_trace = const_cast(sample->stack_trace()); + if (sample_stack_trace != NULL) { + if (sample_stack_trace->id() != stack_trace->id()) { + *sample_stack_trace = *stack_trace; // copy + } } else { sample->set_stack_trace(new JfrStackTrace(stack_trace->id(), *stack_trace, NULL)); // new } assert(sample->stack_trace() != NULL, "invariant"); } -static void install_new_stack_traces(JfrStackTraceRepository& stack_trace_repo) { - StackTraceInstall stack_trace_install(stack_trace_repo); - iterate_samples(stack_trace_install); - stack_trace_id_set->clear(); -} - static void allocate_traceid_working_sets() { const int set_size = JfrOptionSet::old_object_queue_size(); stack_trace_id_set = resource_allocate_array(set_size); id_set = resource_allocate_array(set_size); - sort_unloaded_set(); + sort_unloaded_klass_set(); +} + +static void resolve_stack_traces(JfrStackTraceRepository& stack_trace_repo) { + StackTraceResolver stack_trace_resolver(stack_trace_repo); + iterate_samples(stack_trace_resolver); } // caller needs ResourceMark -void ObjectSampleCheckpoint::rotate(const ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) { +void ObjectSampleCheckpoint::on_rotation(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) { assert(sampler != NULL, "invariant"); assert(LeakProfiler::is_running(), "invariant"); - if (sampler->last() == NULL) { + const ObjectSample* const last = sampler->last(); + if (last == NULL) { // nothing to process return; } - allocate_traceid_working_sets(); - install_new_stack_traces(stack_trace_repo); ObjectSample* const last_resolved = const_cast(sampler->last_resolved()); if (last_resolved != NULL) { - tag_old_traces(last_resolved, stack_trace_repo); + allocate_traceid_working_sets(); + tag_old_stack_traces(last_resolved, stack_trace_repo); + } + if (last != last_resolved) { + resolve_stack_traces(stack_trace_repo); + sampler->set_last_resolved(last); } } @@ -516,30 +482,28 @@ write_klass_blob(sample, writer); } -class CheckpointWrite { +class CheckpointBlobWriter { private: const ObjectSampler* _sampler; JfrCheckpointWriter& _writer; const jlong _last_sweep; public: - CheckpointWrite(const ObjectSampler* sampler, JfrCheckpointWriter& writer, jlong last_sweep) : + CheckpointBlobWriter(const ObjectSampler* sampler, JfrCheckpointWriter& writer, jlong last_sweep) : _sampler(sampler), _writer(writer), _last_sweep(last_sweep) {} void sample_do(ObjectSample* sample) { - assert(sample != NULL, "invariant"); if (sample->is_alive_and_older_than(_last_sweep)) { write_blobs(sample, _writer); } } }; -class CheckpointStateReset { +class CheckpointBlobStateReset { private: const ObjectSampler* _sampler; const jlong _last_sweep; public: - CheckpointStateReset(const ObjectSampler* sampler, jlong last_sweep) : _sampler(sampler), _last_sweep(last_sweep) {} + CheckpointBlobStateReset(const ObjectSampler* sampler, jlong last_sweep) : _sampler(sampler), _last_sweep(last_sweep) {} void sample_do(ObjectSample* sample) { - assert(sample != NULL, "invariant"); if (sample->is_alive_and_older_than(_last_sweep)) { reset_blob_write_state(sample); } @@ -547,32 +511,33 @@ }; static void reset_write_state_for_blobs(const ObjectSampler* sampler, jlong last_sweep) { - CheckpointStateReset state_reset(sampler, last_sweep); - iterate_samples(state_reset, true, false); + CheckpointBlobStateReset state_reset(sampler, last_sweep); + iterate_samples(state_reset, true); } static void write_sample_blobs(const ObjectSampler* sampler, jlong last_sweep, Thread* thread) { JfrCheckpointWriter writer(thread, false); - CheckpointWrite checkpoint_write(sampler, writer, last_sweep); - iterate_samples(checkpoint_write, true, false); + CheckpointBlobWriter cbw(sampler, writer, last_sweep); + iterate_samples(cbw, true); reset_write_state_for_blobs(sampler, last_sweep); } -class StackTraceWrite { +class StackTraceWriter { private: JfrStackTraceRepository& _stack_trace_repo; JfrCheckpointWriter& _writer; const jlong _last_sweep; int _count; public: - StackTraceWrite(JfrStackTraceRepository& stack_trace_repo, JfrCheckpointWriter& writer, jlong last_sweep) : + StackTraceWriter(JfrStackTraceRepository& stack_trace_repo, JfrCheckpointWriter& writer, jlong last_sweep) : _stack_trace_repo(stack_trace_repo), _writer(writer), _last_sweep(last_sweep), _count(0) {} void sample_do(ObjectSample* sample) { - ObjectSampleCheckpoint::tag(sample); - if (stack_trace_precondition(sample) && sample->is_alive_and_older_than(_last_sweep)) { - assert(sample->stack_trace_id() == sample->stack_trace()->id(), "invariant"); - if (ObjectSampleCheckpoint::tag(sample->stack_trace(), &_writer)) { - ++_count; + if (sample->is_alive_and_older_than(_last_sweep)) { + if (stack_trace_precondition(sample)) { + assert(sample->stack_trace_id() == sample->stack_trace()->id(), "invariant"); + if (ObjectSampleCheckpoint::tag(sample->stack_trace(), &_writer)) { + ++_count; + } } } } @@ -584,12 +549,12 @@ static void write_and_tag_stack_traces(const ObjectSampler* sampler, JfrStackTraceRepository& repo, jlong last_sweep, Thread* thread) { assert(sampler != NULL, "invariant"); allocate_traceid_working_sets(); - install_new_stack_traces(repo); + resolve_stack_traces(repo); JfrCheckpointWriter writer(thread); const JfrCheckpointContext ctx = writer.context(); writer.write_type(TYPE_STACKTRACE); const jlong count_offset = writer.reserve(sizeof(u4)); - StackTraceWrite sw(repo, writer, last_sweep); + StackTraceWriter sw(repo, writer, last_sweep); do_samples(sampler->last(), NULL, sw); if (sw.count() == 0) { writer.set_context(ctx); diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -43,9 +43,7 @@ static void on_klass_unload(const Klass* k); static void on_type_set_unload(JfrCheckpointWriter& writer); static void on_thread_exit(JavaThread* jt); - static void resolve_sampled_objects(); - static void rotate(const ObjectSampler* sampler, JfrStackTraceRepository& repo); - static void tag(const ObjectSample* sample); + static void on_rotation(ObjectSampler* sampler, JfrStackTraceRepository& repo); static bool tag(const JfrStackTrace* trace, JfrCheckpointWriter* writer = NULL); static int save_mark_words(const ObjectSampler* sampler, ObjectSampleMarker& marker, bool emit_all); static void write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread); diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/leakprofiler/sampling/objectSample.hpp --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -56,7 +56,6 @@ Ticks _allocation_time; traceid _stack_trace_id; traceid _thread_id; - mutable traceid _klass_id; int _index; size_t _span; size_t _allocated; @@ -80,7 +79,6 @@ void reset() { set_stack_trace_id(0); set_stack_trace_hash(0); - _klass_id = 0; release_references(); _dead = false; } @@ -101,7 +99,6 @@ _allocation_time(), _stack_trace_id(0), _thread_id(0), - _klass_id(0), _index(0), _span(0), _allocated(0), diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -110,6 +110,9 @@ } const JfrThreadLocal* const tl = thread->jfr_thread_local(); assert(tl != NULL, "invariant"); + if (tl->is_excluded()) { + return 0; + } if (!tl->has_thread_checkpoint()) { JfrCheckpointManager::create_thread_checkpoint(thread); } diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -439,16 +439,24 @@ JfrTypeManager::write_type_set_for_unloaded_classes(); } -bool JfrCheckpointManager::is_type_set_checkpoint_required() const { +bool JfrCheckpointManager::is_type_set_required() { return JfrTraceIdEpoch::is_klass_tagged_in_epoch(); } +bool JfrCheckpointManager::is_constant_set_required() { + return JfrTypeManager::is_new_constant_registered(); +} + size_t JfrCheckpointManager::flush_type_set() { const size_t elements = JfrTypeManager::flush_type_set(); flush(); return elements; } +void JfrCheckpointManager::flush_constant_set() { + flush(); +} + void JfrCheckpointManager::create_thread_checkpoint(Thread* t) { JfrTypeManager::create_thread_checkpoint(t); } diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -88,6 +88,8 @@ bool use_epoch_transition_mspace(const Thread* t) const; void notify_threads(); void notify_types_on_rotation(); + bool is_type_set_required(); + bool is_constant_set_required(); JfrCheckpointManager(JfrChunkWriter& cw); ~JfrCheckpointManager(); @@ -99,8 +101,8 @@ public: void register_service_thread(const Thread* t); - bool is_type_set_checkpoint_required() const; size_t flush_type_set(); + void flush_constant_set(); static void write_type_set_for_unloaded_classes(); static void create_thread_checkpoint(Thread* t); static void write_thread_checkpoint(Thread* t); diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -134,11 +134,15 @@ } } +static bool new_registration = false; + void JfrTypeManager::write_types(JfrCheckpointWriter& writer) { + SerializerRegistrationGuard guard; const Iterator iter(types); while (iter.has_next()) { iter.next()->invoke(writer); } + new_registration = false; } static void serialize_threads(JfrCheckpointWriter& writer) { @@ -235,8 +239,9 @@ assert(!types.in_list(registration), "invariant"); DEBUG_ONLY(assert_not_registered_twice(id, types);) if (Jfr::is_recording()) { - JfrCheckpointWriter writer; + JfrCheckpointWriter writer(STATICS); registration->invoke(writer); + new_registration = true; } types.prepend(registration); return true; @@ -268,3 +273,12 @@ SerializerRegistrationGuard guard; return register_type(id, permit_cache, serializer); } + +bool JfrTypeManager::is_new_constant_registered() { + if (new_registration) { + SerializerRegistrationGuard guard; + new_registration = false; + return true; + } + return false; +} diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.hpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -33,6 +33,7 @@ public: static bool initialize(); static void clear(); + static bool is_new_constant_registered(); static void write_types(JfrCheckpointWriter& writer); static void write_threads(JfrCheckpointWriter& writer); static void notify_types_on_rotation(); diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -614,8 +614,11 @@ if (_string_pool.is_modified()) { total_elements += flush_stringpool(_string_pool, _chunkwriter); } - if (_checkpoint_manager.is_type_set_checkpoint_required()) { + if (_checkpoint_manager.is_type_set_required()) { total_elements += flush_typeset(_checkpoint_manager, _chunkwriter); + } else if (_checkpoint_manager.is_constant_set_required()) { + // don't tally this, it is only in order to flush the waiting constants + _checkpoint_manager.flush_constant_set(); } return total_elements; } @@ -653,7 +656,7 @@ if (LeakProfiler::is_running()) { // Exclusive access to the object sampler instance. // The sampler is released (unlocked) later in post_safepoint_write. - ObjectSampleCheckpoint::rotate(ObjectSampler::acquire(), _stack_trace_repository); + ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository); } _checkpoint_manager.notify_types_on_rotation(); _storage.write(); @@ -681,9 +684,6 @@ if (_string_pool.is_modified()) { flush_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); } - if (LeakProfiler::is_running()) { - ObjectSampleCheckpoint::resolve_sampled_objects(); - } _storage.write_at_safepoint(); _checkpoint_manager.notify_threads(); _checkpoint_manager.shift_epoch(); diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.hpp --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -69,7 +69,7 @@ friend class ObjectSampler; friend class OSThreadSampler; friend class ProcessStackTrace; - friend class StackTraceInstall; + friend class StackTraceResolver; friend class StackTraceWrite; private: diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Thu Aug 29 12:53:05 2019 +0200 @@ -177,18 +177,15 @@ return tid; } -traceid JfrStackTraceRepository::record_and_cache(JavaThread* thread, int skip /* 0 */) { +void JfrStackTraceRepository::record_and_cache(JavaThread* thread, int skip /* 0 */) { + assert(thread != NULL, "invariant"); JfrThreadLocal* const tl = thread->jfr_thread_local(); assert(tl != NULL, "invariant"); - if (tl->has_cached_stack_trace()) { - return tl->cached_stack_trace_id(); - } + assert(!tl->has_cached_stack_trace(), "invariant"); JfrStackTrace stacktrace(tl->stackframes(), tl->stackdepth()); stacktrace.record_safe(thread, skip); assert(stacktrace.hash() != 0, "invariant"); - const traceid id = instance().add(stacktrace); - tl->set_cached_stack_trace_id(id, stacktrace.hash()); - return id; + tl->set_cached_stack_trace_id(instance().add(stacktrace), stacktrace.hash()); } traceid JfrStackTraceRepository::add_trace(const JfrStackTrace& stacktrace) { diff -r 6598f2825b1f -r 9c150f2b1fea src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Thu Aug 29 03:29:45 2019 +0200 +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.hpp Thu Aug 29 12:53:05 2019 +0200 @@ -40,7 +40,7 @@ friend class JfrThreadSampleClosure; friend class ObjectSampleCheckpoint; friend class ObjectSampler; - friend class StackTraceInstall; + friend class StackTraceResolver; friend class StackTraceWrite; friend class WriteStackTraceRepository; @@ -71,7 +71,7 @@ public: static traceid record(Thread* thread, int skip = 0); - static traceid record_and_cache(JavaThread* thread, int skip = 0); + static void record_and_cache(JavaThread* thread, int skip = 0); }; #endif // SHARE_JFR_RECORDER_STACKTRACE_JFRSTACKTRACEREPOSITORY_HPP