74 return t != NULL ? (*_letter)(t) : true; |
74 return t != NULL ? (*_letter)(t) : true; |
75 } |
75 } |
76 }; |
76 }; |
77 |
77 |
78 template <typename T> |
78 template <typename T> |
79 void tag_leakp_artifact(T const& value, bool class_unload) { |
79 void tag_leakp_artifact(T const& value, bool current_epoch) { |
80 assert(value != NULL, "invariant"); |
80 assert(value != NULL, "invariant"); |
81 if (class_unload) { |
81 if (current_epoch) { |
82 SET_LEAKP_USED_THIS_EPOCH(value); |
82 SET_LEAKP_USED_THIS_EPOCH(value); |
83 assert(LEAKP_USED_THIS_EPOCH(value), "invariant"); |
83 assert(LEAKP_USED_THIS_EPOCH(value), "invariant"); |
84 } else { |
84 } else { |
85 SET_LEAKP_USED_PREV_EPOCH(value); |
85 SET_LEAKP_USED_PREV_EPOCH(value); |
86 assert(LEAKP_USED_PREV_EPOCH(value), "invariant"); |
86 assert(LEAKP_USED_PREV_EPOCH(value), "invariant"); |
87 } |
87 } |
88 } |
88 } |
89 |
89 |
90 template <typename T> |
90 template <typename T> |
91 class LeakpClearArtifact { |
91 class LeakpClearArtifact { |
92 bool _class_unload; |
92 bool _current_epoch; |
93 public: |
93 public: |
94 LeakpClearArtifact(bool class_unload) : _class_unload(class_unload) {} |
94 LeakpClearArtifact(bool current_epoch) : _current_epoch(current_epoch) {} |
95 bool operator()(T const& value) { |
95 bool operator()(T const& value) { |
96 if (_class_unload) { |
96 if (_current_epoch) { |
97 if (LEAKP_USED_THIS_EPOCH(value)) { |
97 if (LEAKP_USED_THIS_EPOCH(value)) { |
98 LEAKP_UNUSE_THIS_EPOCH(value); |
98 LEAKP_UNUSE_THIS_EPOCH(value); |
99 } |
99 } |
100 } else { |
100 } else { |
101 if (LEAKP_USED_PREV_EPOCH(value)) { |
101 if (LEAKP_USED_PREV_EPOCH(value)) { |
105 return true; |
105 return true; |
106 } |
106 } |
107 }; |
107 }; |
108 |
108 |
109 template <typename T> |
109 template <typename T> |
|
110 class UnTagArtifact { |
|
111 public: |
|
112 UnTagArtifact() {} |
|
113 bool operator()(T const& value) { |
|
114 if (LEAKP_USED_PREV_EPOCH(value)) { |
|
115 LEAKP_UNUSE_PREV_EPOCH(value); |
|
116 } |
|
117 if (USED_PREV_EPOCH(value)) { |
|
118 UNUSE_PREV_EPOCH(value); |
|
119 } |
|
120 return true; |
|
121 } |
|
122 }; |
|
123 |
|
124 template <typename T> |
110 class ClearArtifact { |
125 class ClearArtifact { |
111 bool _class_unload; |
126 public: |
112 public: |
127 bool operator()(T const& value) { |
113 ClearArtifact(bool class_unload) : _class_unload(class_unload) {} |
128 if (LEAKP_USED_PREV_EPOCH(value)) { |
114 bool operator()(T const& value) { |
129 LEAKP_UNUSE_PREV_EPOCH(value); |
115 if (_class_unload) { |
130 } |
116 if (LEAKP_USED_THIS_EPOCH(value)) { |
131 if (USED_PREV_EPOCH(value)) { |
117 LEAKP_UNUSE_THIS_EPOCH(value); |
132 UNUSE_PREV_EPOCH(value); |
118 } |
133 } |
119 if (USED_THIS_EPOCH(value)) { |
134 if (IS_SERIALIZED(value)) { |
120 UNUSE_THIS_EPOCH(value); |
135 UNSERIALIZE(value); |
121 } |
136 } |
122 if (METHOD_USED_THIS_EPOCH(value)) { |
137 assert(IS_NOT_SERIALIZED(value), "invariant"); |
123 UNUSE_METHOD_THIS_EPOCH(value); |
138 return true; |
124 } |
139 } |
125 } else { |
140 }; |
126 if (LEAKP_USED_PREV_EPOCH(value)) { |
141 |
127 LEAKP_UNUSE_PREV_EPOCH(value); |
142 template <> |
128 } |
143 class ClearArtifact<const Klass*> { |
129 if (USED_PREV_EPOCH(value)) { |
144 public: |
130 UNUSE_PREV_EPOCH(value); |
145 bool operator()(const Klass* klass) { |
131 } |
146 if (LEAKP_USED_PREV_EPOCH(klass)) { |
132 if (METHOD_USED_PREV_EPOCH(value)) { |
147 LEAKP_UNUSE_PREV_EPOCH(klass); |
133 UNUSE_METHOD_PREV_EPOCH(value); |
148 } |
134 } |
149 if (USED_PREV_EPOCH(klass)) { |
135 } |
150 UNUSE_PREV_EPOCH(klass); |
|
151 } |
|
152 if (METHOD_USED_PREV_EPOCH(klass)) { |
|
153 UNUSE_METHOD_PREV_EPOCH(klass); |
|
154 } |
|
155 if (IS_SERIALIZED(klass)) { |
|
156 UNSERIALIZE(klass); |
|
157 } |
|
158 assert(IS_NOT_SERIALIZED(klass), "invariant"); |
136 return true; |
159 return true; |
137 } |
160 } |
138 }; |
161 }; |
139 |
162 |
140 template <> |
163 template <> |
141 class ClearArtifact<const Method*> { |
164 class ClearArtifact<const Method*> { |
142 bool _class_unload; |
165 public: |
143 public: |
|
144 ClearArtifact(bool class_unload) : _class_unload(class_unload) {} |
|
145 bool operator()(const Method* method) { |
166 bool operator()(const Method* method) { |
146 if (_class_unload) { |
167 if (METHOD_FLAG_USED_PREV_EPOCH(method)) { |
147 if (METHOD_FLAG_USED_THIS_EPOCH(method)) { |
168 CLEAR_METHOD_FLAG_USED_PREV_EPOCH(method); |
148 CLEAR_METHOD_FLAG_USED_THIS_EPOCH(method); |
|
149 } |
|
150 } else { |
|
151 if (METHOD_FLAG_USED_PREV_EPOCH(method)) { |
|
152 CLEAR_METHOD_FLAG_USED_PREV_EPOCH(method); |
|
153 } |
|
154 } |
169 } |
155 return true; |
170 return true; |
156 } |
171 } |
157 }; |
172 }; |
158 |
173 |
159 template <typename T> |
174 template <typename T> |
160 class LeakPredicate { |
175 class LeakPredicate { |
161 bool _class_unload; |
176 bool _current_epoch; |
162 public: |
177 public: |
163 LeakPredicate(bool class_unload) : _class_unload(class_unload) {} |
178 LeakPredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
164 bool operator()(T const& value) { |
179 bool operator()(T const& value) { |
165 return _class_unload ? LEAKP_USED_THIS_EPOCH(value) : LEAKP_USED_PREV_EPOCH(value); |
180 return _current_epoch ? LEAKP_USED_THIS_EPOCH(value) : LEAKP_USED_PREV_EPOCH(value); |
|
181 } |
|
182 }; |
|
183 |
|
184 template <typename T> |
|
185 class LeakSerializePredicate { |
|
186 LeakPredicate<T> _leak_predicate; |
|
187 public: |
|
188 LeakSerializePredicate(bool current_epoch) : _leak_predicate(current_epoch) {} |
|
189 bool operator()(T const& value) { |
|
190 return IS_NOT_LEAKP_SERIALIZED(value) && _leak_predicate(value); |
166 } |
191 } |
167 }; |
192 }; |
168 |
193 |
169 template <typename T> |
194 template <typename T> |
170 class UsedPredicate { |
195 class UsedPredicate { |
171 bool _class_unload; |
196 bool _current_epoch; |
172 public: |
197 public: |
173 UsedPredicate(bool class_unload) : _class_unload(class_unload) {} |
198 UsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
174 bool operator()(T const& value) { |
199 bool operator()(T const& value) { |
175 return _class_unload ? USED_THIS_EPOCH(value) : USED_PREV_EPOCH(value); |
200 return _current_epoch ? USED_THIS_EPOCH(value) : USED_PREV_EPOCH(value); |
|
201 } |
|
202 }; |
|
203 |
|
204 template <typename T> |
|
205 class SerializePredicate { |
|
206 bool _current_epoch; |
|
207 public: |
|
208 SerializePredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
|
209 bool operator()(T const& value) { |
|
210 assert(value != NULL, "invariant"); |
|
211 return IS_NOT_SERIALIZED(value); |
|
212 } |
|
213 }; |
|
214 |
|
215 template <> |
|
216 class SerializePredicate<const Method*> { |
|
217 bool _current_epoch; |
|
218 public: |
|
219 SerializePredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
|
220 bool operator()(const Method* method) { |
|
221 assert(method != NULL, "invariant"); |
|
222 return METHOD_NOT_SERIALIZED(method); |
176 } |
223 } |
177 }; |
224 }; |
178 |
225 |
179 template <typename T, int compare(const T&, const T&)> |
226 template <typename T, int compare(const T&, const T&)> |
180 class UniquePredicate { |
227 class UniquePredicate { |
192 return true; |
239 return true; |
193 } |
240 } |
194 }; |
241 }; |
195 |
242 |
196 class MethodFlagPredicate { |
243 class MethodFlagPredicate { |
197 bool _class_unload; |
244 bool _current_epoch; |
198 public: |
245 public: |
199 MethodFlagPredicate(bool class_unload) : _class_unload(class_unload) {} |
246 MethodFlagPredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
200 bool operator()(const Method* method) { |
247 bool operator()(const Method* method) { |
201 return _class_unload ? METHOD_FLAG_USED_THIS_EPOCH(method) : METHOD_FLAG_USED_PREV_EPOCH(method); |
248 return _current_epoch ? METHOD_FLAG_USED_THIS_EPOCH(method) : METHOD_FLAG_USED_PREV_EPOCH(method); |
202 } |
249 } |
203 }; |
250 }; |
204 |
251 |
205 template <bool leakp> |
252 template <bool leakp> |
206 class MethodUsedPredicate { |
253 class MethodUsedPredicate { |
207 bool _class_unload; |
254 bool _current_epoch; |
208 public: |
255 public: |
209 MethodUsedPredicate(bool class_unload) : _class_unload(class_unload) {} |
256 MethodUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {} |
210 bool operator()(const Klass* klass) { |
257 bool operator()(const Klass* klass) { |
211 assert(ANY_USED(klass), "invariant"); |
258 assert(ANY_USED(klass), "invariant"); |
212 if (_class_unload) { |
259 if (_current_epoch) { |
213 return leakp ? LEAKP_METHOD_USED_THIS_EPOCH(klass) : METHOD_USED_THIS_EPOCH(klass); |
260 return leakp ? LEAKP_METHOD_USED_THIS_EPOCH(klass) : METHOD_USED_THIS_EPOCH(klass); |
214 } |
261 } |
215 return leakp ? LEAKP_METHOD_USED_PREV_EPOCH(klass) : METHOD_USED_PREV_EPOCH(klass); |
262 return leakp ? LEAKP_METHOD_USED_PREV_EPOCH(klass) : METHOD_USED_PREV_EPOCH(klass); |
216 } |
263 } |
217 }; |
264 }; |
332 const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const; |
380 const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const; |
333 const JfrSymbolId::SymbolEntry* map_symbol(uintptr_t hash) const; |
381 const JfrSymbolId::SymbolEntry* map_symbol(uintptr_t hash) const; |
334 const JfrSymbolId::CStringEntry* map_cstring(uintptr_t hash) const; |
382 const JfrSymbolId::CStringEntry* map_cstring(uintptr_t hash) const; |
335 |
383 |
336 bool has_klass_entries() const; |
384 bool has_klass_entries() const; |
|
385 bool current_epoch() const { return _current_epoch; } |
337 int entries() const; |
386 int entries() const; |
|
387 size_t total_count() const; |
338 void register_klass(const Klass* k); |
388 void register_klass(const Klass* k); |
339 |
389 |
340 template <typename Functor> |
390 template <typename Functor> |
341 void iterate_klasses(Functor& functor) const { |
391 void iterate_klasses(Functor& functor) const { |
342 for (int i = 0; i < _klass_list->length(); ++i) { |
392 for (int i = 0; i < _klass_list->length(); ++i) { |