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

changeset 9885
8e875c964f41
parent 9858
b985cbb00e68
equal deleted inserted replaced
9884:1258121876f8 9885:8e875c964f41
1 /* 1 /*
2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
348 writer->write<u8>(osdi->_data._system); 348 writer->write<u8>(osdi->_data._system);
349 writer->write<u8>(osdi->_data._type); 349 writer->write<u8>(osdi->_data._type);
350 return 1; 350 return 1;
351 } 351 }
352 352
353 static traceid get_root_description_info_id(const Edge& edge, traceid id) { 353 static traceid get_gc_root_description_info_id(const Edge& edge, traceid id) {
354 assert(edge.is_root(), "invariant"); 354 assert(edge.is_root(), "invariant");
355 if (EdgeUtils::is_leak_edge(edge)) { 355 if (EdgeUtils::is_leak_edge(edge)) {
356 return 0; 356 return 0;
357 } 357 }
358 358
516 RootDescriptionWriter rw(&writer, NULL, false); 516 RootDescriptionWriter rw(&writer, NULL, false);
517 root_infos->iterate(rw); 517 root_infos->iterate(rw);
518 } 518 }
519 } 519 }
520 520
521 static void add_old_object_sample_info(const Edge* current, traceid id) { 521 static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
522 assert(current != NULL, "invariant"); 522 assert(current != NULL, "invariant");
523 if (sample_infos == NULL) { 523 if (sample_infos == NULL) {
524 sample_infos = new SampleInfo(); 524 sample_infos = new SampleInfo();
525 } 525 }
526 assert(sample_infos != NULL, "invariant"); 526 assert(sample_infos != NULL, "invariant");
527 OldObjectSampleInfo* const oosi = new OldObjectSampleInfo(); 527 OldObjectSampleInfo* const oosi = new OldObjectSampleInfo();
528 assert(oosi != NULL, "invariant"); 528 assert(oosi != NULL, "invariant");
529 oosi->_id = id; 529 oosi->_id = id;
530 oosi->_data._object = current->pointee(); 530 oosi->_data._object = current->pointee();
531 oosi->_data._reference_id = current->is_root() ? (traceid)0 : id; 531 oosi->_data._reference_id = current->parent() == NULL ? (traceid)0 : id;
532 sample_infos->store(oosi); 532 sample_infos->store(oosi);
533 } 533 }
534 534
535 static void add_reference_info(const RoutableEdge* current, traceid id, traceid parent_id) { 535 static void add_reference_info(const StoredEdge* current, traceid id, traceid parent_id) {
536 assert(current != NULL, "invariant"); 536 assert(current != NULL, "invariant");
537 if (ref_infos == NULL) { 537 if (ref_infos == NULL) {
538 ref_infos = new RefInfo(); 538 ref_infos = new RefInfo();
539 } 539 }
540 540
542 ReferenceInfo* const ri = new ReferenceInfo(); 542 ReferenceInfo* const ri = new ReferenceInfo();
543 assert(ri != NULL, "invariant"); 543 assert(ri != NULL, "invariant");
544 544
545 ri->_id = id; 545 ri->_id = id;
546 ri->_data._array_info_id = !current->is_skip_edge() ? get_array_info_id(*current, id) : 0; 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() ? 547 ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ? get_field_info_id(*current) : (traceid)0;
548 get_field_info_id(*current) : (traceid)0;
549 ri->_data._old_object_sample_id = parent_id; 548 ri->_data._old_object_sample_id = parent_id;
550 ri->_data._skip = current->skip_length(); 549 ri->_data._skip = current->skip_length();
551 ref_infos->store(ri); 550 ref_infos->store(ri);
552 } 551 }
553 552
554 static traceid add_root_info(const Edge* root, traceid id) { 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) {
555 assert(root != NULL, "invariant"); 559 assert(root != NULL, "invariant");
556 assert(root->is_root(), "invariant"); 560 assert(is_gc_root(root), "invariant");
557 return get_root_description_info_id(*root, id); 561 return get_gc_root_description_info_id(*root, id);
558 } 562 }
559 563
560 void ObjectSampleWriter::write(const RoutableEdge* edge) { 564 void ObjectSampleWriter::write(const StoredEdge* edge) {
561 assert(edge != NULL, "invariant"); 565 assert(edge != NULL, "invariant");
562 const traceid id = _store->get_id(edge); 566 const traceid id = _store->get_id(edge);
563 add_old_object_sample_info(edge, id); 567 add_old_object_sample_info(edge, id);
564 const RoutableEdge* parent = edge->logical_parent(); 568 const StoredEdge* const parent = edge->parent();
565 if (parent != NULL) { 569 if (parent != NULL) {
566 add_reference_info(edge, id, _store->get_id(parent)); 570 add_reference_info(edge, id, _store->get_id(parent));
567 } else { 571 } else {
568 assert(edge->is_root(), "invariant"); 572 if (is_gc_root(edge)) {
569 add_root_info(edge, id); 573 assert(edge->gc_root_id() == id, "invariant");
570 } 574 add_gc_root_info(edge, id);
571 } 575 }
572 576 }
573 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, const EdgeStore* store) : 577 }
578
579 ObjectSampleWriter::ObjectSampleWriter(JfrCheckpointWriter& writer, EdgeStore* store) :
574 _writer(writer), 580 _writer(writer),
575 _store(store) { 581 _store(store) {
576 assert(store != NULL, "invariant"); 582 assert(store != NULL, "invariant");
577 assert(store->number_of_entries() > 0, "invariant"); 583 assert(!store->is_empty(), "invariant");
578 sample_infos = NULL; 584 sample_infos = NULL;
579 ref_infos = NULL; 585 ref_infos = NULL;
580 array_infos = NULL; 586 array_infos = NULL;
581 field_infos = NULL; 587 field_infos = NULL;
582 root_infos = NULL; 588 root_infos = NULL;
588 write_array_infos(_writer); 594 write_array_infos(_writer);
589 write_field_infos(_writer); 595 write_field_infos(_writer);
590 write_root_descriptors(_writer); 596 write_root_descriptors(_writer);
591 } 597 }
592 598
593 void ObjectSampleWriter::write_chain(const RoutableEdge& edge) { 599 bool ObjectSampleWriter::operator()(StoredEdge& e) {
594 assert(EdgeUtils::is_leak_edge(edge), "invariant"); 600 write(&e);
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; 601 return true;
615 } 602 }

mercurial