1 /*
2 * Copyright (c) 2001, 2016, 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_GC_SHARED_REFERENCEPROCESSOR_HPP
26 #define SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_HPP
27
28 #include "gc/shared/gcTrace.hpp"
29 #include "gc/shared/referencePolicy.hpp"
30 #include "gc/shared/referenceProcessorStats.hpp"
31 #include "memory/referenceType.hpp"
32 #include "oops/instanceRefKlass.hpp"
33
34 class GCTimer;
35
36 // ReferenceProcessor class encapsulates the per-"collector" processing
37 // of java.lang.Reference objects for GC. The interface is useful for supporting
38 // a generational abstraction, in particular when there are multiple
39 // generations that are being independently collected -- possibly
40 // concurrently and/or incrementally. Note, however, that the
41 // ReferenceProcessor class abstracts away from a generational setting
42 // by using only a heap interval (called "span" below), thus allowing
43 // its use in a straightforward manner in a general, non-generational
44 // setting.
45 //
46 // The basic idea is that each ReferenceProcessor object concerns
47 // itself with ("weak") reference processing in a specific "span"
48 // of the heap of interest to a specific collector. Currently,
49 // the span is a convex interval of the heap, but, efficiency
203 static ReferencePolicy* _always_clear_soft_ref_policy;
204 // . the current policy below is either one of the above
205 ReferencePolicy* _current_soft_ref_policy;
206
207 // The discovered ref lists themselves
208
209 // The active MT'ness degree of the queues below
210 uint _num_q;
211 // The maximum MT'ness degree of the queues below
212 uint _max_num_q;
213
214 // Master array of discovered oops
215 DiscoveredList* _discovered_refs;
216
217 // Arrays of lists of oops, one per thread (pointers into master array above)
218 DiscoveredList* _discoveredSoftRefs;
219 DiscoveredList* _discoveredWeakRefs;
220 DiscoveredList* _discoveredFinalRefs;
221 DiscoveredList* _discoveredPhantomRefs;
222
223 public:
224 static int number_of_subclasses_of_ref() { return (REF_PHANTOM - REF_OTHER); }
225
226 uint num_q() { return _num_q; }
227 uint max_num_q() { return _max_num_q; }
228 void set_active_mt_degree(uint v);
229
230 DiscoveredList* discovered_refs() { return _discovered_refs; }
231
232 ReferencePolicy* setup_policy(bool always_clear) {
233 _current_soft_ref_policy = always_clear ?
234 _always_clear_soft_ref_policy : _default_soft_ref_policy;
235 _current_soft_ref_policy->setup(); // snapshot the policy threshold
236 return _current_soft_ref_policy;
237 }
238
239 // Process references with a certain reachability level.
240 void process_discovered_reflist(DiscoveredList refs_lists[],
241 ReferencePolicy* policy,
242 bool clear_referent,
243 BoolObjectClosure* is_alive,
244 OopClosure* keep_alive,
245 VoidClosure* complete_gc,
246 AbstractRefProcTaskExecutor* task_executor);
247
248 void process_phaseJNI(BoolObjectClosure* is_alive,
249 OopClosure* keep_alive,
250 VoidClosure* complete_gc);
251
252 // Work methods used by the method process_discovered_reflist
253 // Phase1: keep alive all those referents that are otherwise
254 // dead but which must be kept alive by policy (and their closure).
255 void process_phase1(DiscoveredList& refs_list,
256 ReferencePolicy* policy,
257 BoolObjectClosure* is_alive,
258 OopClosure* keep_alive,
259 VoidClosure* complete_gc);
260 // Phase2: remove all those references whose referents are
261 // reachable.
262 inline void process_phase2(DiscoveredList& refs_list,
263 BoolObjectClosure* is_alive,
264 OopClosure* keep_alive,
265 VoidClosure* complete_gc) {
266 if (discovery_is_atomic()) {
294
295 // "Preclean" all the discovered reference lists
296 // by removing references with strongly reachable referents.
297 // The first argument is a predicate on an oop that indicates
298 // its (strong) reachability and the second is a closure that
299 // may be used to incrementalize or abort the precleaning process.
300 // The caller is responsible for taking care of potential
301 // interference with concurrent operations on these lists
302 // (or predicates involved) by other threads. Currently
303 // only used by the CMS collector.
304 void preclean_discovered_references(BoolObjectClosure* is_alive,
305 OopClosure* keep_alive,
306 VoidClosure* complete_gc,
307 YieldClosure* yield,
308 GCTimer* gc_timer);
309
310 // Returns the name of the discovered reference list
311 // occupying the i / _num_q slot.
312 const char* list_name(uint i);
313
314 void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor);
315
316 protected:
317 // "Preclean" the given discovered reference list
318 // by removing references with strongly reachable referents.
319 // Currently used in support of CMS only.
320 void preclean_discovered_reflist(DiscoveredList& refs_list,
321 BoolObjectClosure* is_alive,
322 OopClosure* keep_alive,
323 VoidClosure* complete_gc,
324 YieldClosure* yield);
325
326 // round-robin mod _num_q (not: _not_ mode _max_num_q)
327 uint next_id() {
328 uint id = _next_id;
329 assert(!_discovery_is_mt, "Round robin should only be used in serial discovery");
330 if (++_next_id == _num_q) {
331 _next_id = 0;
332 }
333 assert(_next_id < _num_q, "_next_id %u _num_q %u _max_num_q %u", _next_id, _num_q, _max_num_q);
334 return id;
407
408 // Balance each of the discovered lists.
409 void balance_all_queues();
410 void verify_list(DiscoveredList& ref_list);
411
412 // Discover a Reference object, using appropriate discovery criteria
413 bool discover_reference(oop obj, ReferenceType rt);
414
415 // Has discovered references that need handling
416 bool has_discovered_references();
417
418 // Process references found during GC (called by the garbage collector)
419 ReferenceProcessorStats
420 process_discovered_references(BoolObjectClosure* is_alive,
421 OopClosure* keep_alive,
422 VoidClosure* complete_gc,
423 AbstractRefProcTaskExecutor* task_executor,
424 GCTimer *gc_timer);
425
426 // Enqueue references at end of GC (called by the garbage collector)
427 void enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
428
429 // If a discovery is in process that is being superceded, abandon it: all
430 // the discovered lists will be empty, and all the objects on them will
431 // have NULL discovered fields. Must be called only at a safepoint.
432 void abandon_partial_discovery();
433
434 // debugging
435 void verify_no_references_recorded() PRODUCT_RETURN;
436 void verify_referent(oop obj) PRODUCT_RETURN;
437 };
438
439 // A utility class to disable reference discovery in
440 // the scope which contains it, for given ReferenceProcessor.
441 class NoRefDiscovery: StackObj {
442 private:
443 ReferenceProcessor* _rp;
444 bool _was_discovering_refs;
445 public:
446 NoRefDiscovery(ReferenceProcessor* rp) : _rp(rp) {
447 _was_discovering_refs = _rp->discovery_enabled();
|
1 /*
2 * Copyright (c) 2001, 2017, 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_GC_SHARED_REFERENCEPROCESSOR_HPP
26 #define SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_HPP
27
28 #include "gc/shared/gcTrace.hpp"
29 #include "gc/shared/referencePolicy.hpp"
30 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
31 #include "gc/shared/referenceProcessorStats.hpp"
32 #include "memory/referenceType.hpp"
33 #include "oops/instanceRefKlass.hpp"
34
35 class GCTimer;
36
37 // ReferenceProcessor class encapsulates the per-"collector" processing
38 // of java.lang.Reference objects for GC. The interface is useful for supporting
39 // a generational abstraction, in particular when there are multiple
40 // generations that are being independently collected -- possibly
41 // concurrently and/or incrementally. Note, however, that the
42 // ReferenceProcessor class abstracts away from a generational setting
43 // by using only a heap interval (called "span" below), thus allowing
44 // its use in a straightforward manner in a general, non-generational
45 // setting.
46 //
47 // The basic idea is that each ReferenceProcessor object concerns
48 // itself with ("weak") reference processing in a specific "span"
49 // of the heap of interest to a specific collector. Currently,
50 // the span is a convex interval of the heap, but, efficiency
204 static ReferencePolicy* _always_clear_soft_ref_policy;
205 // . the current policy below is either one of the above
206 ReferencePolicy* _current_soft_ref_policy;
207
208 // The discovered ref lists themselves
209
210 // The active MT'ness degree of the queues below
211 uint _num_q;
212 // The maximum MT'ness degree of the queues below
213 uint _max_num_q;
214
215 // Master array of discovered oops
216 DiscoveredList* _discovered_refs;
217
218 // Arrays of lists of oops, one per thread (pointers into master array above)
219 DiscoveredList* _discoveredSoftRefs;
220 DiscoveredList* _discoveredWeakRefs;
221 DiscoveredList* _discoveredFinalRefs;
222 DiscoveredList* _discoveredPhantomRefs;
223
224 ReferenceProcessorPhaseTimes* _phase_times;
225
226 public:
227 static int number_of_subclasses_of_ref() { return (REF_PHANTOM - REF_OTHER); }
228
229 uint num_q() { return _num_q; }
230 uint max_num_q() { return _max_num_q; }
231 void set_active_mt_degree(uint v);
232
233 DiscoveredList* discovered_refs() { return _discovered_refs; }
234
235 ReferencePolicy* setup_policy(bool always_clear) {
236 _current_soft_ref_policy = always_clear ?
237 _always_clear_soft_ref_policy : _default_soft_ref_policy;
238 _current_soft_ref_policy->setup(); // snapshot the policy threshold
239 return _current_soft_ref_policy;
240 }
241
242 // Process references with a certain reachability level.
243 void process_discovered_reflist(DiscoveredList refs_lists[],
244 ReferencePolicy* policy,
245 bool clear_referent,
246 BoolObjectClosure* is_alive,
247 OopClosure* keep_alive,
248 VoidClosure* complete_gc,
249 AbstractRefProcTaskExecutor* task_executor,
250 GCTimer* gc_timer);
251
252 void process_phaseJNI(BoolObjectClosure* is_alive,
253 OopClosure* keep_alive,
254 VoidClosure* complete_gc);
255
256 // Work methods used by the method process_discovered_reflist
257 // Phase1: keep alive all those referents that are otherwise
258 // dead but which must be kept alive by policy (and their closure).
259 void process_phase1(DiscoveredList& refs_list,
260 ReferencePolicy* policy,
261 BoolObjectClosure* is_alive,
262 OopClosure* keep_alive,
263 VoidClosure* complete_gc);
264 // Phase2: remove all those references whose referents are
265 // reachable.
266 inline void process_phase2(DiscoveredList& refs_list,
267 BoolObjectClosure* is_alive,
268 OopClosure* keep_alive,
269 VoidClosure* complete_gc) {
270 if (discovery_is_atomic()) {
298
299 // "Preclean" all the discovered reference lists
300 // by removing references with strongly reachable referents.
301 // The first argument is a predicate on an oop that indicates
302 // its (strong) reachability and the second is a closure that
303 // may be used to incrementalize or abort the precleaning process.
304 // The caller is responsible for taking care of potential
305 // interference with concurrent operations on these lists
306 // (or predicates involved) by other threads. Currently
307 // only used by the CMS collector.
308 void preclean_discovered_references(BoolObjectClosure* is_alive,
309 OopClosure* keep_alive,
310 VoidClosure* complete_gc,
311 YieldClosure* yield,
312 GCTimer* gc_timer);
313
314 // Returns the name of the discovered reference list
315 // occupying the i / _num_q slot.
316 const char* list_name(uint i);
317
318 void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor, GCTimer* gc_timer);
319
320 ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; }
321
322 protected:
323 // "Preclean" the given discovered reference list
324 // by removing references with strongly reachable referents.
325 // Currently used in support of CMS only.
326 void preclean_discovered_reflist(DiscoveredList& refs_list,
327 BoolObjectClosure* is_alive,
328 OopClosure* keep_alive,
329 VoidClosure* complete_gc,
330 YieldClosure* yield);
331
332 // round-robin mod _num_q (not: _not_ mode _max_num_q)
333 uint next_id() {
334 uint id = _next_id;
335 assert(!_discovery_is_mt, "Round robin should only be used in serial discovery");
336 if (++_next_id == _num_q) {
337 _next_id = 0;
338 }
339 assert(_next_id < _num_q, "_next_id %u _num_q %u _max_num_q %u", _next_id, _num_q, _max_num_q);
340 return id;
413
414 // Balance each of the discovered lists.
415 void balance_all_queues();
416 void verify_list(DiscoveredList& ref_list);
417
418 // Discover a Reference object, using appropriate discovery criteria
419 bool discover_reference(oop obj, ReferenceType rt);
420
421 // Has discovered references that need handling
422 bool has_discovered_references();
423
424 // Process references found during GC (called by the garbage collector)
425 ReferenceProcessorStats
426 process_discovered_references(BoolObjectClosure* is_alive,
427 OopClosure* keep_alive,
428 VoidClosure* complete_gc,
429 AbstractRefProcTaskExecutor* task_executor,
430 GCTimer *gc_timer);
431
432 // Enqueue references at end of GC (called by the garbage collector)
433 void enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL,
434 GCTimer* gc_timer = NULL);
435
436 // If a discovery is in process that is being superceded, abandon it: all
437 // the discovered lists will be empty, and all the objects on them will
438 // have NULL discovered fields. Must be called only at a safepoint.
439 void abandon_partial_discovery();
440
441 // debugging
442 void verify_no_references_recorded() PRODUCT_RETURN;
443 void verify_referent(oop obj) PRODUCT_RETURN;
444 };
445
446 // A utility class to disable reference discovery in
447 // the scope which contains it, for given ReferenceProcessor.
448 class NoRefDiscovery: StackObj {
449 private:
450 ReferenceProcessor* _rp;
451 bool _was_discovering_refs;
452 public:
453 NoRefDiscovery(ReferenceProcessor* rp) : _rp(rp) {
454 _was_discovering_refs = _rp->discovery_enabled();
|