1.1 --- a/src/share/vm/jfr/leakprofiler/chains/dfsClosure.cpp Fri Sep 27 13:23:32 2019 +0800 1.2 +++ b/src/share/vm/jfr/leakprofiler/chains/dfsClosure.cpp Wed Oct 09 16:11:58 2019 +0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -23,14 +23,14 @@ 1.11 */ 1.12 1.13 #include "precompiled.hpp" 1.14 +#include "jfr/leakprofiler/chains/bitset.hpp" 1.15 #include "jfr/leakprofiler/chains/dfsClosure.hpp" 1.16 #include "jfr/leakprofiler/chains/edge.hpp" 1.17 #include "jfr/leakprofiler/chains/edgeStore.hpp" 1.18 +#include "jfr/leakprofiler/chains/rootSetClosure.hpp" 1.19 #include "jfr/leakprofiler/utilities/granularTimer.hpp" 1.20 -#include "jfr/leakprofiler/chains/bitset.hpp" 1.21 +#include "jfr/leakprofiler/utilities/rootType.hpp" 1.22 #include "jfr/leakprofiler/utilities/unifiedOop.hpp" 1.23 -#include "jfr/leakprofiler/utilities/rootType.hpp" 1.24 -#include "jfr/leakprofiler/chains/rootSetClosure.hpp" 1.25 #include "memory/iterator.inline.hpp" 1.26 #include "memory/resourceArea.hpp" 1.27 #include "oops/oop.inline.hpp" 1.28 @@ -87,15 +87,15 @@ 1.29 // Mark root set, to avoid going sideways 1.30 _max_depth = 1; 1.31 _ignore_root_set = false; 1.32 - DFSClosure dfs1; 1.33 - RootSetClosure::process_roots(&dfs1); 1.34 + DFSClosure dfs; 1.35 + RootSetClosure<DFSClosure> rs(&dfs); 1.36 + rs.process(); 1.37 1.38 // Depth-first search 1.39 _max_depth = max_dfs_depth; 1.40 _ignore_root_set = true; 1.41 assert(_start_edge == NULL, "invariant"); 1.42 - DFSClosure dfs2; 1.43 - RootSetClosure::process_roots(&dfs2); 1.44 + rs.process(); 1.45 } 1.46 1.47 void DFSClosure::closure_impl(const oop* reference, const oop pointee) { 1.48 @@ -132,30 +132,29 @@ 1.49 } 1.50 1.51 void DFSClosure::add_chain() { 1.52 - const size_t length = _start_edge == NULL ? _depth + 1 : 1.53 - _start_edge->distance_to_root() + 1 + _depth + 1; 1.54 + const size_t array_length = _depth + 2; 1.55 1.56 ResourceMark rm; 1.57 - Edge* const chain = NEW_RESOURCE_ARRAY(Edge, length); 1.58 + Edge* const chain = NEW_RESOURCE_ARRAY(Edge, array_length); 1.59 size_t idx = 0; 1.60 1.61 // aggregate from depth-first search 1.62 const DFSClosure* c = this; 1.63 while (c != NULL) { 1.64 - chain[idx++] = Edge(NULL, c->reference()); 1.65 + const size_t next = idx + 1; 1.66 + chain[idx++] = Edge(&chain[next], c->reference()); 1.67 c = c->parent(); 1.68 } 1.69 - 1.70 - assert(idx == _depth + 1, "invariant"); 1.71 + assert(_depth + 1 == idx, "invariant"); 1.72 + assert(array_length == idx + 1, "invariant"); 1.73 1.74 // aggregate from breadth-first search 1.75 - const Edge* current = _start_edge; 1.76 - while (current != NULL) { 1.77 - chain[idx++] = Edge(NULL, current->reference()); 1.78 - current = current->parent(); 1.79 + if (_start_edge != NULL) { 1.80 + chain[idx++] = *_start_edge; 1.81 + } else { 1.82 + chain[idx - 1] = Edge(NULL, chain[idx - 1].reference()); 1.83 } 1.84 - assert(idx == length, "invariant"); 1.85 - _edge_store->add_chain(chain, length); 1.86 + _edge_store->put_chain(chain, idx + (_start_edge != NULL ? _start_edge->distance_to_root() : 0)); 1.87 } 1.88 1.89 void DFSClosure::do_oop(oop* ref) { 1.90 @@ -175,3 +174,10 @@ 1.91 closure_impl(UnifiedOop::encode(ref), pointee); 1.92 } 1.93 } 1.94 + 1.95 +void DFSClosure::do_root(const oop* ref) { 1.96 + assert(ref != NULL, "invariant"); 1.97 + const oop pointee = UnifiedOop::dereference(ref); 1.98 + assert(pointee != NULL, "invariant"); 1.99 + closure_impl(ref, pointee); 1.100 +}