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