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 | ///////////////////////////////////////////////////////////////// |
35 | class ConcurrentMarkSweepGeneration; |
36 | class CMSBitMap; |
37 | class CMSMarkStack; |
38 | class CMSCollector; |
39 | class MarkFromRootsClosure; |
40 | class ParMarkFromRootsClosure; |
41 | |
42 | class 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. |
52 | class 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 | |
59 | class 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 | |
71 | class 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. |
85 | class 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). |
100 | class 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. |
128 | class 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). |
147 | class 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. |
186 | class 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. |
210 | class 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. |
241 | class 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. |
278 | class 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 | |
296 | class 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. |
315 | class 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 | |