34 #include "gc/shenandoah/shenandoahMarkCompact.hpp" 35 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 36 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" 37 #include "gc/shenandoah/shenandoahHeap.hpp" 38 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 39 #include "gc/shenandoah/shenandoahPartialGC.hpp" 40 #include "gc/shenandoah/shenandoahRootProcessor.hpp" 41 #include "gc/shenandoah/shenandoahTraversalGC.hpp" 42 #include "gc/shenandoah/shenandoahUtils.hpp" 43 #include "gc/shenandoah/shenandoahVerifier.hpp" 44 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" 45 #include "gc/shenandoah/vm_operations_shenandoah.hpp" 46 #include "oops/oop.inline.hpp" 47 #include "runtime/biasedLocking.hpp" 48 #include "runtime/thread.hpp" 49 #include "utilities/copy.hpp" 50 #include "utilities/growableArray.hpp" 51 #include "gc/shared/taskqueue.inline.hpp" 52 #include "gc/shared/workgroup.hpp" 53 54 class ShenandoahMarkCompactBarrierSet : public ShenandoahBarrierSet { 55 public: 56 ShenandoahMarkCompactBarrierSet(ShenandoahHeap* heap) : ShenandoahBarrierSet(heap) {} 57 58 oop read_barrier(oop src) { 59 return src; 60 } 61 62 #ifdef ASSERT 63 void verify_safe_oop(oop o) {} 64 void verify_safe_oop(narrowOop o) {} 65 #endif 66 }; 67 68 class ShenandoahClearRegionStatusClosure: public ShenandoahHeapRegionClosure { 69 private: 70 ShenandoahHeap* const _heap; 71 72 public: 73 ShenandoahClearRegionStatusClosure() : _heap(ShenandoahHeap::heap()) {} 74 75 bool heap_region_do(ShenandoahHeapRegion *r) { 76 _heap->set_next_top_at_mark_start(r->bottom(), r->top()); 77 r->clear_live_data(); 78 r->set_concurrent_iteration_safe_limit(r->top()); 79 return false; 80 } 81 }; 82 83 class ShenandoahEnsureHeapActiveClosure: public ShenandoahHeapRegionClosure { 84 private: 85 ShenandoahHeap* const _heap; 86 87 public: 169 // d. Abandon reference discovery and clear all discovered references. 170 ReferenceProcessor* rp = heap->ref_processor(); 171 rp->disable_discovery(); 172 rp->abandon_partial_discovery(); 173 rp->verify_no_references_recorded(); 174 175 { 176 ShenandoahHeapLocker lock(heap->lock()); 177 178 // f. Make sure all regions are active. This is needed because we are potentially 179 // sliding the data through them 180 ShenandoahEnsureHeapActiveClosure ecl; 181 heap->heap_region_iterate(&ecl, false, false); 182 183 // g. Clear region statuses, including collection set status 184 ShenandoahClearRegionStatusClosure cl; 185 heap->heap_region_iterate(&cl, false, false); 186 } 187 } 188 189 BarrierSet* old_bs = BarrierSet::barrier_set(); 190 ShenandoahMarkCompactBarrierSet bs(heap); 191 BarrierSet::set_bs(&bs); 192 193 { 194 if (UseTLAB) { 195 heap->make_tlabs_parsable(true); 196 } 197 198 CodeCache::gc_prologue(); 199 200 // We should save the marks of the currently locked biased monitors. 201 // The marking doesn't preserve the marks of biased objects. 202 //BiasedLocking::preserve_marks(); 203 204 heap->set_has_forwarded_objects(true); 205 206 OrderAccess::fence(); 207 208 phase1_mark_heap(); 209 210 heap->set_full_gc_move_in_progress(true); 211 212 // Setup workers for the rest 213 { 214 OrderAccess::fence(); 215 216 // Initialize worker slices 217 ShenandoahHeapRegionSet** worker_slices = NEW_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, heap->max_workers(), mtGC); 218 for (uint i = 0; i < heap->max_workers(); i++) { 219 worker_slices[i] = new ShenandoahHeapRegionSet(); 220 } 221 222 phase2_calculate_target_addresses(worker_slices); 223 224 OrderAccess::fence(); 225 226 phase3_update_references(); 227 228 phase4_compact_objects(worker_slices); 229 230 // Free worker slices 231 for (uint i = 0; i < heap->max_workers(); i++) { 232 delete worker_slices[i]; 233 } 234 FREE_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, worker_slices); 235 236 CodeCache::gc_epilogue(); 237 JvmtiExport::gc_epilogue(); 238 } 239 240 heap->set_has_forwarded_objects(false); 241 heap->set_full_gc_move_in_progress(false); 242 heap->set_full_gc_in_progress(false); 243 244 if (ShenandoahVerify) { 245 heap->verifier()->verify_after_fullgc(); 246 } 247 } 248 249 { 250 ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdumps); 251 heap->post_full_gc_dump(_gc_timer); 252 } 253 254 if (UseTLAB) { 255 ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); 256 heap->resize_all_tlabs(); 257 } 258 259 BarrierSet::set_bs(old_bs); 260 } 261 262 263 if (UseShenandoahMatrix && PrintShenandoahMatrix) { 264 LogTarget(Info, gc) lt; 265 LogStream ls(lt); 266 heap->connection_matrix()->print_on(&ls); 267 } 268 } 269 270 void ShenandoahMarkCompact::phase1_mark_heap() { 271 GCTraceTime(Info, gc, phases) time("Phase 1: Mark live objects", _gc_timer); 272 ShenandoahGCPhase mark_phase(ShenandoahPhaseTimings::full_gc_mark); 273 274 ShenandoahHeap* heap = ShenandoahHeap::heap(); 275 276 ShenandoahConcurrentMark* cm = heap->concurrentMark(); 277 278 // Do not trust heuristics, because this can be our last resort collection. 279 // Only ignore processing references and class unloading if explicitly disabled. | 34 #include "gc/shenandoah/shenandoahMarkCompact.hpp" 35 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 36 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" 37 #include "gc/shenandoah/shenandoahHeap.hpp" 38 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 39 #include "gc/shenandoah/shenandoahPartialGC.hpp" 40 #include "gc/shenandoah/shenandoahRootProcessor.hpp" 41 #include "gc/shenandoah/shenandoahTraversalGC.hpp" 42 #include "gc/shenandoah/shenandoahUtils.hpp" 43 #include "gc/shenandoah/shenandoahVerifier.hpp" 44 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" 45 #include "gc/shenandoah/vm_operations_shenandoah.hpp" 46 #include "oops/oop.inline.hpp" 47 #include "runtime/biasedLocking.hpp" 48 #include "runtime/thread.hpp" 49 #include "utilities/copy.hpp" 50 #include "utilities/growableArray.hpp" 51 #include "gc/shared/taskqueue.inline.hpp" 52 #include "gc/shared/workgroup.hpp" 53 54 class ShenandoahClearRegionStatusClosure: public ShenandoahHeapRegionClosure { 55 private: 56 ShenandoahHeap* const _heap; 57 58 public: 59 ShenandoahClearRegionStatusClosure() : _heap(ShenandoahHeap::heap()) {} 60 61 bool heap_region_do(ShenandoahHeapRegion *r) { 62 _heap->set_next_top_at_mark_start(r->bottom(), r->top()); 63 r->clear_live_data(); 64 r->set_concurrent_iteration_safe_limit(r->top()); 65 return false; 66 } 67 }; 68 69 class ShenandoahEnsureHeapActiveClosure: public ShenandoahHeapRegionClosure { 70 private: 71 ShenandoahHeap* const _heap; 72 73 public: 155 // d. Abandon reference discovery and clear all discovered references. 156 ReferenceProcessor* rp = heap->ref_processor(); 157 rp->disable_discovery(); 158 rp->abandon_partial_discovery(); 159 rp->verify_no_references_recorded(); 160 161 { 162 ShenandoahHeapLocker lock(heap->lock()); 163 164 // f. Make sure all regions are active. This is needed because we are potentially 165 // sliding the data through them 166 ShenandoahEnsureHeapActiveClosure ecl; 167 heap->heap_region_iterate(&ecl, false, false); 168 169 // g. Clear region statuses, including collection set status 170 ShenandoahClearRegionStatusClosure cl; 171 heap->heap_region_iterate(&cl, false, false); 172 } 173 } 174 175 { 176 if (UseTLAB) { 177 heap->make_tlabs_parsable(true); 178 } 179 180 CodeCache::gc_prologue(); 181 182 // TODO: We don't necessarily need to update refs. We might want to clean 183 // up managing has_forwarded_objects when diving into degen/full-gc. 184 heap->set_has_forwarded_objects(true); 185 186 OrderAccess::fence(); 187 188 phase1_mark_heap(); 189 190 // Prevent read-barrier from kicking in while adjusting pointers in phase3. 191 heap->set_has_forwarded_objects(false); 192 193 heap->set_full_gc_move_in_progress(true); 194 195 // Setup workers for the rest 196 { 197 OrderAccess::fence(); 198 199 // Initialize worker slices 200 ShenandoahHeapRegionSet** worker_slices = NEW_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, heap->max_workers(), mtGC); 201 for (uint i = 0; i < heap->max_workers(); i++) { 202 worker_slices[i] = new ShenandoahHeapRegionSet(); 203 } 204 205 phase2_calculate_target_addresses(worker_slices); 206 207 OrderAccess::fence(); 208 209 phase3_update_references(); 210 211 phase4_compact_objects(worker_slices); 212 213 // Free worker slices 214 for (uint i = 0; i < heap->max_workers(); i++) { 215 delete worker_slices[i]; 216 } 217 FREE_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, worker_slices); 218 219 CodeCache::gc_epilogue(); 220 JvmtiExport::gc_epilogue(); 221 } 222 223 heap->set_full_gc_move_in_progress(false); 224 heap->set_full_gc_in_progress(false); 225 226 if (ShenandoahVerify) { 227 heap->verifier()->verify_after_fullgc(); 228 } 229 } 230 231 { 232 ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_heapdumps); 233 heap->post_full_gc_dump(_gc_timer); 234 } 235 236 if (UseTLAB) { 237 ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); 238 heap->resize_all_tlabs(); 239 } 240 } 241 242 243 if (UseShenandoahMatrix && PrintShenandoahMatrix) { 244 LogTarget(Info, gc) lt; 245 LogStream ls(lt); 246 heap->connection_matrix()->print_on(&ls); 247 } 248 } 249 250 void ShenandoahMarkCompact::phase1_mark_heap() { 251 GCTraceTime(Info, gc, phases) time("Phase 1: Mark live objects", _gc_timer); 252 ShenandoahGCPhase mark_phase(ShenandoahPhaseTimings::full_gc_mark); 253 254 ShenandoahHeap* heap = ShenandoahHeap::heap(); 255 256 ShenandoahConcurrentMark* cm = heap->concurrentMark(); 257 258 // Do not trust heuristics, because this can be our last resort collection. 259 // Only ignore processing references and class unloading if explicitly disabled. |