1/*
2 * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
25#define SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
26
27#include "gc/shared/referenceProcessor.hpp"
28#include "gc/shenandoah/shenandoahHeap.hpp"
29#include "gc/shenandoah/shenandoahStrDedupQueue.hpp"
30#include "gc/shenandoah/shenandoahTaskqueue.hpp"
31#include "gc/shenandoah/shenandoahTraversalGC.hpp"
32#include "memory/iterator.hpp"
33#include "runtime/thread.hpp"
34
35enum UpdateRefsMode {
36 NONE, // No reference updating
37 RESOLVE, // Only a resolve (no reference updating)
38 SIMPLE, // Reference updating using simple store
39 CONCURRENT // Reference updating using CAS
40};
41
42enum StringDedupMode {
43 NO_DEDUP, // Do not do anything for String deduplication
44 ENQUEUE_DEDUP // Enqueue candidate Strings for deduplication
45};
46
47class ShenandoahMarkRefsSuperClosure : public MetadataVisitingOopIterateClosure {
48private:
49 ShenandoahObjToScanQueue* _queue;
50 ShenandoahHeap* _heap;
51 ShenandoahMarkingContext* const _mark_context;
52
53protected:
54 template <class T, UpdateRefsMode UPDATE_MODE, StringDedupMode STRING_DEDUP>
55 void work(T *p);
56
57public:
58 ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp);
59};
60
61class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure {
62private:
63 template <class T>
64 inline void do_oop_work(T* p) { work<T, CONCURRENT, NO_DEDUP>(p); }
65
66public:
67 ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
68 ShenandoahMarkRefsSuperClosure(q, rp) {};
69
70 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
71 virtual void do_oop(oop* p) { do_oop_work(p); }
72 virtual bool do_metadata() { return false; }
73};
74
75class ShenandoahMarkUpdateRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
76private:
77 template <class T>
78 inline void do_oop_work(T* p) { work<T, CONCURRENT, ENQUEUE_DEDUP>(p); }
79
80public:
81 ShenandoahMarkUpdateRefsDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
82 ShenandoahMarkRefsSuperClosure(q, rp) {};
83
84 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
85 virtual void do_oop(oop* p) { do_oop_work(p); }
86 virtual bool do_metadata() { return false; }
87};
88
89class ShenandoahMarkUpdateRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
90private:
91 template <class T>
92 inline void do_oop_work(T* p) { work<T, CONCURRENT, NO_DEDUP>(p); }
93
94public:
95 ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
96 ShenandoahMarkRefsSuperClosure(q, rp) {};
97
98 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
99 virtual void do_oop(oop* p) { do_oop_work(p); }
100 virtual bool do_metadata() { return true; }
101};
102
103class ShenandoahMarkUpdateRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
104private:
105 template <class T>
106 inline void do_oop_work(T* p) { work<T, CONCURRENT, ENQUEUE_DEDUP>(p); }
107
108public:
109 ShenandoahMarkUpdateRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
110 ShenandoahMarkRefsSuperClosure(q, rp) {};
111
112 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
113 virtual void do_oop(oop* p) { do_oop_work(p); }
114 virtual bool do_metadata() { return true; }
115};
116
117class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
118private:
119 template <class T>
120 inline void do_oop_work(T* p) { work<T, NONE, NO_DEDUP>(p); }
121
122public:
123 ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
124 ShenandoahMarkRefsSuperClosure(q, rp) {};
125
126 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
127 virtual void do_oop(oop* p) { do_oop_work(p); }
128 virtual bool do_metadata() { return false; }
129};
130
131class ShenandoahMarkRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
132private:
133 template <class T>
134 inline void do_oop_work(T* p) { work<T, NONE, ENQUEUE_DEDUP>(p); }
135
136public:
137 ShenandoahMarkRefsDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
138 ShenandoahMarkRefsSuperClosure(q, rp) {};
139
140 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
141 virtual void do_oop(oop* p) { do_oop_work(p); }
142 virtual bool do_metadata() { return false; }
143};
144
145class ShenandoahMarkResolveRefsClosure : public ShenandoahMarkRefsSuperClosure {
146private:
147 template <class T>
148 inline void do_oop_work(T* p) { work<T, RESOLVE, NO_DEDUP>(p); }
149
150public:
151 ShenandoahMarkResolveRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
152 ShenandoahMarkRefsSuperClosure(q, rp) {};
153
154 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
155 virtual void do_oop(oop* p) { do_oop_work(p); }
156 virtual bool do_metadata() { return false; }
157};
158
159class ShenandoahMarkRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
160private:
161 template <class T>
162 inline void do_oop_work(T* p) { work<T, NONE, NO_DEDUP>(p); }
163
164public:
165 ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
166 ShenandoahMarkRefsSuperClosure(q, rp) {};
167
168 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
169 virtual void do_oop(oop* p) { do_oop_work(p); }
170 virtual bool do_metadata() { return true; }
171};
172
173class ShenandoahMarkRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
174private:
175 template <class T>
176 inline void do_oop_work(T* p) { work<T, NONE, ENQUEUE_DEDUP>(p); }
177
178public:
179 ShenandoahMarkRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
180 ShenandoahMarkRefsSuperClosure(q, rp) {};
181
182 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
183 virtual void do_oop(oop* p) { do_oop_work(p); }
184 virtual bool do_metadata() { return true; }
185};
186
187class ShenandoahUpdateHeapRefsClosure : public BasicOopIterateClosure {
188private:
189 ShenandoahHeap* _heap;
190
191 template <class T>
192 void do_oop_work(T* p);
193
194public:
195 ShenandoahUpdateHeapRefsClosure() :
196 _heap(ShenandoahHeap::heap()) {}
197
198 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
199 virtual void do_oop(oop* p) { do_oop_work(p); }
200};
201
202class ShenandoahTraversalSuperClosure : public MetadataVisitingOopIterateClosure {
203private:
204 ShenandoahTraversalGC* const _traversal_gc;
205 Thread* const _thread;
206 ShenandoahObjToScanQueue* const _queue;
207 ShenandoahMarkingContext* const _mark_context;
208protected:
209 ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
210 MetadataVisitingOopIterateClosure(rp),
211 _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
212 _thread(Thread::current()),
213 _queue(q),
214 _mark_context(ShenandoahHeap::heap()->marking_context()) {
215 }
216
217 template <class T, bool STRING_DEDUP, bool DEGEN>
218 void work(T* p);
219
220};
221
222class ShenandoahTraversalClosure : public ShenandoahTraversalSuperClosure {
223private:
224 template <class T>
225 inline void do_oop_work(T* p) { work<T, false, false>(p); }
226
227public:
228 ShenandoahTraversalClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
229 ShenandoahTraversalSuperClosure(q, rp) {}
230
231 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
232 virtual void do_oop(oop* p) { do_oop_work(p); }
233
234 virtual bool do_metadata() { return false; }
235};
236
237class ShenandoahTraversalMetadataClosure : public ShenandoahTraversalSuperClosure {
238private:
239 template <class T>
240 inline void do_oop_work(T* p) { work<T, false, false>(p); }
241
242public:
243 ShenandoahTraversalMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
244 ShenandoahTraversalSuperClosure(q, rp) {}
245
246 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
247 virtual void do_oop(oop* p) { do_oop_work(p); }
248
249 virtual bool do_metadata() { return true; }
250};
251
252class ShenandoahTraversalDedupClosure : public ShenandoahTraversalSuperClosure {
253private:
254 template <class T>
255 inline void do_oop_work(T* p) { work<T, true, false>(p); }
256
257public:
258 ShenandoahTraversalDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
259 ShenandoahTraversalSuperClosure(q, rp) {}
260
261 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
262 virtual void do_oop(oop* p) { do_oop_work(p); }
263
264 virtual bool do_metadata() { return false; }
265};
266
267class ShenandoahTraversalMetadataDedupClosure : public ShenandoahTraversalSuperClosure {
268private:
269 template <class T>
270 inline void do_oop_work(T* p) { work<T, true, false>(p); }
271
272public:
273 ShenandoahTraversalMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
274 ShenandoahTraversalSuperClosure(q, rp) {}
275
276 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
277 virtual void do_oop(oop* p) { do_oop_work(p); }
278
279 virtual bool do_metadata() { return true; }
280};
281
282class ShenandoahTraversalDegenClosure : public ShenandoahTraversalSuperClosure {
283private:
284 template <class T>
285 inline void do_oop_work(T* p) { work<T, false, true>(p); }
286
287public:
288 ShenandoahTraversalDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
289 ShenandoahTraversalSuperClosure(q, rp) {}
290
291 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
292 virtual void do_oop(oop* p) { do_oop_work(p); }
293
294 virtual bool do_metadata() { return false; }
295};
296
297class ShenandoahTraversalMetadataDegenClosure : public ShenandoahTraversalSuperClosure {
298private:
299 template <class T>
300 inline void do_oop_work(T* p) { work<T, false, true>(p); }
301
302public:
303 ShenandoahTraversalMetadataDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
304 ShenandoahTraversalSuperClosure(q, rp) {}
305
306 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
307 virtual void do_oop(oop* p) { do_oop_work(p); }
308
309 virtual bool do_metadata() { return true; }
310};
311
312class ShenandoahTraversalDedupDegenClosure : public ShenandoahTraversalSuperClosure {
313private:
314 template <class T>
315 inline void do_oop_work(T* p) { work<T, true, true>(p); }
316
317public:
318 ShenandoahTraversalDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
319 ShenandoahTraversalSuperClosure(q, rp) {}
320
321 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
322 virtual void do_oop(oop* p) { do_oop_work(p); }
323
324 virtual bool do_metadata() { return false; }
325};
326
327class ShenandoahTraversalMetadataDedupDegenClosure : public ShenandoahTraversalSuperClosure {
328private:
329 template <class T>
330 inline void do_oop_work(T* p) { work<T, true, true>(p); }
331
332public:
333 ShenandoahTraversalMetadataDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
334 ShenandoahTraversalSuperClosure(q, rp) {}
335
336 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
337 virtual void do_oop(oop* p) { do_oop_work(p); }
338
339 virtual bool do_metadata() { return true; }
340};
341
342#endif // SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
343