1 /* 2 * Copyright (c) 2001, 2014, 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_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP 27 28 #include "memory/iterator.hpp" 29 #include "oops/markOop.hpp" 30 31 class HeapRegion; 32 class G1CollectedHeap; 33 class G1RemSet; 34 class ConcurrentMark; 35 class DirtyCardToOopClosure; 36 class CMBitMap; 37 class CMMarkStack; 38 class G1ParScanThreadState; 39 class CMTask; 40 class ReferenceProcessor; 41 42 // A class that scans oops in a given heap region (much as OopsInGenClosure 43 // scans oops in a generation.) 44 class OopsInHeapRegionClosure: public ExtendedOopClosure { 45 protected: 46 HeapRegion* _from; 47 public: 48 void set_region(HeapRegion* from) { _from = from; } 49 }; 50 51 class G1ParClosureSuper : public OopsInHeapRegionClosure { 52 protected: 53 G1CollectedHeap* _g1; 54 G1ParScanThreadState* _par_scan_state; 55 uint _worker_id; 56 public: 57 // Initializes the instance, leaving _par_scan_state uninitialized. Must be done 58 // later using the set_par_scan_thread_state() method. 59 G1ParClosureSuper(G1CollectedHeap* g1); 60 G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state); 61 bool apply_to_weak_ref_discovered_field() { return true; } 62 63 void set_par_scan_thread_state(G1ParScanThreadState* par_scan_state); 64 }; 65 66 class G1ParPushHeapRSClosure : public G1ParClosureSuper { 67 public: 68 G1ParPushHeapRSClosure(G1CollectedHeap* g1, 69 G1ParScanThreadState* par_scan_state): 70 G1ParClosureSuper(g1, par_scan_state) { } 71 72 template <class T> void do_oop_nv(T* p); 73 virtual void do_oop(oop* p) { do_oop_nv(p); } 74 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 75 }; 76 77 class G1ParScanClosure : public G1ParClosureSuper { 78 public: 79 G1ParScanClosure(G1CollectedHeap* g1, ReferenceProcessor* rp) : 80 G1ParClosureSuper(g1) { 81 assert(_ref_processor == NULL, "sanity"); 82 _ref_processor = rp; 83 } 84 85 template <class T> void do_oop_nv(T* p); 86 virtual void do_oop(oop* p) { do_oop_nv(p); } 87 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 88 }; 89 90 // Add back base class for metadata 91 class G1ParCopyHelper : public G1ParClosureSuper { 92 protected: 93 Klass* _scanned_klass; 94 ConcurrentMark* _cm; 95 96 // Mark the object if it's not already marked. This is used to mark 97 // objects pointed to by roots that are guaranteed not to move 98 // during the GC (i.e., non-CSet objects). It is MT-safe. 99 void mark_object(oop obj); 100 101 // Mark the object if it's not already marked. This is used to mark 102 // objects pointed to by roots that have been forwarded during a 103 // GC. It is MT-safe. 104 void mark_forwarded_object(oop from_obj, oop to_obj); 105 public: 106 G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state); 107 108 void set_scanned_klass(Klass* k) { _scanned_klass = k; } 109 template <class T> void do_klass_barrier(T* p, oop new_obj); 110 }; 111 112 template <G1Barrier barrier, G1Mark do_mark_object> 113 class G1ParCopyClosure : public G1ParCopyHelper { 114 private: 115 template <class T> void do_oop_work(T* p); 116 117 public: 118 G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state, 119 ReferenceProcessor* rp) : 120 G1ParCopyHelper(g1, par_scan_state) { 121 assert(_ref_processor == NULL, "sanity"); 122 } 123 124 template <class T> void do_oop_nv(T* p) { do_oop_work(p); } 125 virtual void do_oop(oop* p) { do_oop_nv(p); } 126 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 127 128 G1CollectedHeap* g1() { return _g1; }; 129 G1ParScanThreadState* pss() { return _par_scan_state; } 130 ReferenceProcessor* rp() { return _ref_processor; }; 131 }; 132 133 typedef G1ParCopyClosure<G1BarrierNone, G1MarkNone> G1ParScanExtRootClosure; 134 typedef G1ParCopyClosure<G1BarrierNone, G1MarkFromRoot> G1ParScanAndMarkExtRootClosure; 135 typedef G1ParCopyClosure<G1BarrierNone, G1MarkPromotedFromRoot> G1ParScanAndMarkWeakExtRootClosure; 136 // We use a separate closure to handle references during evacuation 137 // failure processing. 138 139 typedef G1ParCopyClosure<G1BarrierEvac, G1MarkNone> G1ParScanHeapEvacFailureClosure; 140 141 class FilterIntoCSClosure: public ExtendedOopClosure { 142 G1CollectedHeap* _g1; 143 OopClosure* _oc; 144 DirtyCardToOopClosure* _dcto_cl; 145 public: 146 FilterIntoCSClosure( DirtyCardToOopClosure* dcto_cl, 147 G1CollectedHeap* g1, 148 OopClosure* oc) : 149 _dcto_cl(dcto_cl), _g1(g1), _oc(oc) { } 150 151 template <class T> void do_oop_nv(T* p); 152 virtual void do_oop(oop* p) { do_oop_nv(p); } 153 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 154 bool apply_to_weak_ref_discovered_field() { return true; } 155 }; 156 157 class FilterOutOfRegionClosure: public ExtendedOopClosure { 158 HeapWord* _r_bottom; 159 HeapWord* _r_end; 160 OopClosure* _oc; 161 public: 162 FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc); 163 template <class T> void do_oop_nv(T* p); 164 virtual void do_oop(oop* p) { do_oop_nv(p); } 165 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 166 bool apply_to_weak_ref_discovered_field() { return true; } 167 }; 168 169 // Closure for iterating over object fields during concurrent marking 170 class G1CMOopClosure : public MetadataAwareOopClosure { 171 protected: 172 ConcurrentMark* _cm; 173 private: 174 G1CollectedHeap* _g1h; 175 CMTask* _task; 176 public: 177 G1CMOopClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, CMTask* task); 178 template <class T> void do_oop_nv(T* p); 179 virtual void do_oop( oop* p) { do_oop_nv(p); } 180 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 181 }; 182 183 // Closure to scan the root regions during concurrent marking 184 class G1RootRegionScanClosure : public MetadataAwareOopClosure { 185 private: 186 G1CollectedHeap* _g1h; 187 ConcurrentMark* _cm; 188 uint _worker_id; 189 public: 190 G1RootRegionScanClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, 191 uint worker_id) : 192 _g1h(g1h), _cm(cm), _worker_id(worker_id) { } 193 template <class T> void do_oop_nv(T* p); 194 virtual void do_oop( oop* p) { do_oop_nv(p); } 195 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 196 }; 197 198 // Closure that applies the given two closures in sequence. 199 // Used by the RSet refinement code (when updating RSets 200 // during an evacuation pause) to record cards containing 201 // pointers into the collection set. 202 203 class G1Mux2Closure : public ExtendedOopClosure { 204 OopClosure* _c1; 205 OopClosure* _c2; 206 public: 207 G1Mux2Closure(OopClosure *c1, OopClosure *c2); 208 template <class T> void do_oop_nv(T* p); 209 virtual void do_oop(oop* p) { do_oop_nv(p); } 210 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 211 }; 212 213 // A closure that returns true if it is actually applied 214 // to a reference 215 216 class G1TriggerClosure : public ExtendedOopClosure { 217 bool _triggered; 218 public: 219 G1TriggerClosure(); 220 bool triggered() const { return _triggered; } 221 template <class T> void do_oop_nv(T* p); 222 virtual void do_oop(oop* p) { do_oop_nv(p); } 223 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 224 }; 225 226 // A closure which uses a triggering closure to determine 227 // whether to apply an oop closure. 228 229 class G1InvokeIfNotTriggeredClosure: public ExtendedOopClosure { 230 G1TriggerClosure* _trigger_cl; 231 OopClosure* _oop_cl; 232 public: 233 G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc); 234 template <class T> void do_oop_nv(T* p); 235 virtual void do_oop(oop* p) { do_oop_nv(p); } 236 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 237 }; 238 239 class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure { 240 G1CollectedHeap* _g1; 241 G1RemSet* _g1_rem_set; 242 HeapRegion* _from; 243 OopsInHeapRegionClosure* _push_ref_cl; 244 bool _record_refs_into_cset; 245 uint _worker_i; 246 247 public: 248 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, 249 G1RemSet* rs, 250 OopsInHeapRegionClosure* push_ref_cl, 251 bool record_refs_into_cset, 252 uint worker_i = 0); 253 254 void set_from(HeapRegion* from) { 255 assert(from != NULL, "from region must be non-NULL"); 256 _from = from; 257 } 258 259 bool self_forwarded(oop obj) { 260 markOop m = obj->mark(); 261 bool result = (m->is_marked() && ((oop)m->decode_pointer() == obj)); 262 return result; 263 } 264 265 bool apply_to_weak_ref_discovered_field() { return true; } 266 267 template <class T> void do_oop_nv(T* p); 268 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 269 virtual void do_oop(oop* p) { do_oop_nv(p); } 270 }; 271 272 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP