diff -r 84ef29ccac56 -r 00860d9caf4d src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp --- 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 SampleWriterImpl; -typedef JfrArtifactWriterHost SampleWriter; +typedef JfrTypeWriterImplHost SampleWriterImpl; +typedef JfrTypeWriterHost 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 ReferenceWriterImpl; -typedef JfrArtifactWriterHost ReferenceWriter; +typedef JfrTypeWriterImplHost ReferenceWriterImpl; +typedef JfrTypeWriterHost 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 ArrayWriterImpl; -typedef JfrArtifactWriterHost ArrayWriter; +typedef JfrTypeWriterImplHost ArrayWriterImpl; +typedef JfrTypeWriterHost 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 FieldWriterImpl; -typedef JfrArtifactWriterHost FieldWriter; +typedef JfrTypeWriterImplHost FieldWriterImpl; +typedef JfrTypeWriterHost 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 RootDescriptionWriterImpl; -typedef JfrArtifactWriterHost RootDescriptionWriter; +typedef JfrTypeWriterImplHost RootDescriptionWriterImpl; +typedef JfrTypeWriterHost 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; }