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