1 /*
2 * Copyright (c) 2019, 2022, Red Hat, Inc. 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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
26
27 #include "gc/shared/stringdedup/stringDedup.hpp"
28 #include "gc/shenandoah/shenandoahGenerationType.hpp"
29 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
30 #include "memory/iterator.hpp"
31 #include "runtime/javaThread.hpp"
32
33 class BarrierSetNMethod;
34 class ShenandoahBarrierSet;
35 class ShenandoahHeap;
36 class ShenandoahMarkingContext;
37 class ShenandoahReferenceProcessor;
38 class SATBMarkQueueSet;
39
40 //
41 // ========= Super
42 //
43
44 class ShenandoahSuperClosure : public MetadataVisitingOopIterateClosure {
45 protected:
46 ShenandoahHeap* const _heap;
47
48 public:
49 inline ShenandoahSuperClosure();
50 inline ShenandoahSuperClosure(ShenandoahReferenceProcessor* rp);
51 inline void do_nmethod(nmethod* nm);
52 };
53
54 //
55 // ========= Marking
56 //
57
58 class ShenandoahFlushSATBHandshakeClosure : public HandshakeClosure {
59 private:
60 SATBMarkQueueSet& _qset;
61 public:
62 inline explicit ShenandoahFlushSATBHandshakeClosure(SATBMarkQueueSet& qset);
63 inline void do_thread(Thread* thread) override;
64 };
65
66 class ShenandoahMarkRefsSuperClosure : public ShenandoahSuperClosure {
67 private:
68 ShenandoahObjToScanQueue* _queue;
69 ShenandoahObjToScanQueue* _old_queue;
70 ShenandoahMarkingContext* const _mark_context;
71 bool _weak;
72
73 protected:
74 template <class T, ShenandoahGenerationType GENERATION, bool REDIRTY>
75 void work(T *p);
76
77 public:
78 inline ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q);
79
80 bool is_weak() const {
81 return _weak;
82 }
83
84 void set_weak(bool weak) {
85 _weak = weak;
86 }
87
88 virtual void do_nmethod(nmethod* nm) {
89 assert(!is_weak(), "Can't handle weak marking of nmethods");
90 ShenandoahSuperClosure::do_nmethod(nm);
91 }
92 };
93
94 template <ShenandoahGenerationType GENERATION>
95 class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
96 private:
97 template <class T>
98 ALWAYSINLINE
99 void do_oop_work(T* p) { work<T, GENERATION, false>(p); }
100
101 public:
102 ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q) :
103 ShenandoahMarkRefsSuperClosure(q, rp, old_q) {};
104
105 ALWAYSINLINE
106 void do_oop(narrowOop* p) override { do_oop_work(p); }
107
108 ALWAYSINLINE
109 void do_oop(oop* p) override { do_oop_work(p); }
110 };
111
112 class ShenandoahRedirtyCardsMarkClosure : public ShenandoahMarkRefsSuperClosure {
113 private:
114 template <class T>
115 ALWAYSINLINE
116 void do_oop_work(T* p) { work<T, YOUNG, true>(p); }
117
118 public:
119 ShenandoahRedirtyCardsMarkClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q)
120 : ShenandoahMarkRefsSuperClosure(q, rp, old_q) {}
121
122 ALWAYSINLINE
123 void do_oop(narrowOop* p) override { do_oop_work(p); }
124
125 ALWAYSINLINE
126 void do_oop(oop* p) override { do_oop_work(p); }
127 };
128
129 class ShenandoahForwardedIsAliveClosure : public BoolObjectClosure {
130 private:
131 ShenandoahMarkingContext* const _mark_context;
132 public:
133 inline ShenandoahForwardedIsAliveClosure();
134 inline bool do_object_b(oop obj);
135 };
136
137 class ShenandoahIsAliveClosure : public BoolObjectClosure {
138 private:
139 ShenandoahMarkingContext* const _mark_context;
140 public:
141 inline ShenandoahIsAliveClosure();
142 inline bool do_object_b(oop obj);
143 };
144
145 class ShenandoahIsAliveSelector : public StackObj {
146 private:
147 ShenandoahIsAliveClosure _alive_cl;
148 ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
149 public:
150 inline BoolObjectClosure* is_alive_closure();
151 };
152
153 class ShenandoahKeepAliveClosure : public OopClosure {
154 private:
155 ShenandoahBarrierSet* const _bs;
156 template <typename T>
157 void do_oop_work(T* p);
158
159 public:
160 inline ShenandoahKeepAliveClosure();
161 inline void do_oop(oop* p) { do_oop_work(p); }
162 inline void do_oop(narrowOop* p) { do_oop_work(p); }
163 };
164
165
166 //
167 // ========= Evacuating + Roots
168 //
169
170 template <bool CONCURRENT, bool STABLE_THREAD>
171 class ShenandoahEvacuateUpdateRootClosureBase : public ShenandoahSuperClosure {
172 protected:
173 Thread* const _thread;
174 public:
175 inline ShenandoahEvacuateUpdateRootClosureBase() :
176 ShenandoahSuperClosure(),
177 _thread(STABLE_THREAD ? Thread::current() : nullptr) {}
178
179 inline void do_oop(oop* p);
180 inline void do_oop(narrowOop* p);
181 protected:
182 template <class T>
183 inline void do_oop_work(T* p);
184 };
185
186 using ShenandoahEvacuateUpdateMetadataClosure = ShenandoahEvacuateUpdateRootClosureBase<false, true>;
187 using ShenandoahEvacuateUpdateRootsClosure = ShenandoahEvacuateUpdateRootClosureBase<true, false>;
188 using ShenandoahContextEvacuateUpdateRootsClosure = ShenandoahEvacuateUpdateRootClosureBase<true, true>;
189
190
191 template <bool CONCURRENT, typename IsAlive, typename KeepAlive>
192 class ShenandoahCleanUpdateWeakOopsClosure : public OopClosure {
193 private:
194 IsAlive* _is_alive;
195 KeepAlive* _keep_alive;
196
197 public:
198 inline ShenandoahCleanUpdateWeakOopsClosure(IsAlive* is_alive, KeepAlive* keep_alive);
199 inline void do_oop(oop* p);
200 inline void do_oop(narrowOop* p);
201 };
202
203 class ShenandoahNMethodAndDisarmClosure : public NMethodToOopClosure {
204 public:
205 inline ShenandoahNMethodAndDisarmClosure(OopClosure* cl);
206 inline void do_nmethod(nmethod* nm);
207 };
208
209
210 //
211 // ========= Update References
212 //
213
214 template <ShenandoahGenerationType GENERATION>
215 class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure {
216 private:
217 template <class T>
218 inline void work(T* p);
219
220 public:
221 ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q);
222
223 virtual void do_oop(narrowOop* p) { work(p); }
224 virtual void do_oop(oop* p) { work(p); }
225 };
226
227 class ShenandoahUpdateRefsSuperClosure : public ShenandoahSuperClosure {};
228
229 class ShenandoahNonConcUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
230 private:
231 template<class T>
232 inline void work(T* p);
233
234 public:
235 virtual void do_oop(narrowOop* p) { work(p); }
236 virtual void do_oop(oop* p) { work(p); }
237 };
238
239 class ShenandoahConcUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
240 private:
241 template<class T>
242 inline void work(T* p);
243
244 public:
245 virtual void do_oop(narrowOop* p) { work(p); }
246 virtual void do_oop(oop* p) { work(p); }
247 };
248
249
250 class ShenandoahFlushSATB : public ThreadClosure {
251 private:
252 SATBMarkQueueSet& _satb_qset;
253
254 public:
255 explicit ShenandoahFlushSATB(SATBMarkQueueSet& satb_qset) : _satb_qset(satb_qset) {}
256
257 inline void do_thread(Thread* thread) override;
258 };
259
260
261 //
262 // ========= Utilities
263 //
264
265 #ifdef ASSERT
266 class ShenandoahAssertNotForwardedClosure : public OopClosure {
267 private:
268 template <class T>
269 inline void do_oop_work(T* p);
270
271 public:
272 inline void do_oop(narrowOop* p);
273 inline void do_oop(oop* p);
274 };
275 #endif // ASSERT
276
277 class ShenandoahMultiThreadClosure : public ThreadClosure {
278 ThreadClosure& _cl1;
279 ThreadClosure& _cl2;
280 public:
281 ShenandoahMultiThreadClosure(ThreadClosure& cl1, ThreadClosure& cl2) :
282 _cl1(cl1), _cl2(cl2) {}
283 inline void do_thread(Thread* thread) override {
284 _cl1.do_thread(thread);
285 _cl2.do_thread(thread);
286 }
287 };
288
289 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP