--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Wed Jul 03 11:43:01 2019 +0800
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Wed Jul 03 11:34:46 2019 +0200
@@ -181,21 +181,18 @@
}
};
-void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool resume) {
- assert(class_unload ? SafepointSynchronize::is_at_safepoint() : LeakProfiler::is_suspended(), "invariant");
-
+void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload) {
if (!writer.has_data()) {
- if (!class_unload) {
- LeakProfiler::resume();
- }
- assert(LeakProfiler::is_running(), "invariant");
return;
}
assert(writer.has_data(), "invariant");
const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob();
- const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
+ // Class unload implies a safepoint.
+ // Not class unload implies the object sampler is locked, because it was claimed exclusively earlier.
+ // Therefore: direct access the object sampler instance is safe.
+ const ObjectSampler* const object_sampler = ObjectSampler::sampler();
assert(object_sampler != NULL, "invariant");
ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
@@ -203,80 +200,71 @@
CheckpointInstall install(h_cp);
if (class_unload) {
- if (last != NULL) {
- // all samples need the class unload information
- do_samples(last, NULL, install);
- }
- assert(LeakProfiler::is_running(), "invariant");
+ // all samples need class unload information
+ do_samples(last, NULL, install);
return;
}
// only new samples since last resolved checkpoint
if (last != last_resolved) {
do_samples(last, last_resolved, install);
- if (resume) {
- const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last);
- }
- }
- assert(LeakProfiler::is_suspended(), "invariant");
- if (resume) {
- LeakProfiler::resume();
- assert(LeakProfiler::is_running(), "invariant");
+ const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last);
}
}
-void ObjectSampleCheckpoint::write(const EdgeStore* edge_store, bool emit_all, Thread* thread) {
+void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
+ assert(sampler != NULL, "invariant");
assert(edge_store != NULL, "invariant");
assert(thread != NULL, "invariant");
+
static bool types_registered = false;
if (!types_registered) {
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
types_registered = true;
}
- const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
+
+ const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
+ ObjectSample* const last = const_cast<ObjectSample*>(sampler->last());
{
JfrCheckpointWriter writer(false, false, thread);
CheckpointWrite checkpoint_write(writer, last_sweep);
do_samples(last, NULL, checkpoint_write);
}
+
CheckpointStateReset state_reset(last_sweep);
do_samples(last, NULL, state_reset);
+
if (!edge_store->is_empty()) {
// java object and chain representations
JfrCheckpointWriter writer(false, true, thread);
ObjectSampleWriter osw(writer, edge_store);
- edge_store->iterate_edges(osw);
+ edge_store->iterate(osw);
}
}
-WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(JfrStackTraceRepository& repo) :
- _stack_trace_repo(repo) {
+int ObjectSampleCheckpoint::mark(ObjectSampler* object_sampler, ObjectSampleMarker& marker, bool emit_all) {
+ assert(object_sampler != NULL, "invariant");
+ ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
+ if (last == NULL) {
+ return 0;
+ }
+ const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
+ SampleMark mark(marker, last_sweep);
+ do_samples(last, NULL, mark);
+ return mark.count();
}
+WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo) :
+ _sampler(sampler), _stack_trace_repo(repo) {}
+
bool WriteObjectSampleStacktrace::process() {
- assert(SafepointSynchronize::is_at_safepoint(), "invariant");
- if (!LeakProfiler::is_running()) {
- return true;
- }
- // Suspend the LeakProfiler subsystem
- // to ensure stable samples even
- // after we return from the safepoint.
- LeakProfiler::suspend();
- assert(!LeakProfiler::is_running(), "invariant");
- assert(LeakProfiler::is_suspended(), "invariant");
+ assert(LeakProfiler::is_running(), "invariant");
+ assert(_sampler != NULL, "invariant");
- const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- assert(LeakProfiler::is_suspended(), "invariant");
-
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
- const ObjectSample* const last_resolved = object_sampler->last_resolved();
+ ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
+ const ObjectSample* const last_resolved = _sampler->last_resolved();
if (last == last_resolved) {
- assert(LeakProfiler::is_suspended(), "invariant");
return true;
}
@@ -294,27 +282,13 @@
}
if (count == 0) {
writer.set_context(ctx);
- assert(LeakProfiler::is_suspended(), "invariant");
return true;
}
assert(count > 0, "invariant");
writer.write_count((u4)count, count_offset);
JfrStackTraceRepository::write_metadata(writer);
- ObjectSampleCheckpoint::install(writer, false, false);
- assert(LeakProfiler::is_suspended(), "invariant");
+ // install the stacktrace checkpoint information to the candidates
+ ObjectSampleCheckpoint::install(writer, false);
return true;
}
-
-int ObjectSampleCheckpoint::mark(ObjectSampleMarker& marker, bool emit_all) {
- const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
- assert(object_sampler != NULL, "invariant");
- ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
- if (last == NULL) {
- return 0;
- }
- const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
- SampleMark mark(marker, last_sweep);
- do_samples(last, NULL, mark);
- return mark.count();
-}