src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 50752 9d62da00bf15
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     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.
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "jfr/leakprofiler/chains/bitset.inline.hpp"
    26 #include "jfr/leakprofiler/chains/dfsClosure.hpp"
    27 #include "jfr/leakprofiler/chains/dfsClosure.hpp"
    27 #include "jfr/leakprofiler/chains/edge.hpp"
    28 #include "jfr/leakprofiler/chains/edge.hpp"
    28 #include "jfr/leakprofiler/chains/edgeStore.hpp"
    29 #include "jfr/leakprofiler/chains/edgeStore.hpp"
       
    30 #include "jfr/leakprofiler/chains/rootSetClosure.hpp"
    29 #include "jfr/leakprofiler/utilities/granularTimer.hpp"
    31 #include "jfr/leakprofiler/utilities/granularTimer.hpp"
    30 #include "jfr/leakprofiler/chains/bitset.hpp"
    32 #include "jfr/leakprofiler/utilities/rootType.hpp"
    31 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
    33 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
    32 #include "jfr/leakprofiler/utilities/rootType.hpp"
       
    33 #include "jfr/leakprofiler/chains/rootSetClosure.hpp"
       
    34 #include "memory/iterator.inline.hpp"
    34 #include "memory/iterator.inline.hpp"
    35 #include "memory/resourceArea.hpp"
    35 #include "memory/resourceArea.hpp"
    36 #include "oops/access.inline.hpp"
    36 #include "oops/access.inline.hpp"
    37 #include "oops/oop.inline.hpp"
    37 #include "oops/oop.inline.hpp"
    38 #include "utilities/align.hpp"
    38 #include "utilities/align.hpp"
    86   _start_edge = NULL;
    86   _start_edge = NULL;
    87 
    87 
    88   // Mark root set, to avoid going sideways
    88   // Mark root set, to avoid going sideways
    89   _max_depth = 1;
    89   _max_depth = 1;
    90   _ignore_root_set = false;
    90   _ignore_root_set = false;
    91   DFSClosure dfs1;
    91   DFSClosure dfs;
    92   RootSetClosure::process_roots(&dfs1);
    92   RootSetClosure<DFSClosure> rs(&dfs);
       
    93   rs.process();
    93 
    94 
    94   // Depth-first search
    95   // Depth-first search
    95   _max_depth = max_dfs_depth;
    96   _max_depth = max_dfs_depth;
    96   _ignore_root_set = true;
    97   _ignore_root_set = true;
    97   assert(_start_edge == NULL, "invariant");
    98   assert(_start_edge == NULL, "invariant");
    98   DFSClosure dfs2;
    99   rs.process();
    99   RootSetClosure::process_roots(&dfs2);
       
   100 }
   100 }
   101 
   101 
   102 void DFSClosure::closure_impl(const oop* reference, const oop pointee) {
   102 void DFSClosure::closure_impl(const oop* reference, const oop pointee) {
   103   assert(pointee != NULL, "invariant");
   103   assert(pointee != NULL, "invariant");
   104   assert(reference != NULL, "invariant");
   104   assert(reference != NULL, "invariant");
   119   _reference = reference;
   119   _reference = reference;
   120   _mark_bits->mark_obj(pointee);
   120   _mark_bits->mark_obj(pointee);
   121   assert(_mark_bits->is_marked(pointee), "invariant");
   121   assert(_mark_bits->is_marked(pointee), "invariant");
   122 
   122 
   123   // is the pointee a sample object?
   123   // is the pointee a sample object?
   124   if (NULL == pointee->mark()) {
   124   if (NULL == pointee->mark().to_pointer()) {
   125     add_chain();
   125     add_chain();
   126   }
   126   }
   127 
   127 
   128   assert(_max_depth >= 1, "invariant");
   128   assert(_max_depth >= 1, "invariant");
   129   if (_depth < _max_depth - 1) {
   129   if (_depth < _max_depth - 1) {
   131     pointee->oop_iterate(&next_level);
   131     pointee->oop_iterate(&next_level);
   132   }
   132   }
   133 }
   133 }
   134 
   134 
   135 void DFSClosure::add_chain() {
   135 void DFSClosure::add_chain() {
   136   const size_t length = _start_edge == NULL ? _depth + 1 :
   136   const size_t array_length = _depth + 2;
   137                         _start_edge->distance_to_root() + 1 + _depth + 1;
       
   138 
   137 
   139   ResourceMark rm;
   138   ResourceMark rm;
   140   Edge* const chain = NEW_RESOURCE_ARRAY(Edge, length);
   139   Edge* const chain = NEW_RESOURCE_ARRAY(Edge, array_length);
   141   size_t idx = 0;
   140   size_t idx = 0;
   142 
   141 
   143   // aggregate from depth-first search
   142   // aggregate from depth-first search
   144   const DFSClosure* c = this;
   143   const DFSClosure* c = this;
   145   while (c != NULL) {
   144   while (c != NULL) {
   146     chain[idx++] = Edge(NULL, c->reference());
   145     const size_t next = idx + 1;
       
   146     chain[idx++] = Edge(&chain[next], c->reference());
   147     c = c->parent();
   147     c = c->parent();
   148   }
   148   }
   149 
   149   assert(_depth + 1 == idx, "invariant");
   150   assert(idx == _depth + 1, "invariant");
   150   assert(array_length == idx + 1, "invariant");
   151 
   151 
   152   // aggregate from breadth-first search
   152   // aggregate from breadth-first search
   153   const Edge* current = _start_edge;
   153   if (_start_edge != NULL) {
   154   while (current != NULL) {
   154     chain[idx++] = *_start_edge;
   155     chain[idx++] = Edge(NULL, current->reference());
   155   } else {
   156     current = current->parent();
   156     chain[idx - 1] = Edge(NULL, chain[idx - 1].reference());
   157   }
   157   }
   158   assert(idx == length, "invariant");
   158   _edge_store->put_chain(chain, idx + (_start_edge != NULL ? _start_edge->distance_to_root() : 0));
   159   _edge_store->add_chain(chain, length);
       
   160 }
   159 }
   161 
   160 
   162 void DFSClosure::do_oop(oop* ref) {
   161 void DFSClosure::do_oop(oop* ref) {
   163   assert(ref != NULL, "invariant");
   162   assert(ref != NULL, "invariant");
   164   assert(is_aligned(ref, HeapWordSize), "invariant");
   163   assert(is_aligned(ref, HeapWordSize), "invariant");
   174   const oop pointee = RawAccess<>::oop_load(ref);
   173   const oop pointee = RawAccess<>::oop_load(ref);
   175   if (pointee != NULL) {
   174   if (pointee != NULL) {
   176     closure_impl(UnifiedOop::encode(ref), pointee);
   175     closure_impl(UnifiedOop::encode(ref), pointee);
   177   }
   176   }
   178 }
   177 }
       
   178 
       
   179 void DFSClosure::do_root(const oop* ref) {
       
   180   assert(ref != NULL, "invariant");
       
   181   const oop pointee = UnifiedOop::dereference(ref);
       
   182   assert(pointee != NULL, "invariant");
       
   183   closure_impl(ref, pointee);
       
   184 }