--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Fri Aug 23 18:47:55 2019 +0200
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Sat Aug 24 14:30:27 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,7 @@
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/leakprofiler/utilities/rootType.hpp"
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
-#include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
-#include "jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp"
+#include "jfr/writers/jfrTypeWriterHost.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "utilities/growableArray.hpp"
@@ -159,6 +158,11 @@
return stored->_field_modifiers == query->_field_modifiers;
}
+ void unlink(FieldInfoEntry* entry) {
+ assert(entry != NULL, "invariant");
+ // nothing
+ }
+
public:
FieldTable() : _table(new FieldInfoTable(this)) {}
~FieldTable() {
@@ -196,7 +200,7 @@
static FieldTable* field_infos = NULL;
static RootDescriptionInfo* root_infos = NULL;
-int __write_sample_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* si) {
+int __write_sample_info__(JfrCheckpointWriter* writer, const void* si) {
assert(writer != NULL, "invariant");
assert(si != NULL, "invariant");
const OldObjectSampleInfo* const oosi = (const OldObjectSampleInfo*)si;
@@ -211,17 +215,17 @@
return 1;
}
-typedef JfrArtifactWriterImplHost<const OldObjectSampleInfo*, __write_sample_info__> SampleWriterImpl;
-typedef JfrArtifactWriterHost<SampleWriterImpl, TYPE_OLDOBJECT> SampleWriter;
+typedef JfrTypeWriterImplHost<const OldObjectSampleInfo*, __write_sample_info__> SampleWriterImpl;
+typedef JfrTypeWriterHost<SampleWriterImpl, TYPE_OLDOBJECT> SampleWriter;
static void write_sample_infos(JfrCheckpointWriter& writer) {
if (sample_infos != NULL) {
- SampleWriter sw(&writer, NULL, false);
+ SampleWriter sw(&writer);
sample_infos->iterate(sw);
}
}
-int __write_reference_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* ri) {
+int __write_reference_info__(JfrCheckpointWriter* writer, const void* ri) {
assert(writer != NULL, "invariant");
assert(ri != NULL, "invariant");
const ReferenceInfo* const ref_info = (const ReferenceInfo*)ri;
@@ -233,17 +237,17 @@
return 1;
}
-typedef JfrArtifactWriterImplHost<const ReferenceInfo*, __write_reference_info__> ReferenceWriterImpl;
-typedef JfrArtifactWriterHost<ReferenceWriterImpl, TYPE_REFERENCE> ReferenceWriter;
+typedef JfrTypeWriterImplHost<const ReferenceInfo*, __write_reference_info__> ReferenceWriterImpl;
+typedef JfrTypeWriterHost<ReferenceWriterImpl, TYPE_REFERENCE> ReferenceWriter;
static void write_reference_infos(JfrCheckpointWriter& writer) {
if (ref_infos != NULL) {
- ReferenceWriter rw(&writer, NULL, false);
+ ReferenceWriter rw(&writer);
ref_infos->iterate(rw);
}
}
-int __write_array_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* ai) {
+int __write_array_info__(JfrCheckpointWriter* writer, const void* ai) {
assert(writer != NULL, "invariant");
assert(ai != NULL, "invariant");
const ObjectSampleArrayInfo* const osai = (const ObjectSampleArrayInfo*)ai;
@@ -270,17 +274,17 @@
return array_infos->store(osai);
}
-typedef JfrArtifactWriterImplHost<const ObjectSampleArrayInfo*, __write_array_info__> ArrayWriterImpl;
-typedef JfrArtifactWriterHost<ArrayWriterImpl, TYPE_OLDOBJECTARRAY> ArrayWriter;
+typedef JfrTypeWriterImplHost<const ObjectSampleArrayInfo*, __write_array_info__> ArrayWriterImpl;
+typedef JfrTypeWriterHost<ArrayWriterImpl, TYPE_OLDOBJECTARRAY> ArrayWriter;
static void write_array_infos(JfrCheckpointWriter& writer) {
if (array_infos != NULL) {
- ArrayWriter aw(&writer, NULL, false);
+ ArrayWriter aw(&writer);
array_infos->iterate(aw);
}
}
-int __write_field_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* fi) {
+int __write_field_info__(JfrCheckpointWriter* writer, const void* fi) {
assert(writer != NULL, "invariant");
assert(fi != NULL, "invariant");
const FieldTable::FieldInfoEntry* field_info_entry = (const FieldTable::FieldInfoEntry*)fi;
@@ -314,12 +318,12 @@
return field_infos->store(osfi);
}
-typedef JfrArtifactWriterImplHost<const FieldTable::FieldInfoEntry*, __write_field_info__> FieldWriterImpl;
-typedef JfrArtifactWriterHost<FieldWriterImpl, TYPE_OLDOBJECTFIELD> FieldWriter;
+typedef JfrTypeWriterImplHost<const FieldTable::FieldInfoEntry*, __write_field_info__> FieldWriterImpl;
+typedef JfrTypeWriterHost<FieldWriterImpl, TYPE_OLDOBJECTFIELD> FieldWriter;
static void write_field_infos(JfrCheckpointWriter& writer) {
if (field_infos != NULL) {
- FieldWriter fw(&writer, NULL, false);
+ FieldWriter fw(&writer);
field_infos->iterate(fw);
}
}
@@ -339,7 +343,7 @@
return description.description();
}
-int __write_root_description_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* di) {
+int __write_root_description_info__(JfrCheckpointWriter* writer, const void* di) {
assert(writer != NULL, "invariant");
assert(di != NULL, "invariant");
const ObjectSampleRootDescriptionInfo* const osdi = (const ObjectSampleRootDescriptionInfo*)di;
@@ -350,7 +354,7 @@
return 1;
}
-static traceid get_root_description_info_id(const Edge& edge, traceid id) {
+static traceid get_gc_root_description_info_id(const Edge& edge, traceid id) {
assert(edge.is_root(), "invariant");
if (EdgeUtils::is_leak_edge(edge)) {
return 0;
@@ -366,8 +370,8 @@
return root_infos->store(oodi);
}
-typedef JfrArtifactWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
-typedef JfrArtifactWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
+typedef JfrTypeWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
+typedef JfrTypeWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
int _edge_reference_compare_(uintptr_t lhs, uintptr_t rhs) {
@@ -513,12 +517,12 @@
RootResolutionSet rrs(root_infos);
RootResolver::resolve(rrs);
// write roots
- RootDescriptionWriter rw(&writer, NULL, false);
+ RootDescriptionWriter rw(&writer);
root_infos->iterate(rw);
}
}
-static void add_old_object_sample_info(const Edge* current, traceid id) {
+static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
assert(current != NULL, "invariant");
if (sample_infos == NULL) {
sample_infos = new SampleInfo();
@@ -528,11 +532,11 @@
assert(oosi != NULL, "invariant");
oosi->_id = id;
oosi->_data._object = current->pointee();
- oosi->_data._reference_id = current->is_root() ? (traceid)0 : id;
+ oosi->_data._reference_id = current->parent() == NULL ? (traceid)0 : id;
sample_infos->store(oosi);
}
-static void add_reference_info(const RoutableEdge* current, traceid id, traceid parent_id) {
+static void add_reference_info(const StoredEdge* current, traceid id, traceid parent_id) {
assert(current != NULL, "invariant");
if (ref_infos == NULL) {
ref_infos = new RefInfo();
@@ -544,37 +548,43 @@
ri->_id = id;
ri->_data._array_info_id = !current->is_skip_edge() ? get_array_info_id(*current, id) : 0;
- ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ?
- get_field_info_id(*current) : (traceid)0;
+ ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ? get_field_info_id(*current) : (traceid)0;
ri->_data._old_object_sample_id = parent_id;
ri->_data._skip = current->skip_length();
ref_infos->store(ri);
}
-static traceid add_root_info(const Edge* root, traceid id) {
- assert(root != NULL, "invariant");
- assert(root->is_root(), "invariant");
- return get_root_description_info_id(*root, id);
+static bool is_gc_root(const StoredEdge* current) {
+ assert(current != NULL, "invariant");
+ return current->parent() == NULL && current->gc_root_id() != 0;
}
-void ObjectSampleWriter::write(const RoutableEdge* edge) {
+static traceid add_gc_root_info(const StoredEdge* root, traceid id) {
+ assert(root != NULL, "invariant");
+ assert(is_gc_root(root), "invariant");
+ return get_gc_root_description_info_id(*root, id);
+}
+
+void ObjectSampleWriter::write(const StoredEdge* edge) {
assert(edge != NULL, "invariant");
const traceid id = _store->get_id(edge);
add_old_object_sample_info(edge, id);
- const RoutableEdge* parent = edge->logical_parent();
+ const StoredEdge* const parent = edge->parent();
if (parent != NULL) {
add_reference_info(edge, id, _store->get_id(parent));
} else {
- assert(edge->is_root(), "invariant");
- add_root_info(edge, id);
+ if (is_gc_root(edge)) {
+ assert(edge->gc_root_id() == id, "invariant");
+ add_gc_root_info(edge, id);
+ }
}
}
-ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, const EdgeStore* store) :
+ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
_writer(writer),
_store(store) {
assert(store != NULL, "invariant");
- assert(store->number_of_entries() > 0, "invariant");
+ assert(!store->is_empty(), "invariant");
sample_infos = NULL;
ref_infos = NULL;
array_infos = NULL;
@@ -590,26 +600,7 @@
write_root_descriptors(_writer);
}
-void ObjectSampleWriter::write_chain(const RoutableEdge& edge) {
- assert(EdgeUtils::is_leak_edge(edge), "invariant");
- if (edge.processed()) {
- return;
- }
- EdgeUtils::collapse_chain(edge);
- const RoutableEdge* current = &edge;
- while (current != NULL) {
- if (current->processed()) {
- return;
- }
- write(current);
- current->set_processed();
- current = current->logical_parent();
- }
-}
-
-bool ObjectSampleWriter::operator()(const RoutableEdge& edge) {
- if (EdgeUtils::is_leak_edge(edge)) {
- write_chain(edge);
- }
+bool ObjectSampleWriter::operator()(StoredEdge& e) {
+ write(&e);
return true;
}