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 "code/nmethod.hpp"
 28 #include "gc/shared/stringdedup/stringDedup.hpp"
 29 #include "gc/shenandoah/shenandoahGenerationType.hpp"
 30 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
 31 #include "memory/iterator.hpp"
 32 #include "runtime/javaThread.hpp"
 33 
 34 class BarrierSetNMethod;
 35 class ShenandoahBarrierSet;
 36 class ShenandoahHeap;
 37 class ShenandoahMarkingContext;
 38 class ShenandoahReferenceProcessor;
 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 ShenandoahMarkRefsSuperClosure : public ShenandoahSuperClosure {
 59 private:
 60   ShenandoahObjToScanQueue* _queue;
 61   ShenandoahObjToScanQueue* _old_queue;
 62   ShenandoahMarkingContext* const _mark_context;
 63   bool _weak;
 64 
 65 protected:
 66   template <class T, ShenandoahGenerationType GENERATION>
 67   void work(T *p);
 68 
 69 public:
 70   inline ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q);
 71 
 72   bool is_weak() const {
 73     return _weak;
 74   }
 75 
 76   void set_weak(bool weak) {
 77     _weak = weak;
 78   }
 79 
 80   virtual void do_nmethod(nmethod* nm) {
 81     assert(!is_weak(), "Can't handle weak marking of nmethods");
 82     ShenandoahSuperClosure::do_nmethod(nm);
 83   }
 84 };
 85 
 86 template <ShenandoahGenerationType GENERATION>
 87 class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
 88 private:
 89   template <class T>
 90   inline void do_oop_work(T* p)     { work<T, GENERATION>(p); }
 91 
 92 public:
 93   ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q) :
 94           ShenandoahMarkRefsSuperClosure(q, rp, old_q) {};
 95 
 96   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 97   virtual void do_oop(oop* p)       { do_oop_work(p); }
 98 };
 99 
100 class ShenandoahForwardedIsAliveClosure : public BoolObjectClosure {
101 private:
102   ShenandoahMarkingContext* const _mark_context;
103 public:
104   inline ShenandoahForwardedIsAliveClosure();
105   inline bool do_object_b(oop obj);
106 };
107 
108 class ShenandoahIsAliveClosure : public BoolObjectClosure {
109 private:
110   ShenandoahMarkingContext* const _mark_context;
111 public:
112   inline ShenandoahIsAliveClosure();
113   inline bool do_object_b(oop obj);
114 };
115 
116 class ShenandoahIsAliveSelector : public StackObj {
117 private:
118   ShenandoahIsAliveClosure _alive_cl;
119   ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
120 public:
121   inline BoolObjectClosure* is_alive_closure();
122 };
123 
124 class ShenandoahKeepAliveClosure : public OopClosure {
125 private:
126   ShenandoahBarrierSet* const _bs;
127   template <typename T>
128   void do_oop_work(T* p);
129 
130 public:
131   inline ShenandoahKeepAliveClosure();
132   inline void do_oop(oop* p)       { do_oop_work(p); }
133   inline void do_oop(narrowOop* p) { do_oop_work(p); }
134 };
135 
136 
137 //
138 // ========= Evacuating + Roots
139 //
140 
141 template <bool CONCURRENT, bool STABLE_THREAD>
142 class ShenandoahEvacuateUpdateRootClosureBase : public ShenandoahSuperClosure {
143 protected:
144   Thread* const _thread;
145 public:
146   inline ShenandoahEvacuateUpdateRootClosureBase() :
147     ShenandoahSuperClosure(),
148     _thread(STABLE_THREAD ? Thread::current() : nullptr) {}
149 
150   inline void do_oop(oop* p);
151   inline void do_oop(narrowOop* p);
152 protected:
153   template <class T>
154   inline void do_oop_work(T* p);
155 };
156 
157 using ShenandoahEvacuateUpdateMetadataClosure     = ShenandoahEvacuateUpdateRootClosureBase<false, true>;
158 using ShenandoahEvacuateUpdateRootsClosure        = ShenandoahEvacuateUpdateRootClosureBase<true, false>;
159 using ShenandoahContextEvacuateUpdateRootsClosure = ShenandoahEvacuateUpdateRootClosureBase<true, true>;
160 
161 
162 template <bool CONCURRENT, typename IsAlive, typename KeepAlive>
163 class ShenandoahCleanUpdateWeakOopsClosure : public OopClosure {
164 private:
165   IsAlive*    _is_alive;
166   KeepAlive*  _keep_alive;
167 
168 public:
169   inline ShenandoahCleanUpdateWeakOopsClosure(IsAlive* is_alive, KeepAlive* keep_alive);
170   inline void do_oop(oop* p);
171   inline void do_oop(narrowOop* p);
172 };
173 
174 class ShenandoahNMethodAndDisarmClosure : public NMethodToOopClosure {
175 private:
176   BarrierSetNMethod* const _bs;
177 
178 public:
179   inline ShenandoahNMethodAndDisarmClosure(OopClosure* cl);
180   inline void do_nmethod(nmethod* nm);
181 };
182 
183 
184 //
185 // ========= Update References
186 //
187 
188 template <ShenandoahGenerationType GENERATION>
189 class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure {
190 private:
191   template <class T>
192   inline void work(T* p);
193 
194 public:
195   ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q);
196 
197   virtual void do_oop(narrowOop* p) { work(p); }
198   virtual void do_oop(oop* p)       { work(p); }
199 };
200 
201 class ShenandoahUpdateRefsSuperClosure : public ShenandoahSuperClosure {};
202 
203 class ShenandoahNonConcUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
204 private:
205   template<class T>
206   inline void work(T* p);
207 
208 public:
209   virtual void do_oop(narrowOop* p) { work(p); }
210   virtual void do_oop(oop* p)       { work(p); }
211 };
212 
213 class ShenandoahConcUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
214 private:
215   template<class T>
216   inline void work(T* p);
217 
218 public:
219   virtual void do_oop(narrowOop* p) { work(p); }
220   virtual void do_oop(oop* p)       { work(p); }
221 };
222 
223 
224 //
225 // ========= Utilities
226 //
227 
228 #ifdef ASSERT
229 class ShenandoahAssertNotForwardedClosure : public OopClosure {
230 private:
231   template <class T>
232   inline void do_oop_work(T* p);
233 
234 public:
235   inline void do_oop(narrowOop* p);
236   inline void do_oop(oop* p);
237 };
238 #endif // ASSERT
239 
240 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP