|
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 * |
|
23 */ |
|
24 |
|
25 #ifndef SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP |
|
26 #define SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP |
|
27 |
|
28 #include "jfr/utilities/jfrHashtable.hpp" |
|
29 #include "jfr/leakprofiler/chains/edge.hpp" |
|
30 #include "memory/allocation.hpp" |
|
31 |
|
32 typedef u8 traceid; |
|
33 |
|
34 class RoutableEdge : public Edge { |
|
35 private: |
|
36 mutable const RoutableEdge* _skip_edge; |
|
37 mutable size_t _skip_length; |
|
38 mutable bool _processed; |
|
39 |
|
40 public: |
|
41 RoutableEdge(); |
|
42 RoutableEdge(const Edge* parent, const oop* reference); |
|
43 RoutableEdge(const Edge& edge); |
|
44 RoutableEdge(const RoutableEdge& edge); |
|
45 void operator=(const RoutableEdge& edge); |
|
46 |
|
47 const RoutableEdge* skip_edge() const { return _skip_edge; } |
|
48 size_t skip_length() const { return _skip_length; } |
|
49 |
|
50 bool is_skip_edge() const { return _skip_edge != NULL; } |
|
51 bool processed() const { return _processed; } |
|
52 bool is_sentinel() const { |
|
53 return _skip_edge == NULL && _skip_length == 1; |
|
54 } |
|
55 |
|
56 void set_skip_edge(const RoutableEdge* edge) const { |
|
57 assert(!is_skip_edge(), "invariant"); |
|
58 assert(edge != this, "invariant"); |
|
59 _skip_edge = edge; |
|
60 } |
|
61 |
|
62 void set_skip_length(size_t length) const { |
|
63 _skip_length = length; |
|
64 } |
|
65 |
|
66 void set_processed() const { |
|
67 assert(!_processed, "invariant"); |
|
68 _processed = true; |
|
69 } |
|
70 |
|
71 // true navigation according to physical tree representation |
|
72 const RoutableEdge* physical_parent() const { |
|
73 return static_cast<const RoutableEdge*>(parent()); |
|
74 } |
|
75 |
|
76 // logical navigation taking skip levels into account |
|
77 const RoutableEdge* logical_parent() const { |
|
78 return is_skip_edge() ? skip_edge() : physical_parent(); |
|
79 } |
|
80 |
|
81 size_t logical_distance_to_root() const; |
|
82 }; |
|
83 |
|
84 class EdgeStore : public CHeapObj<mtTracing> { |
|
85 typedef HashTableHost<RoutableEdge, traceid, Entry, EdgeStore> EdgeHashTable; |
|
86 typedef EdgeHashTable::HashEntry EdgeEntry; |
|
87 template <typename, |
|
88 typename, |
|
89 template<typename, typename> class, |
|
90 typename, |
|
91 size_t> |
|
92 friend class HashTableHost; |
|
93 private: |
|
94 static traceid _edge_id_counter; |
|
95 EdgeHashTable* _edges; |
|
96 |
|
97 // Hash table callbacks |
|
98 void assign_id(EdgeEntry* entry); |
|
99 bool equals(const Edge& query, uintptr_t hash, const EdgeEntry* entry); |
|
100 |
|
101 const Edge* get_edge(const Edge* edge) const; |
|
102 const Edge* put(const Edge* edge); |
|
103 |
|
104 public: |
|
105 EdgeStore(); |
|
106 ~EdgeStore(); |
|
107 |
|
108 void add_chain(const Edge* chain, size_t length); |
|
109 bool is_empty() const; |
|
110 size_t number_of_entries() const; |
|
111 |
|
112 traceid get_id(const Edge* edge) const; |
|
113 traceid get_root_id(const Edge* edge) const; |
|
114 |
|
115 template <typename T> |
|
116 void iterate_edges(T& functor) const { _edges->iterate_value<T>(functor); } |
|
117 }; |
|
118 |
|
119 #endif // SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP |