< prev index next >

src/share/vm/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp

Print this page
rev 9055 : 8214542: JFR: Old Object Sample event slow on a deep heap in debug builds
Reviewed-by: egahlin, rwestberg
   1 /*
   2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 333 
 334   ObjectDescriptionBuilder description;
 335   if (osdi->_data._system == OldObjectRoot::_threads) {
 336     description.write_text("Thread Name: ");
 337   }
 338   description.write_text(osdi->_data._description);
 339   return description.description();
 340 }
 341 
 342 int __write_root_description_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* di) {
 343   assert(writer != NULL, "invariant");
 344   assert(di != NULL, "invariant");
 345   const ObjectSampleRootDescriptionInfo* const osdi = (const ObjectSampleRootDescriptionInfo*)di;
 346   writer->write(osdi->_id);
 347   writer->write(description(osdi));
 348   writer->write<u8>(osdi->_data._system);
 349   writer->write<u8>(osdi->_data._type);
 350   return 1;
 351 }
 352 
 353 static traceid get_root_description_info_id(const Edge& edge, traceid id) {
 354   assert(edge.is_root(), "invariant");
 355   if (EdgeUtils::is_leak_edge(edge)) {
 356     return 0;
 357   }
 358 
 359   if (root_infos == NULL) {
 360     root_infos = new RootDescriptionInfo();
 361   }
 362   assert(root_infos != NULL, "invariant");
 363   ObjectSampleRootDescriptionInfo* const oodi = new ObjectSampleRootDescriptionInfo();
 364   oodi->_id = id;
 365   oodi->_data._root_edge = &edge;
 366   return root_infos->store(oodi);
 367 }
 368 
 369 typedef JfrArtifactWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
 370 typedef JfrArtifactWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
 371 
 372 
 373 int _edge_reference_compare_(uintptr_t lhs, uintptr_t rhs) {


 501   }
 502 
 503   const void* at(int idx) const {
 504     assert(idx >= 0, "invariant");
 505     assert(idx < _unresolved_roots->length(), "invariant");
 506     return _unresolved_roots->at(idx)->_data._root_edge->reference();
 507   }
 508 };
 509 
 510 static void write_root_descriptors(JfrCheckpointWriter& writer) {
 511   if (root_infos != NULL) {
 512     // resolve roots
 513     RootResolutionSet rrs(root_infos);
 514     RootResolver::resolve(rrs);
 515     // write roots
 516     RootDescriptionWriter rw(&writer, NULL, false);
 517     root_infos->iterate(rw);
 518   }
 519 }
 520 
 521 static void add_old_object_sample_info(const Edge* current, traceid id) {
 522   assert(current != NULL, "invariant");
 523   if (sample_infos == NULL) {
 524     sample_infos = new SampleInfo();
 525   }
 526   assert(sample_infos != NULL, "invariant");
 527   OldObjectSampleInfo* const oosi = new OldObjectSampleInfo();
 528   assert(oosi != NULL, "invariant");
 529   oosi->_id = id;
 530   oosi->_data._object = current->pointee();
 531   oosi->_data._reference_id = current->is_root() ? (traceid)0 : id;
 532   sample_infos->store(oosi);
 533 }
 534 
 535 static void add_reference_info(const RoutableEdge* current, traceid id, traceid parent_id) {
 536   assert(current != NULL, "invariant");
 537   if (ref_infos == NULL) {
 538     ref_infos = new RefInfo();
 539   }
 540 
 541   assert(ref_infos != NULL, "invariant");
 542   ReferenceInfo* const ri = new ReferenceInfo();
 543   assert(ri != NULL, "invariant");
 544 
 545   ri->_id = id;
 546   ri->_data._array_info_id =  !current->is_skip_edge() ? get_array_info_id(*current, id) : 0;
 547   ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ?
 548                                get_field_info_id(*current) : (traceid)0;
 549   ri->_data._old_object_sample_id = parent_id;
 550   ri->_data._skip = current->skip_length();
 551   ref_infos->store(ri);
 552 }
 553 
 554 static traceid add_root_info(const Edge* root, traceid id) {





 555   assert(root != NULL, "invariant");
 556   assert(root->is_root(), "invariant");
 557   return get_root_description_info_id(*root, id);
 558 }
 559 
 560 void ObjectSampleWriter::write(const RoutableEdge* edge) {
 561   assert(edge != NULL, "invariant");
 562   const traceid id = _store->get_id(edge);
 563   add_old_object_sample_info(edge, id);
 564   const RoutableEdge* parent = edge->logical_parent();
 565   if (parent != NULL) {
 566     add_reference_info(edge, id, _store->get_id(parent));
 567   } else {
 568     assert(edge->is_root(), "invariant");
 569     add_root_info(edge, id);


 570   }
 571 }
 572 
 573 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, const EdgeStore* store) :
 574   _writer(writer),
 575   _store(store) {
 576   assert(store != NULL, "invariant");
 577   assert(store->number_of_entries() > 0, "invariant");
 578   sample_infos = NULL;
 579   ref_infos = NULL;
 580   array_infos = NULL;
 581   field_infos = NULL;
 582   root_infos = NULL;
 583 }
 584 
 585 ObjectSampleWriter::~ObjectSampleWriter() {
 586   write_sample_infos(_writer);
 587   write_reference_infos(_writer);
 588   write_array_infos(_writer);
 589   write_field_infos(_writer);
 590   write_root_descriptors(_writer);
 591 }
 592 
 593 void ObjectSampleWriter::write_chain(const RoutableEdge& edge) {
 594   assert(EdgeUtils::is_leak_edge(edge), "invariant");
 595   if (edge.processed()) {
 596     return;
 597   }
 598   EdgeUtils::collapse_chain(edge);
 599   const RoutableEdge* current = &edge;
 600   while (current != NULL) {
 601     if (current->processed()) {
 602       return;
 603     }
 604     write(current);
 605     current->set_processed();
 606     current = current->logical_parent();
 607   }
 608 }
 609 
 610 bool ObjectSampleWriter::operator()(const RoutableEdge& edge) {
 611   if (EdgeUtils::is_leak_edge(edge)) {
 612     write_chain(edge);
 613   }
 614   return true;
 615 }
   1 /*
   2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 333 
 334   ObjectDescriptionBuilder description;
 335   if (osdi->_data._system == OldObjectRoot::_threads) {
 336     description.write_text("Thread Name: ");
 337   }
 338   description.write_text(osdi->_data._description);
 339   return description.description();
 340 }
 341 
 342 int __write_root_description_info__(JfrCheckpointWriter* writer, JfrArtifactSet* unused, const void* di) {
 343   assert(writer != NULL, "invariant");
 344   assert(di != NULL, "invariant");
 345   const ObjectSampleRootDescriptionInfo* const osdi = (const ObjectSampleRootDescriptionInfo*)di;
 346   writer->write(osdi->_id);
 347   writer->write(description(osdi));
 348   writer->write<u8>(osdi->_data._system);
 349   writer->write<u8>(osdi->_data._type);
 350   return 1;
 351 }
 352 
 353 static traceid get_gc_root_description_info_id(const Edge& edge, traceid id) {
 354   assert(edge.is_root(), "invariant");
 355   if (EdgeUtils::is_leak_edge(edge)) {
 356     return 0;
 357   }
 358 
 359   if (root_infos == NULL) {
 360     root_infos = new RootDescriptionInfo();
 361   }
 362   assert(root_infos != NULL, "invariant");
 363   ObjectSampleRootDescriptionInfo* const oodi = new ObjectSampleRootDescriptionInfo();
 364   oodi->_id = id;
 365   oodi->_data._root_edge = &edge;
 366   return root_infos->store(oodi);
 367 }
 368 
 369 typedef JfrArtifactWriterImplHost<const ObjectSampleRootDescriptionInfo*, __write_root_description_info__> RootDescriptionWriterImpl;
 370 typedef JfrArtifactWriterHost<RootDescriptionWriterImpl, TYPE_OLDOBJECTGCROOT> RootDescriptionWriter;
 371 
 372 
 373 int _edge_reference_compare_(uintptr_t lhs, uintptr_t rhs) {


 501   }
 502 
 503   const void* at(int idx) const {
 504     assert(idx >= 0, "invariant");
 505     assert(idx < _unresolved_roots->length(), "invariant");
 506     return _unresolved_roots->at(idx)->_data._root_edge->reference();
 507   }
 508 };
 509 
 510 static void write_root_descriptors(JfrCheckpointWriter& writer) {
 511   if (root_infos != NULL) {
 512     // resolve roots
 513     RootResolutionSet rrs(root_infos);
 514     RootResolver::resolve(rrs);
 515     // write roots
 516     RootDescriptionWriter rw(&writer, NULL, false);
 517     root_infos->iterate(rw);
 518   }
 519 }
 520 
 521 static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
 522   assert(current != NULL, "invariant");
 523   if (sample_infos == NULL) {
 524     sample_infos = new SampleInfo();
 525   }
 526   assert(sample_infos != NULL, "invariant");
 527   OldObjectSampleInfo* const oosi = new OldObjectSampleInfo();
 528   assert(oosi != NULL, "invariant");
 529   oosi->_id = id;
 530   oosi->_data._object = current->pointee();
 531   oosi->_data._reference_id = current->parent() == NULL ? (traceid)0 : id;
 532   sample_infos->store(oosi);
 533 }
 534 
 535 static void add_reference_info(const StoredEdge* current, traceid id, traceid parent_id) {
 536   assert(current != NULL, "invariant");
 537   if (ref_infos == NULL) {
 538     ref_infos = new RefInfo();
 539   }
 540 
 541   assert(ref_infos != NULL, "invariant");
 542   ReferenceInfo* const ri = new ReferenceInfo();
 543   assert(ri != NULL, "invariant");
 544 
 545   ri->_id = id;
 546   ri->_data._array_info_id =  !current->is_skip_edge() ? get_array_info_id(*current, id) : 0;
 547   ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ? get_field_info_id(*current) : (traceid)0;

 548   ri->_data._old_object_sample_id = parent_id;
 549   ri->_data._skip = current->skip_length();
 550   ref_infos->store(ri);
 551 }
 552 
 553 static bool is_gc_root(const StoredEdge* current) {
 554   assert(current != NULL, "invariant");
 555   return current->parent() == NULL && current->gc_root_id() != 0;
 556 }
 557 
 558 static traceid add_gc_root_info(const StoredEdge* root, traceid id) {
 559   assert(root != NULL, "invariant");
 560   assert(is_gc_root(root), "invariant");
 561   return get_gc_root_description_info_id(*root, id);
 562 }
 563 
 564 void ObjectSampleWriter::write(const StoredEdge* edge) {
 565   assert(edge != NULL, "invariant");
 566   const traceid id = _store->get_id(edge);
 567   add_old_object_sample_info(edge, id);
 568   const StoredEdge* const parent = edge->parent();
 569   if (parent != NULL) {
 570     add_reference_info(edge, id, _store->get_id(parent));
 571   } else {
 572     if (is_gc_root(edge)) {
 573       assert(edge->gc_root_id() == id, "invariant");
 574       add_gc_root_info(edge, id);
 575     }
 576   }
 577 }
 578 
 579 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
 580   _writer(writer),
 581   _store(store) {
 582   assert(store != NULL, "invariant");
 583   assert(!store->is_empty(), "invariant");
 584   sample_infos = NULL;
 585   ref_infos = NULL;
 586   array_infos = NULL;
 587   field_infos = NULL;
 588   root_infos = NULL;
 589 }
 590 
 591 ObjectSampleWriter::~ObjectSampleWriter() {
 592   write_sample_infos(_writer);
 593   write_reference_infos(_writer);
 594   write_array_infos(_writer);
 595   write_field_infos(_writer);
 596   write_root_descriptors(_writer);
 597 }
 598 
 599 bool ObjectSampleWriter::operator()(StoredEdge& e) {
 600   write(&e);



















 601   return true;
 602 }
< prev index next >