1.1 --- a/src/share/vm/jfr/leakprofiler/chains/edgeStore.hpp Fri Sep 27 13:23:32 2019 +0800 1.2 +++ b/src/share/vm/jfr/leakprofiler/chains/edgeStore.hpp Wed Oct 09 16:11:58 2019 +0800 1.3 @@ -25,64 +25,40 @@ 1.4 #ifndef SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP 1.5 #define SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP 1.6 1.7 +#include "jfr/leakprofiler/chains/edge.hpp" 1.8 #include "jfr/utilities/jfrHashtable.hpp" 1.9 -#include "jfr/leakprofiler/chains/edge.hpp" 1.10 #include "memory/allocation.hpp" 1.11 1.12 typedef u8 traceid; 1.13 1.14 -class RoutableEdge : public Edge { 1.15 +class StoredEdge : public Edge { 1.16 private: 1.17 - mutable const RoutableEdge* _skip_edge; 1.18 - mutable size_t _skip_length; 1.19 - mutable bool _processed; 1.20 + mutable traceid _gc_root_id; 1.21 + size_t _skip_length; 1.22 1.23 public: 1.24 - RoutableEdge(); 1.25 - RoutableEdge(const Edge* parent, const oop* reference); 1.26 - RoutableEdge(const Edge& edge); 1.27 - RoutableEdge(const RoutableEdge& edge); 1.28 - void operator=(const RoutableEdge& edge); 1.29 + StoredEdge(); 1.30 + StoredEdge(const Edge* parent, const oop* reference); 1.31 + StoredEdge(const Edge& edge); 1.32 + StoredEdge(const StoredEdge& edge); 1.33 + void operator=(const StoredEdge& edge); 1.34 1.35 - const RoutableEdge* skip_edge() const { return _skip_edge; } 1.36 + traceid gc_root_id() const { return _gc_root_id; } 1.37 + void set_gc_root_id(traceid root_id) const { _gc_root_id = root_id; } 1.38 + 1.39 + bool is_skip_edge() const { return _skip_length != 0; } 1.40 size_t skip_length() const { return _skip_length; } 1.41 + void set_skip_length(size_t length) { _skip_length = length; } 1.42 1.43 - bool is_skip_edge() const { return _skip_edge != NULL; } 1.44 - bool processed() const { return _processed; } 1.45 - bool is_sentinel() const { 1.46 - return _skip_edge == NULL && _skip_length == 1; 1.47 + void set_parent(const Edge* edge) { this->_parent = edge; } 1.48 + 1.49 + StoredEdge* parent() const { 1.50 + return const_cast<StoredEdge*>(static_cast<const StoredEdge*>(Edge::parent())); 1.51 } 1.52 - 1.53 - void set_skip_edge(const RoutableEdge* edge) const { 1.54 - assert(!is_skip_edge(), "invariant"); 1.55 - assert(edge != this, "invariant"); 1.56 - _skip_edge = edge; 1.57 - } 1.58 - 1.59 - void set_skip_length(size_t length) const { 1.60 - _skip_length = length; 1.61 - } 1.62 - 1.63 - void set_processed() const { 1.64 - assert(!_processed, "invariant"); 1.65 - _processed = true; 1.66 - } 1.67 - 1.68 - // true navigation according to physical tree representation 1.69 - const RoutableEdge* physical_parent() const { 1.70 - return static_cast<const RoutableEdge*>(parent()); 1.71 - } 1.72 - 1.73 - // logical navigation taking skip levels into account 1.74 - const RoutableEdge* logical_parent() const { 1.75 - return is_skip_edge() ? skip_edge() : physical_parent(); 1.76 - } 1.77 - 1.78 - size_t logical_distance_to_root() const; 1.79 }; 1.80 1.81 class EdgeStore : public CHeapObj<mtTracing> { 1.82 - typedef HashTableHost<RoutableEdge, traceid, Entry, EdgeStore> EdgeHashTable; 1.83 + typedef HashTableHost<StoredEdge, traceid, Entry, EdgeStore> EdgeHashTable; 1.84 typedef EdgeHashTable::HashEntry EdgeEntry; 1.85 template <typename, 1.86 typename, 1.87 @@ -90,6 +66,9 @@ 1.88 typename, 1.89 size_t> 1.90 friend class HashTableHost; 1.91 + friend class EventEmitter; 1.92 + friend class ObjectSampleWriter; 1.93 + friend class ObjectSampleCheckpoint; 1.94 private: 1.95 static traceid _edge_id_counter; 1.96 EdgeHashTable* _edges; 1.97 @@ -98,22 +77,31 @@ 1.98 void assign_id(EdgeEntry* entry); 1.99 bool equals(const Edge& query, uintptr_t hash, const EdgeEntry* entry); 1.100 1.101 - const Edge* get_edge(const Edge* edge) const; 1.102 - const Edge* put(const Edge* edge); 1.103 + StoredEdge* get(const oop* reference) const; 1.104 + StoredEdge* put(const oop* reference); 1.105 + traceid gc_root_id(const Edge* edge) const; 1.106 + 1.107 + bool put_edges(StoredEdge** previous, const Edge** current, size_t length); 1.108 + bool put_skip_edge(StoredEdge** previous, const Edge** current, size_t distance_to_root); 1.109 + void put_chain_epilogue(StoredEdge* leak_context_edge, const Edge* root) const; 1.110 + 1.111 + StoredEdge* associate_leak_context_with_candidate(const Edge* edge); 1.112 + void store_gc_root_id_in_leak_context_edge(StoredEdge* leak_context_edge, const Edge* root) const; 1.113 + StoredEdge* link_new_edge(StoredEdge** previous, const Edge** current); 1.114 + void link_with_existing_chain(const StoredEdge* current_stored, StoredEdge** previous, size_t previous_length); 1.115 + 1.116 + template <typename T> 1.117 + void iterate(T& functor) const { _edges->iterate_value<T>(functor); } 1.118 + 1.119 + DEBUG_ONLY(bool contains(const oop* reference) const;) 1.120 1.121 public: 1.122 EdgeStore(); 1.123 ~EdgeStore(); 1.124 1.125 - void add_chain(const Edge* chain, size_t length); 1.126 bool is_empty() const; 1.127 - size_t number_of_entries() const; 1.128 - 1.129 traceid get_id(const Edge* edge) const; 1.130 - traceid get_root_id(const Edge* edge) const; 1.131 - 1.132 - template <typename T> 1.133 - void iterate_edges(T& functor) const { _edges->iterate_value<T>(functor); } 1.134 + void put_chain(const Edge* chain, size_t length); 1.135 }; 1.136 1.137 #endif // SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP