1/*
2 * Copyright (c) 2007, 2019, 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_GC_CMS_CMSOOPCLOSURES_HPP
26#define SHARE_GC_CMS_CMSOOPCLOSURES_HPP
27
28#include "gc/shared/genOopClosures.hpp"
29#include "gc/shared/taskqueue.hpp"
30#include "memory/iterator.hpp"
31
32/////////////////////////////////////////////////////////////////
33// Closures used by ConcurrentMarkSweepGeneration's collector
34/////////////////////////////////////////////////////////////////
35class ConcurrentMarkSweepGeneration;
36class CMSBitMap;
37class CMSMarkStack;
38class CMSCollector;
39class MarkFromRootsClosure;
40class ParMarkFromRootsClosure;
41
42class Mutex;
43
44// Decode the oop and call do_oop on it.
45#define DO_OOP_WORK_DEFN \
46 void do_oop(oop obj); \
47 template <class T> inline void do_oop_work(T* p);
48
49// TODO: This duplication of the MetadataVisitingOopIterateClosure class is only needed
50// because some CMS OopClosures derive from OopsInGenClosure. It would be
51// good to get rid of them completely.
52class MetadataVisitingOopsInGenClosure: public OopsInGenClosure {
53 public:
54 virtual bool do_metadata() { return true; }
55 virtual void do_klass(Klass* k);
56 virtual void do_cld(ClassLoaderData* cld);
57};
58
59class MarkRefsIntoClosure: public MetadataVisitingOopsInGenClosure {
60 private:
61 const MemRegion _span;
62 CMSBitMap* _bitMap;
63 protected:
64 DO_OOP_WORK_DEFN
65 public:
66 MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
67 virtual void do_oop(oop* p);
68 virtual void do_oop(narrowOop* p);
69};
70
71class ParMarkRefsIntoClosure: public MetadataVisitingOopsInGenClosure {
72 private:
73 const MemRegion _span;
74 CMSBitMap* _bitMap;
75 protected:
76 DO_OOP_WORK_DEFN
77 public:
78 ParMarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
79 virtual void do_oop(oop* p);
80 virtual void do_oop(narrowOop* p);
81};
82
83// A variant of the above used in certain kinds of CMS
84// marking verification.
85class MarkRefsIntoVerifyClosure: public MetadataVisitingOopsInGenClosure {
86 private:
87 const MemRegion _span;
88 CMSBitMap* _verification_bm;
89 CMSBitMap* _cms_bm;
90 protected:
91 DO_OOP_WORK_DEFN
92 public:
93 MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
94 CMSBitMap* cms_bm);
95 virtual void do_oop(oop* p);
96 virtual void do_oop(narrowOop* p);
97};
98
99// The non-parallel version (the parallel version appears further below).
100class PushAndMarkClosure: public MetadataVisitingOopIterateClosure {
101 private:
102 CMSCollector* _collector;
103 MemRegion _span;
104 CMSBitMap* _bit_map;
105 CMSBitMap* _mod_union_table;
106 CMSMarkStack* _mark_stack;
107 bool _concurrent_precleaning;
108 protected:
109 DO_OOP_WORK_DEFN
110 public:
111 PushAndMarkClosure(CMSCollector* collector,
112 MemRegion span,
113 ReferenceDiscoverer* rd,
114 CMSBitMap* bit_map,
115 CMSBitMap* mod_union_table,
116 CMSMarkStack* mark_stack,
117 bool concurrent_precleaning);
118 virtual void do_oop(oop* p);
119 virtual void do_oop(narrowOop* p);
120};
121
122// In the parallel case, the bit map and the
123// reference processor are currently all shared. Access to
124// these shared mutable structures must use appropriate
125// synchronization (for instance, via CAS). The marking stack
126// used in the non-parallel case above is here replaced with
127// an OopTaskQueue structure to allow efficient work stealing.
128class ParPushAndMarkClosure: public MetadataVisitingOopIterateClosure {
129 private:
130 CMSCollector* _collector;
131 MemRegion _span;
132 CMSBitMap* _bit_map;
133 OopTaskQueue* _work_queue;
134 protected:
135 DO_OOP_WORK_DEFN
136 public:
137 ParPushAndMarkClosure(CMSCollector* collector,
138 MemRegion span,
139 ReferenceDiscoverer* rd,
140 CMSBitMap* bit_map,
141 OopTaskQueue* work_queue);
142 virtual void do_oop(oop* p);
143 virtual void do_oop(narrowOop* p);
144};
145
146// The non-parallel version (the parallel version appears further below).
147class MarkRefsIntoAndScanClosure: public MetadataVisitingOopsInGenClosure {
148 private:
149 MemRegion _span;
150 CMSBitMap* _bit_map;
151 CMSMarkStack* _mark_stack;
152 PushAndMarkClosure _pushAndMarkClosure;
153 CMSCollector* _collector;
154 Mutex* _freelistLock;
155 bool _yield;
156 // Whether closure is being used for concurrent precleaning
157 bool _concurrent_precleaning;
158 protected:
159 DO_OOP_WORK_DEFN
160 public:
161 MarkRefsIntoAndScanClosure(MemRegion span,
162 ReferenceDiscoverer* rd,
163 CMSBitMap* bit_map,
164 CMSBitMap* mod_union_table,
165 CMSMarkStack* mark_stack,
166 CMSCollector* collector,
167 bool should_yield,
168 bool concurrent_precleaning);
169 virtual void do_oop(oop* p);
170 virtual void do_oop(narrowOop* p);
171
172 void set_freelistLock(Mutex* m) {
173 _freelistLock = m;
174 }
175
176 private:
177 inline void do_yield_check();
178 void do_yield_work();
179 bool take_from_overflow_list();
180};
181
182// In this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
183// stack and the bitMap are shared, so access needs to be suitably
184// synchronized. An OopTaskQueue structure, supporting efficient
185// work stealing, replaces a CMSMarkStack for storing grey objects.
186class ParMarkRefsIntoAndScanClosure: public MetadataVisitingOopsInGenClosure {
187 private:
188 MemRegion _span;
189 CMSBitMap* _bit_map;
190 OopTaskQueue* _work_queue;
191 const uint _low_water_mark;
192 ParPushAndMarkClosure _parPushAndMarkClosure;
193 protected:
194 DO_OOP_WORK_DEFN
195 public:
196 ParMarkRefsIntoAndScanClosure(CMSCollector* collector,
197 MemRegion span,
198 ReferenceDiscoverer* rd,
199 CMSBitMap* bit_map,
200 OopTaskQueue* work_queue);
201 virtual void do_oop(oop* p);
202 virtual void do_oop(narrowOop* p);
203
204 void trim_queue(uint size);
205};
206
207// This closure is used during the concurrent marking phase
208// following the first checkpoint. Its use is buried in
209// the closure MarkFromRootsClosure.
210class PushOrMarkClosure: public MetadataVisitingOopIterateClosure {
211 private:
212 CMSCollector* _collector;
213 MemRegion _span;
214 CMSBitMap* _bitMap;
215 CMSMarkStack* _markStack;
216 HeapWord* const _finger;
217 MarkFromRootsClosure* const
218 _parent;
219 protected:
220 DO_OOP_WORK_DEFN
221 public:
222 PushOrMarkClosure(CMSCollector* cms_collector,
223 MemRegion span,
224 CMSBitMap* bitMap,
225 CMSMarkStack* markStack,
226 HeapWord* finger,
227 MarkFromRootsClosure* parent);
228 virtual void do_oop(oop* p);
229 virtual void do_oop(narrowOop* p);
230
231 // Deal with a stack overflow condition
232 void handle_stack_overflow(HeapWord* lost);
233 private:
234 inline void do_yield_check();
235};
236
237// A parallel (MT) version of the above.
238// This closure is used during the concurrent marking phase
239// following the first checkpoint. Its use is buried in
240// the closure ParMarkFromRootsClosure.
241class ParPushOrMarkClosure: public MetadataVisitingOopIterateClosure {
242 private:
243 CMSCollector* _collector;
244 MemRegion _whole_span;
245 MemRegion _span; // local chunk
246 CMSBitMap* _bit_map;
247 OopTaskQueue* _work_queue;
248 CMSMarkStack* _overflow_stack;
249 HeapWord* const _finger;
250 HeapWord* volatile* const _global_finger_addr;
251 ParMarkFromRootsClosure* const _parent;
252 protected:
253 DO_OOP_WORK_DEFN
254 public:
255 ParPushOrMarkClosure(CMSCollector* cms_collector,
256 MemRegion span,
257 CMSBitMap* bit_map,
258 OopTaskQueue* work_queue,
259 CMSMarkStack* mark_stack,
260 HeapWord* finger,
261 HeapWord* volatile* global_finger_addr,
262 ParMarkFromRootsClosure* parent);
263 virtual void do_oop(oop* p);
264 virtual void do_oop(narrowOop* p);
265
266 // Deal with a stack overflow condition
267 void handle_stack_overflow(HeapWord* lost);
268 private:
269 inline void do_yield_check();
270};
271
272// For objects in CMS generation, this closure marks
273// given objects (transitively) as being reachable/live.
274// This is currently used during the (weak) reference object
275// processing phase of the CMS final checkpoint step, as
276// well as during the concurrent precleaning of the discovered
277// reference lists.
278class CMSKeepAliveClosure: public MetadataVisitingOopIterateClosure {
279 private:
280 CMSCollector* _collector;
281 const MemRegion _span;
282 CMSMarkStack* _mark_stack;
283 CMSBitMap* _bit_map;
284 bool _concurrent_precleaning;
285 protected:
286 DO_OOP_WORK_DEFN
287 public:
288 CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
289 CMSBitMap* bit_map, CMSMarkStack* mark_stack,
290 bool cpc);
291 bool concurrent_precleaning() const { return _concurrent_precleaning; }
292 virtual void do_oop(oop* p);
293 virtual void do_oop(narrowOop* p);
294};
295
296class CMSInnerParMarkAndPushClosure: public MetadataVisitingOopIterateClosure {
297 private:
298 CMSCollector* _collector;
299 MemRegion _span;
300 OopTaskQueue* _work_queue;
301 CMSBitMap* _bit_map;
302 protected:
303 DO_OOP_WORK_DEFN
304 public:
305 CMSInnerParMarkAndPushClosure(CMSCollector* collector,
306 MemRegion span, CMSBitMap* bit_map,
307 OopTaskQueue* work_queue);
308 virtual void do_oop(oop* p);
309 virtual void do_oop(narrowOop* p);
310};
311
312// A parallel (MT) version of the above, used when
313// reference processing is parallel; the only difference
314// is in the do_oop method.
315class CMSParKeepAliveClosure: public MetadataVisitingOopIterateClosure {
316 private:
317 MemRegion _span;
318 OopTaskQueue* _work_queue;
319 CMSBitMap* _bit_map;
320 CMSInnerParMarkAndPushClosure
321 _mark_and_push;
322 const uint _low_water_mark;
323 void trim_queue(uint max);
324 protected:
325 DO_OOP_WORK_DEFN
326 public:
327 CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
328 CMSBitMap* bit_map, OopTaskQueue* work_queue);
329 virtual void do_oop(oop* p);
330 virtual void do_oop(narrowOop* p);
331};
332
333#endif // SHARE_GC_CMS_CMSOOPCLOSURES_HPP
334