1 /*
  2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. 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_VM_GC_G1_G1OOPCLOSURES_HPP
 26 #define SHARE_VM_GC_G1_G1OOPCLOSURES_HPP
 27 
 28 #include "gc/g1/g1InCSetState.hpp"
 29 #include "memory/iterator.hpp"
 30 #include "oops/markOop.hpp"
 31 
 32 class HeapRegion;
 33 class G1CollectedHeap;
 34 class G1RemSet;
 35 class G1ConcurrentMark;
 36 class DirtyCardToOopClosure;
 37 class G1CMBitMap;
 38 class G1ParScanThreadState;
 39 class G1CMTask;
 40 class ReferenceProcessor;
 41 
 42 class G1ScanClosureBase : public BasicOopIterateClosure {
 43 protected:
 44   G1CollectedHeap* _g1h;
 45   G1ParScanThreadState* _par_scan_state;
 46   HeapRegion* _from;
 47 
 48   G1ScanClosureBase(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state);
 49   ~G1ScanClosureBase() { }
 50 
 51   template <class T>
 52   inline void prefetch_and_push(T* p, oop const obj);
 53 
 54   template <class T>
 55   inline void handle_non_cset_obj_common(InCSetState const state, T* p, oop const obj);
 56 public:
 57   // This closure needs special handling for InstanceRefKlass.
 58   virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
 59   void set_region(HeapRegion* from) { _from = from; }
 60 
 61   inline void trim_queue_partially();
 62 };
 63 
 64 // Used during the Update RS phase to refine remaining cards in the DCQ during garbage collection.
 65 class G1ScanObjsDuringUpdateRSClosure: public G1ScanClosureBase {
 66   uint _worker_i;
 67 
 68 public:
 69   G1ScanObjsDuringUpdateRSClosure(G1CollectedHeap* g1h,
 70                                   G1ParScanThreadState* pss,
 71                                   uint worker_i) :
 72     G1ScanClosureBase(g1h, pss), _worker_i(worker_i) { }
 73 
 74   template <class T> void do_oop_work(T* p);
 75   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 76   virtual void do_oop(oop* p) { do_oop_work(p); }
 77 };
 78 
 79 // Used during the Scan RS phase to scan cards from the remembered set during garbage collection.
 80 class G1ScanObjsDuringScanRSClosure : public G1ScanClosureBase {
 81 public:
 82   G1ScanObjsDuringScanRSClosure(G1CollectedHeap* g1h,
 83                                 G1ParScanThreadState* par_scan_state):
 84     G1ScanClosureBase(g1h, par_scan_state) { }
 85 
 86   template <class T> void do_oop_work(T* p);
 87   virtual void do_oop(oop* p)          { do_oop_work(p); }
 88   virtual void do_oop(narrowOop* p)    { do_oop_work(p); }
 89 };
 90 
 91 // This closure is applied to the fields of the objects that have just been copied during evacuation.
 92 class G1ScanEvacuatedObjClosure : public G1ScanClosureBase {
 93 public:
 94   G1ScanEvacuatedObjClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state) :
 95     G1ScanClosureBase(g1h, par_scan_state) { }
 96 
 97   template <class T> void do_oop_work(T* p);
 98   virtual void do_oop(oop* p)          { do_oop_work(p); }
 99   virtual void do_oop(narrowOop* p)    { do_oop_work(p); }
100 
101   void set_ref_discoverer(ReferenceDiscoverer* rd) {
102     set_ref_discoverer_internal(rd);
103   }
104 };
105 
106 // Add back base class for metadata
107 class G1ParCopyHelper : public OopClosure {
108 protected:
109   G1CollectedHeap* _g1h;
110   G1ParScanThreadState* _par_scan_state;
111   uint _worker_id;              // Cache value from par_scan_state.
112   ClassLoaderData* _scanned_cld;
113   G1ConcurrentMark* _cm;
114 
115   // Mark the object if it's not already marked. This is used to mark
116   // objects pointed to by roots that are guaranteed not to move
117   // during the GC (i.e., non-CSet objects). It is MT-safe.
118   inline void mark_object(oop obj);
119 
120   // Mark the object if it's not already marked. This is used to mark
121   // objects pointed to by roots that have been forwarded during a
122   // GC. It is MT-safe.
123   inline void mark_forwarded_object(oop from_obj, oop to_obj);
124 
125   G1ParCopyHelper(G1CollectedHeap* g1h,  G1ParScanThreadState* par_scan_state);
126   ~G1ParCopyHelper() { }
127 
128  public:
129   void set_scanned_cld(ClassLoaderData* cld) { _scanned_cld = cld; }
130   inline void do_cld_barrier(oop new_obj);
131 
132   inline void trim_queue_partially();
133 };
134 
135 enum G1Barrier {
136   G1BarrierNone,
137   G1BarrierCLD
138 };
139 
140 enum G1Mark {
141   G1MarkNone,
142   G1MarkFromRoot,
143   G1MarkPromotedFromRoot
144 };
145 
146 template <G1Barrier barrier, G1Mark do_mark_object>
147 class G1ParCopyClosure : public G1ParCopyHelper {
148 public:
149   G1ParCopyClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state) :
150       G1ParCopyHelper(g1h, par_scan_state) { }
151 
152   template <class T> void do_oop_work(T* p);
153   virtual void do_oop(oop* p)       { do_oop_work(p); }
154   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
155 };
156 
157 class G1CLDScanClosure : public CLDClosure {
158   G1ParCopyHelper* _closure;
159   bool             _process_only_dirty;
160   bool             _must_claim;
161   int              _count;
162 public:
163   G1CLDScanClosure(G1ParCopyHelper* closure,
164                    bool process_only_dirty, bool must_claim)
165   : _closure(closure), _process_only_dirty(process_only_dirty), _must_claim(must_claim), _count(0) {}
166   void do_cld(ClassLoaderData* cld);
167 };
168 
169 // Closure for iterating over object fields during concurrent marking
170 class G1CMOopClosure : public MetadataVisitingOopIterateClosure {
171   G1CollectedHeap*   _g1h;
172   G1CMTask*          _task;
173 public:
174   G1CMOopClosure(G1CollectedHeap* g1h,G1CMTask* task);
175   template <class T> void do_oop_work(T* p);
176   virtual void do_oop(      oop* p) { do_oop_work(p); }
177   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
178 };
179 
180 // Closure to scan the root regions during concurrent marking
181 class G1RootRegionScanClosure : public MetadataVisitingOopIterateClosure {
182 private:
183   G1CollectedHeap* _g1h;
184   G1ConcurrentMark* _cm;
185   uint _worker_id;
186 public:
187   G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm, uint worker_id) :
188     _g1h(g1h), _cm(cm), _worker_id(worker_id) { }
189   template <class T> void do_oop_work(T* p);
190   virtual void do_oop(      oop* p) { do_oop_work(p); }
191   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
192 };
193 
194 class G1ConcurrentRefineOopClosure: public BasicOopIterateClosure {
195   G1CollectedHeap* _g1h;
196   uint _worker_i;
197 
198 public:
199   G1ConcurrentRefineOopClosure(G1CollectedHeap* g1h, uint worker_i) :
200     _g1h(g1h),
201     _worker_i(worker_i) {
202   }
203 
204   // This closure needs special handling for InstanceRefKlass.
205   virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
206 
207   template <class T> void do_oop_work(T* p);
208   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
209   virtual void do_oop(oop* p)       { do_oop_work(p); }
210 };
211 
212 class G1RebuildRemSetClosure : public BasicOopIterateClosure {
213   G1CollectedHeap* _g1h;
214   uint _worker_id;
215 public:
216   G1RebuildRemSetClosure(G1CollectedHeap* g1h, uint worker_id) : _g1h(g1h), _worker_id(worker_id) {
217   }
218 
219   template <class T> void do_oop_work(T* p);
220   virtual void do_oop(oop* p)       { do_oop_work(p); }
221   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
222   // This closure needs special handling for InstanceRefKlass.
223   virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
224 };
225 
226 #endif // SHARE_VM_GC_G1_G1OOPCLOSURES_HPP