src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp
changeset 58132 caa25ab47aca
parent 55571 49102ba8cf14
child 58157 9dca61a7df19
child 58679 9c3209ff7550
child 58863 c16ac7a2eba4
equal deleted inserted replaced
58131:3054503bad7d 58132:caa25ab47aca
    31 #include "jfr/leakprofiler/checkpoint/objectSampleWriter.hpp"
    31 #include "jfr/leakprofiler/checkpoint/objectSampleWriter.hpp"
    32 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
    32 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
    33 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    33 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    34 #include "jfr/leakprofiler/utilities/rootType.hpp"
    34 #include "jfr/leakprofiler/utilities/rootType.hpp"
    35 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
    35 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
    36 #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
    36 #include "jfr/metadata/jfrSerializer.hpp"
    37 #include "jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp"
    37 #include "jfr/writers/jfrTypeWriterHost.hpp"
    38 #include "oops/oop.inline.hpp"
    38 #include "oops/oop.inline.hpp"
    39 #include "oops/symbol.hpp"
    39 #include "oops/symbol.hpp"
    40 #include "utilities/growableArray.hpp"
    40 #include "utilities/growableArray.hpp"
    41 
    41 
    42 template <typename Data>
    42 template <typename Data>
   135             typename,
   135             typename,
   136             template<typename, typename> class,
   136             template<typename, typename> class,
   137             typename,
   137             typename,
   138             size_t>
   138             size_t>
   139   friend class HashTableHost;
   139   friend class HashTableHost;
   140   typedef HashTableHost<const ObjectSampleFieldInfo*, traceid, Entry, FieldTable, 109> FieldInfoTable;
   140   typedef HashTableHost<const ObjectSampleFieldInfo*, traceid, JfrHashtableEntry, FieldTable, 109> FieldInfoTable;
   141  public:
   141  public:
   142   typedef FieldInfoTable::HashEntry FieldInfoEntry;
   142   typedef FieldInfoTable::HashEntry FieldInfoEntry;
   143 
   143 
   144  private:
   144  private:
   145   static traceid _field_id_counter;
   145   static traceid _field_id_counter;
   146   FieldInfoTable* _table;
   146   FieldInfoTable* _table;
   147 
   147   const ObjectSampleFieldInfo* _lookup;
   148   void assign_id(FieldInfoEntry* entry) {
   148 
       
   149   void on_link(FieldInfoEntry* entry) {
   149     assert(entry != NULL, "invariant");
   150     assert(entry != NULL, "invariant");
   150     entry->set_id(++_field_id_counter);
   151     entry->set_id(++_field_id_counter);
   151   }
   152   }
   152 
   153 
   153   bool equals(const ObjectSampleFieldInfo* query, uintptr_t hash, const FieldInfoEntry* entry) {
   154   bool on_equals(uintptr_t hash, const FieldInfoEntry* entry) {
   154     assert(hash == entry->hash(), "invariant");
   155     assert(hash == entry->hash(), "invariant");
   155     assert(query != NULL, "invariant");
   156     assert(_lookup != NULL, "invariant");
   156     const ObjectSampleFieldInfo* stored = entry->literal();
   157     return entry->literal()->_field_modifiers == _lookup->_field_modifiers;
   157     assert(stored != NULL, "invariant");
   158   }
   158     assert(stored->_field_name_symbol->identity_hash() == query->_field_name_symbol->identity_hash(), "invariant");
   159 
   159     return stored->_field_modifiers == query->_field_modifiers;
   160   void on_unlink(FieldInfoEntry* entry) {
   160   }
   161     assert(entry != NULL, "invariant");
   161 
   162     // nothing
   162  public:
   163   }
   163   FieldTable() : _table(new FieldInfoTable(this)) {}
   164 
       
   165  public:
       
   166   FieldTable() : _table(new FieldInfoTable(this)), _lookup(NULL) {}
   164   ~FieldTable() {
   167   ~FieldTable() {
   165     assert(_table != NULL, "invariant");
   168     assert(_table != NULL, "invariant");
   166     delete _table;
   169     delete _table;
   167   }
   170   }
   168 
   171 
   169   traceid store(const ObjectSampleFieldInfo* field_info) {
   172   traceid store(const ObjectSampleFieldInfo* field_info) {
   170     assert(field_info != NULL, "invariant");
   173     assert(field_info != NULL, "invariant");
   171     const FieldInfoEntry& entry =_table->lookup_put(field_info,
   174     _lookup = field_info;
   172                                                     field_info->_field_name_symbol->identity_hash());
   175     const FieldInfoEntry& entry = _table->lookup_put(field_info->_field_name_symbol->identity_hash(), field_info);
   173     return entry.id();
   176     return entry.id();
   174   }
   177   }
   175 
   178 
   176   size_t size() const {
   179   size_t size() const {
   177     return _table->cardinality();
   180     return _table->cardinality();
   194 static RefInfo* ref_infos = NULL;
   197 static RefInfo* ref_infos = NULL;
   195 static ArrayInfo* array_infos = NULL;
   198 static ArrayInfo* array_infos = NULL;
   196 static FieldTable* field_infos = NULL;
   199 static FieldTable* field_infos = NULL;
   197 static RootDescriptionInfo* root_infos = NULL;
   200 static RootDescriptionInfo* root_infos = NULL;
   198 
   201 
   199 int __write_sample_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* si) {
   202 int __write_sample_info__(JfrCheckpointWriter* writer, const void* si) {
   200   assert(writer != NULL, "invariant");
   203   assert(writer != NULL, "invariant");
   201   assert(si != NULL, "invariant");
   204   assert(si != NULL, "invariant");
   202   const OldObjectSampleInfo* const oosi = (const OldObjectSampleInfo*)si;
   205   const OldObjectSampleInfo* const oosi = (const OldObjectSampleInfo*)si;
   203   oop object = oosi->_data._object;
   206   oop object = oosi->_data._object;
   204   assert(object != NULL, "invariant");
   207   assert(object != NULL, "invariant");
   209   writer->write(od.description());
   212   writer->write(od.description());
   210   writer->write(oosi->_data._reference_id);
   213   writer->write(oosi->_data._reference_id);
   211   return 1;
   214   return 1;
   212 }
   215 }
   213 
   216 
   214 typedef JfrArtifactWriterImplHost<const OldObjectSampleInfo*, __write_sample_info__> SampleWriterImpl;
   217 typedef JfrTypeWriterImplHost<const OldObjectSampleInfo*, __write_sample_info__> SampleWriterImpl;
   215 typedef JfrArtifactWriterHost<SampleWriterImpl, TYPE_OLDOBJECT> SampleWriter;
   218 typedef JfrTypeWriterHost<SampleWriterImpl, TYPE_OLDOBJECT> SampleWriter;
   216 
   219 
   217 static void write_sample_infos(JfrCheckpointWriter& writer) {
   220 static void write_sample_infos(JfrCheckpointWriter& writer) {
   218   if (sample_infos != NULL) {
   221   if (sample_infos != NULL) {
   219     SampleWriter sw(&writer, NULL, false);
   222     SampleWriter sw(&writer);
   220     sample_infos->iterate(sw);
   223     sample_infos->iterate(sw);
   221   }
   224   }
   222 }
   225 }
   223 
   226 
   224 int __write_reference_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* ri) {
   227 int __write_reference_info__(JfrCheckpointWriter* writer, const void* ri) {
   225   assert(writer != NULL, "invariant");
   228   assert(writer != NULL, "invariant");
   226   assert(ri != NULL, "invariant");
   229   assert(ri != NULL, "invariant");
   227   const ReferenceInfo* const ref_info = (const ReferenceInfo*)ri;
   230   const ReferenceInfo* const ref_info = (const ReferenceInfo*)ri;
   228   writer->write(ref_info->_id);
   231   writer->write(ref_info->_id);
   229   writer->write(ref_info->_data._array_info_id);
   232   writer->write(ref_info->_data._array_info_id);
   231   writer->write(ref_info->_data._old_object_sample_id);
   234   writer->write(ref_info->_data._old_object_sample_id);
   232   writer->write<s4>((s4)ref_info->_data._skip);
   235   writer->write<s4>((s4)ref_info->_data._skip);
   233   return 1;
   236   return 1;
   234 }
   237 }
   235 
   238 
   236 typedef JfrArtifactWriterImplHost<const ReferenceInfo*, __write_reference_info__> ReferenceWriterImpl;
   239 typedef JfrTypeWriterImplHost<const ReferenceInfo*, __write_reference_info__> ReferenceWriterImpl;
   237 typedef JfrArtifactWriterHost<ReferenceWriterImpl, TYPE_REFERENCE> ReferenceWriter;
   240 typedef JfrTypeWriterHost<ReferenceWriterImpl, TYPE_REFERENCE> ReferenceWriter;
   238 
   241 
   239 static void write_reference_infos(JfrCheckpointWriter& writer) {
   242 static void write_reference_infos(JfrCheckpointWriter& writer) {
   240   if (ref_infos != NULL) {
   243   if (ref_infos != NULL) {
   241     ReferenceWriter rw(&writer, NULL, false);
   244     ReferenceWriter rw(&writer);
   242     ref_infos->iterate(rw);
   245     ref_infos->iterate(rw);
   243   }
   246   }
   244 }
   247 }
   245 
   248 
   246 int __write_array_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* ai) {
   249 int __write_array_info__(JfrCheckpointWriter* writer, const void* ai) {
   247   assert(writer != NULL, "invariant");
   250   assert(writer != NULL, "invariant");
   248   assert(ai != NULL, "invariant");
   251   assert(ai != NULL, "invariant");
   249   const ObjectSampleArrayInfo* const osai = (const ObjectSampleArrayInfo*)ai;
   252   const ObjectSampleArrayInfo* const osai = (const ObjectSampleArrayInfo*)ai;
   250   writer->write(osai->_id);
   253   writer->write(osai->_id);
   251   writer->write(osai->_data._array_size);
   254   writer->write(osai->_data._array_size);
   268   osai->_data._array_size = EdgeUtils::array_size(edge);
   271   osai->_data._array_size = EdgeUtils::array_size(edge);
   269   osai->_data._array_index = EdgeUtils::array_index(edge);
   272   osai->_data._array_index = EdgeUtils::array_index(edge);
   270   return array_infos->store(osai);
   273   return array_infos->store(osai);
   271 }
   274 }
   272 
   275 
   273 typedef JfrArtifactWriterImplHost<const ObjectSampleArrayInfo*, __write_array_info__> ArrayWriterImpl;
   276 typedef JfrTypeWriterImplHost<const ObjectSampleArrayInfo*, __write_array_info__> ArrayWriterImpl;
   274 typedef JfrArtifactWriterHost<ArrayWriterImpl, TYPE_OLDOBJECTARRAY> ArrayWriter;
   277 typedef JfrTypeWriterHost<ArrayWriterImpl, TYPE_OLDOBJECTARRAY> ArrayWriter;
   275 
   278 
   276 static void write_array_infos(JfrCheckpointWriter& writer) {
   279 static void write_array_infos(JfrCheckpointWriter& writer) {
   277   if (array_infos != NULL) {
   280   if (array_infos != NULL) {
   278     ArrayWriter aw(&writer, NULL, false);
   281     ArrayWriter aw(&writer);
   279     array_infos->iterate(aw);
   282     array_infos->iterate(aw);
   280   }
   283   }
   281 }
   284 }
   282 
   285 
   283 int __write_field_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* fi) {
   286 int __write_field_info__(JfrCheckpointWriter* writer, const void* fi) {
   284   assert(writer != NULL, "invariant");
   287   assert(writer != NULL, "invariant");
   285   assert(fi != NULL, "invariant");
   288   assert(fi != NULL, "invariant");
   286   const FieldTable::FieldInfoEntry* field_info_entry = (const FieldTable::FieldInfoEntry*)fi;
   289   const FieldTable::FieldInfoEntry* field_info_entry = (const FieldTable::FieldInfoEntry*)fi;
   287   writer->write(field_info_entry->id());
   290   writer->write(field_info_entry->id());
   288   const ObjectSampleFieldInfo* const osfi = field_info_entry->literal();
   291   const ObjectSampleFieldInfo* const osfi = field_info_entry->literal();
   312   osfi->_field_name_symbol = field_name_symbol;
   315   osfi->_field_name_symbol = field_name_symbol;
   313   osfi->_field_modifiers = EdgeUtils::field_modifiers(edge);
   316   osfi->_field_modifiers = EdgeUtils::field_modifiers(edge);
   314   return field_infos->store(osfi);
   317   return field_infos->store(osfi);
   315 }
   318 }
   316 
   319 
   317 typedef JfrArtifactWriterImplHost<const FieldTable::FieldInfoEntry*, __write_field_info__> FieldWriterImpl;
   320 typedef JfrTypeWriterImplHost<const FieldTable::FieldInfoEntry*, __write_field_info__> FieldWriterImpl;
   318 typedef JfrArtifactWriterHost<FieldWriterImpl, TYPE_OLDOBJECTFIELD> FieldWriter;
   321 typedef JfrTypeWriterHost<FieldWriterImpl, TYPE_OLDOBJECTFIELD> FieldWriter;
   319 
   322 
   320 static void write_field_infos(JfrCheckpointWriter& writer) {
   323 static void write_field_infos(JfrCheckpointWriter& writer) {
   321   if (field_infos != NULL) {
   324   if (field_infos != NULL) {
   322     FieldWriter fw(&writer, NULL, false);
   325     FieldWriter fw(&writer);
   323     field_infos->iterate(fw);
   326     field_infos->iterate(fw);
   324   }
   327   }
   325 }
   328 }
   326 
   329 
   327 static const char* description(const ObjectSampleRootDescriptionInfo* osdi) {
   330 static const char* description(const ObjectSampleRootDescriptionInfo* osdi) {
   337   }
   340   }
   338   description.write_text(osdi->_data._description);
   341   description.write_text(osdi->_data._description);
   339   return description.description();
   342   return description.description();
   340 }
   343 }
   341 
   344 
   342 int __write_root_description_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* di) {
   345 int __write_root_description_info__(JfrCheckpointWriter* writer, const void* di) {
   343   assert(writer != NULL, "invariant");
   346   assert(writer != NULL, "invariant");
   344   assert(di != NULL, "invariant");
   347   assert(di != NULL, "invariant");
   345   const ObjectSampleRootDescriptionInfo* const osdi = (const ObjectSampleRootDescriptionInfo*)di;
   348   const ObjectSampleRootDescriptionInfo* const osdi = (const ObjectSampleRootDescriptionInfo*)di;
   346   writer->write(osdi->_id);
   349   writer->write(osdi->_id);
   347   writer->write(description(osdi));
   350   writer->write(description(osdi));
   364   oodi->_id = id;
   367   oodi->_id = id;
   365   oodi->_data._root_edge = &edge;
   368   oodi->_data._root_edge = &edge;
   366   return root_infos->store(oodi);
   369   return root_infos->store(oodi);
   367 }
   370 }
   368 
   371 
   369 typedef JfrArtifactWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
   372 typedef JfrTypeWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
   370 typedef JfrArtifactWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
   373 typedef JfrTypeWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
   371 
   374 
   372 
   375 
   373 int _edge_reference_compare_(uintptr_t lhs, uintptr_t rhs) {
   376 int _edge_reference_compare_(uintptr_t lhs, uintptr_t rhs) {
   374   return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0;
   377   return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0;
   375 }
   378 }
   511   if (root_infos != NULL) {
   514   if (root_infos != NULL) {
   512     // resolve roots
   515     // resolve roots
   513     RootResolutionSet rrs(root_infos);
   516     RootResolutionSet rrs(root_infos);
   514     RootResolver::resolve(rrs);
   517     RootResolver::resolve(rrs);
   515     // write roots
   518     // write roots
   516     RootDescriptionWriter rw(&writer, NULL, false);
   519     RootDescriptionWriter rw(&writer);
   517     root_infos->iterate(rw);
   520     root_infos->iterate(rw);
   518   }
   521   }
   519 }
   522 }
   520 
   523 
   521 static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
   524 static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
   574       add_gc_root_info(edge, id);
   577       add_gc_root_info(edge, id);
   575     }
   578     }
   576   }
   579   }
   577 }
   580 }
   578 
   581 
       
   582 class RootSystemType : public JfrSerializer {
       
   583  public:
       
   584   void serialize(JfrCheckpointWriter& writer) {
       
   585     const u4 nof_root_systems = OldObjectRoot::_number_of_systems;
       
   586     writer.write_count(nof_root_systems);
       
   587     for (u4 i = 0; i < nof_root_systems; ++i) {
       
   588       writer.write_key(i);
       
   589       writer.write(OldObjectRoot::system_description((OldObjectRoot::System)i));
       
   590     }
       
   591   }
       
   592 };
       
   593 
       
   594 class RootType : public JfrSerializer {
       
   595  public:
       
   596   void serialize(JfrCheckpointWriter& writer) {
       
   597     const u4 nof_root_types = OldObjectRoot::_number_of_types;
       
   598     writer.write_count(nof_root_types);
       
   599     for (u4 i = 0; i < nof_root_types; ++i) {
       
   600       writer.write_key(i);
       
   601       writer.write(OldObjectRoot::type_description((OldObjectRoot::Type)i));
       
   602     }
       
   603   }
       
   604 };
       
   605 
       
   606 static void register_serializers() {
       
   607   static bool is_registered = false;
       
   608   if (!is_registered) {
       
   609     JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
       
   610     JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
       
   611     is_registered = true;
       
   612   }
       
   613 }
       
   614 
   579 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
   615 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
   580   _writer(writer),
   616   _writer(writer),
   581   _store(store) {
   617   _store(store) {
   582   assert(store != NULL, "invariant");
   618   assert(store != NULL, "invariant");
   583   assert(!store->is_empty(), "invariant");
   619   assert(!store->is_empty(), "invariant");
       
   620   register_serializers();
   584   sample_infos = NULL;
   621   sample_infos = NULL;
   585   ref_infos = NULL;
   622   ref_infos = NULL;
   586   array_infos = NULL;
   623   array_infos = NULL;
   587   field_infos = NULL;
   624   field_infos = NULL;
   588   root_infos = NULL;
   625   root_infos = NULL;