1 /*
  2  * Copyright (c) 2015, 2021, 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 
 25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
 27 
 28 #include "gc/shared/stringdedup/stringDedup.hpp"
 29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 30 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
 31 #include "gc/shenandoah/shenandoahUtils.hpp"
 32 #include "memory/iterator.hpp"
 33 #include "runtime/thread.hpp"
 34 
 35 enum StringDedupMode {
 36   NO_DEDUP,      // Do not do anything for String deduplication
 37   ENQUEUE_DEDUP, // Enqueue candidate Strings for deduplication, if meet age threshold
 38   ALWAYS_DEDUP   // Enqueue Strings for deduplication
 39 };
 40 
 41 class ShenandoahMarkRefsSuperClosure : public MetadataVisitingOopIterateClosure {
 42 private:
 43   ShenandoahObjToScanQueue* _queue;
 44   ShenandoahObjToScanQueue* _old_queue;
 45   ShenandoahMarkingContext* const _mark_context;
 46   bool _weak;
 47 
 48 protected:
 49   template <class T, GenerationMode GENERATION>
 50   void work(T *p);
 51 
 52 public:
 53   ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp,  ShenandoahObjToScanQueue* old_queue = NULL);
 54 
 55   bool is_weak() const {
 56     return _weak;
 57   }
 58 
 59   void set_weak(bool weak) {
 60     _weak = weak;
 61   }
 62 };
 63 
 64 class ShenandoahMarkUpdateRefsSuperClosure : public ShenandoahMarkRefsSuperClosure {
 65 protected:
 66   ShenandoahHeap* const _heap;
 67 
 68   template <class T, GenerationMode GENERATION>
 69   inline void work(T* p);
 70 
 71 public:
 72   ShenandoahMarkUpdateRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old = NULL) :
 73     ShenandoahMarkRefsSuperClosure(q, rp, old),
 74     _heap(ShenandoahHeap::heap()) {
 75     assert(_heap->is_stw_gc_in_progress(), "Can only be used for STW GC");
 76   };
 77 };
 78 
 79 template <GenerationMode GENERATION>
 80 class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkUpdateRefsSuperClosure {
 81 private:
 82   template <class T>
 83   inline void do_oop_work(T* p)     { work<T, GENERATION>(p); }
 84 
 85 public:
 86   ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old = NULL) :
 87     ShenandoahMarkUpdateRefsSuperClosure(q, rp, old) {}
 88 
 89   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 90   virtual void do_oop(oop* p)       { do_oop_work(p); }
 91   virtual bool do_metadata()        { return false; }
 92 };
 93 
 94 template <GenerationMode GENERATION>
 95 class ShenandoahMarkUpdateRefsMetadataClosure : public ShenandoahMarkUpdateRefsSuperClosure {
 96 private:
 97   template <class T>
 98   inline void do_oop_work(T* p)     { work<T, GENERATION>(p); }
 99 
100 public:
101   ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old = NULL) :
102     ShenandoahMarkUpdateRefsSuperClosure(q, rp, old) {}
103 
104   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
105   virtual void do_oop(oop* p)       { do_oop_work(p); }
106   virtual bool do_metadata()        { return true; }
107 };
108 
109 template <GenerationMode GENERATION>
110 class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
111 private:
112   template <class T>
113   inline void do_oop_work(T* p)     { work<T, GENERATION>(p); }
114 
115 public:
116   ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old = NULL) :
117     ShenandoahMarkRefsSuperClosure(q, rp, old) {};
118 
119   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
120   virtual void do_oop(oop* p)       { do_oop_work(p); }
121   virtual bool do_metadata()        { return false; }
122 };
123 
124 template <GenerationMode GENERATION>
125 class ShenandoahMarkRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
126 private:
127   template <class T>
128   inline void do_oop_work(T* p)     { work<T, GENERATION>(p); }
129 
130 public:
131   ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old = NULL) :
132     ShenandoahMarkRefsSuperClosure(q, rp, old) {};
133 
134   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
135   virtual void do_oop(oop* p)       { do_oop_work(p); }
136   virtual bool do_metadata()        { return true; }
137 };
138 
139 class ShenandoahUpdateRefsSuperClosure : public BasicOopIterateClosure {
140 protected:
141   ShenandoahHeap* _heap;
142 
143 public:
144   ShenandoahUpdateRefsSuperClosure() :  _heap(ShenandoahHeap::heap()) {}
145 };
146 
147 class ShenandoahSTWUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
148 private:
149   template<class T>
150   inline void work(T* p);
151 
152 public:
153   ShenandoahSTWUpdateRefsClosure() : ShenandoahUpdateRefsSuperClosure() {
154     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must only be used at safepoints");
155   }
156 
157   virtual void do_oop(narrowOop* p) { work(p); }
158   virtual void do_oop(oop* p)       { work(p); }
159 };
160 
161 class ShenandoahConcUpdateRefsClosure : public ShenandoahUpdateRefsSuperClosure {
162 private:
163   template<class T>
164   inline void work(T* p);
165 
166 public:
167   ShenandoahConcUpdateRefsClosure() : ShenandoahUpdateRefsSuperClosure() {}
168 
169   virtual void do_oop(narrowOop* p) { work(p); }
170   virtual void do_oop(oop* p)       { work(p); }
171 };
172 
173 class ShenandoahVerifyRemSetClosure : public BasicOopIterateClosure {
174   protected:
175   bool _init_mark;
176   ShenandoahHeap* _heap;
177   RememberedScanner* _scanner;
178 
179   public:
180 // Argument distinguishes between initial mark or start of update refs verification.
181   ShenandoahVerifyRemSetClosure(bool init_mark) :
182       _init_mark(init_mark),
183       _heap(ShenandoahHeap::heap()),
184       _scanner(_heap->card_scan()) {  }
185   template<class T>
186   inline void work(T* p);
187 
188   virtual void do_oop(narrowOop* p) { work(p); }
189   virtual void do_oop(oop* p) { work(p); }
190 };
191 
192 class ShenandoahSetRememberedCardsToDirtyClosure : public BasicOopIterateClosure {
193 
194 protected:
195   ShenandoahHeap* _heap;
196   RememberedScanner* _scanner;
197 
198 public:
199 
200   ShenandoahSetRememberedCardsToDirtyClosure() :
201       _heap(ShenandoahHeap::heap()),
202       _scanner(_heap->card_scan()) {  }
203 
204   template<class T>
205   inline void work(T* p);
206 
207   virtual void do_oop(narrowOop* p) { work(p); }
208   virtual void do_oop(oop* p) { work(p); }
209 };
210 
211 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP