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 }
|