< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp

Print this page
rev 57866 : 8246100: Shenandoah: walk roots in more efficient order
Reviewed-by: zgu
rev 57867 : 8246097: Shenandoah: limit parallelism in CLDG root handling
Reviewed-by: zgu


 144 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
 145   if (ShenandoahStringDedup::is_enabled()) {
 146     ShenandoahStringDedup::parallel_oops_do(_phase, is_alive, keep_alive, worker_id);
 147   }
 148 }
 149 
 150 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
 151   _heap(ShenandoahHeap::heap()),
 152   _phase(phase),
 153   _worker_phase(phase) {
 154   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 155 }
 156 
 157 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
 158                                                  ShenandoahPhaseTimings::Phase phase,
 159                                                  bool stw_roots_processing,
 160                                                  bool stw_class_unloading) :
 161   ShenandoahRootProcessor(phase),
 162   _serial_roots(phase),
 163   _vm_roots(phase),
 164   _cld_roots(phase),
 165   _thread_roots(phase, n_workers > 1),
 166   _serial_weak_roots(phase),
 167   _weak_roots(phase),
 168   _dedup_roots(phase),
 169   _code_roots(phase),
 170   _stw_roots_processing(stw_roots_processing),
 171   _stw_class_unloading(stw_class_unloading) {
 172 }
 173 
 174 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
 175   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
 176   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 177   CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 178                                    static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 179                                    static_cast<CodeBlobToOopClosure*>(&blobsCl);
 180   AlwaysTrueClosure always_true;
 181 
 182   // Process serial-claiming roots first
 183   _serial_roots.oops_do(oops, worker_id);
 184   _serial_weak_roots.weak_oops_do(oops, worker_id);
 185 
 186   // Process light-weight/limited parallel roots then
 187   if (_stw_roots_processing) {
 188     _vm_roots.oops_do<OopClosure>(oops, worker_id);
 189     _weak_roots.oops_do<OopClosure>(oops, worker_id);
 190   }
 191   _dedup_roots.oops_do(&always_true, oops, worker_id);
 192 
 193   // Process heavy-weight/fully parallel roots the last
 194   if (_stw_class_unloading) {
 195     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 196     _cld_roots.cld_do(&clds, worker_id);




 197     _code_roots.code_blobs_do(codes_cl, worker_id);
 198     _thread_roots.oops_do(oops, NULL, worker_id);
 199   } else {
 200     _thread_roots.oops_do(oops, codes_cl, worker_id);
 201   }
 202 }
 203 
 204 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 205   ShenandoahRootProcessor(phase),
 206   _serial_roots(phase),
 207   _vm_roots(phase),
 208   _cld_roots(phase),
 209   _thread_roots(phase, n_workers > 1),
 210   _serial_weak_roots(phase),
 211   _weak_roots(phase),
 212   _dedup_roots(phase),
 213   _code_roots(phase) {
 214 }
 215 
 216 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 217   ShenandoahRootProcessor(phase),
 218   _serial_roots(phase),
 219   _vm_roots(phase),
 220   _cld_roots(phase),
 221   _thread_roots(phase, n_workers > 1),
 222   _serial_weak_roots(phase),
 223   _weak_roots(phase),
 224   _dedup_roots(phase),
 225   _code_roots(phase) {
 226   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 227 }
 228 
 229 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
 230   CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
 231   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 232   CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 233                                               static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 234                                               static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
 235   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
 236   AlwaysTrueClosure always_true;
 237 
 238   // Process serial-claiming roots first
 239   _serial_roots.oops_do(oops, worker_id);
 240   _serial_weak_roots.weak_oops_do(oops, worker_id);
 241 
 242   // Process light-weight/limited parallel roots then
 243   _vm_roots.oops_do(oops, worker_id);
 244   _weak_roots.oops_do<OopClosure>(oops, worker_id);
 245   _dedup_roots.oops_do(&always_true, oops, worker_id);

 246 
 247   // Process heavy-weight/fully parallel roots the last
 248   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
 249   _code_roots.code_blobs_do(adjust_code_closure, worker_id);
 250   _thread_roots.oops_do(oops, NULL, worker_id);
 251 }
 252 
 253 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
 254    ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
 255    _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 256    _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
 257    _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 258    _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 259    _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 260    _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 261    _dedup_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 262    _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
 263  }
 264 
 265  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
 266    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
 267    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
 268    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
 269    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
 270    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
 271    AlwaysTrueClosure always_true;
 272 
 273    ResourceMark rm;
 274 
 275    // Process serial-claiming roots first
 276    _serial_roots.oops_do(oops, 0);
 277    _serial_weak_roots.weak_oops_do(oops, 0);
 278 
 279    // Process light-weight/limited parallel roots then
 280    _vm_roots.oops_do(oops, 0);
 281    _weak_roots.oops_do<OopClosure>(oops, 0);
 282    _dedup_roots.oops_do(&always_true, oops, 0);

 283 
 284    // Process heavy-weight/fully parallel roots the last
 285    _cld_roots.cld_do(&clds, 0);
 286    _code_roots.code_blobs_do(&code, 0);
 287    _thread_roots.threads_do(&tc_cl, 0);
 288  }


 144 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
 145   if (ShenandoahStringDedup::is_enabled()) {
 146     ShenandoahStringDedup::parallel_oops_do(_phase, is_alive, keep_alive, worker_id);
 147   }
 148 }
 149 
 150 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
 151   _heap(ShenandoahHeap::heap()),
 152   _phase(phase),
 153   _worker_phase(phase) {
 154   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 155 }
 156 
 157 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
 158                                                  ShenandoahPhaseTimings::Phase phase,
 159                                                  bool stw_roots_processing,
 160                                                  bool stw_class_unloading) :
 161   ShenandoahRootProcessor(phase),
 162   _serial_roots(phase),
 163   _vm_roots(phase),
 164   _cld_roots(phase, n_workers),
 165   _thread_roots(phase, n_workers > 1),
 166   _serial_weak_roots(phase),
 167   _weak_roots(phase),
 168   _dedup_roots(phase),
 169   _code_roots(phase),
 170   _stw_roots_processing(stw_roots_processing),
 171   _stw_class_unloading(stw_class_unloading) {
 172 }
 173 
 174 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
 175   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
 176   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 177   CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 178                                    static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 179                                    static_cast<CodeBlobToOopClosure*>(&blobsCl);
 180   AlwaysTrueClosure always_true;
 181 
 182   // Process serial-claiming roots first
 183   _serial_roots.oops_do(oops, worker_id);
 184   _serial_weak_roots.weak_oops_do(oops, worker_id);
 185 
 186   // Process light-weight/limited parallel roots then
 187   if (_stw_roots_processing) {
 188     _vm_roots.oops_do<OopClosure>(oops, worker_id);
 189     _weak_roots.oops_do<OopClosure>(oops, worker_id);
 190   }
 191   _dedup_roots.oops_do(&always_true, oops, worker_id);


 192   if (_stw_class_unloading) {
 193     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 194     _cld_roots.cld_do(&clds, worker_id);
 195   }
 196 
 197   // Process heavy-weight/fully parallel roots the last
 198   if (_stw_class_unloading) {
 199     _code_roots.code_blobs_do(codes_cl, worker_id);
 200     _thread_roots.oops_do(oops, NULL, worker_id);
 201   } else {
 202     _thread_roots.oops_do(oops, codes_cl, worker_id);
 203   }
 204 }
 205 
 206 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 207   ShenandoahRootProcessor(phase),
 208   _serial_roots(phase),
 209   _vm_roots(phase),
 210   _cld_roots(phase, n_workers),
 211   _thread_roots(phase, n_workers > 1),
 212   _serial_weak_roots(phase),
 213   _weak_roots(phase),
 214   _dedup_roots(phase),
 215   _code_roots(phase) {
 216 }
 217 
 218 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 219   ShenandoahRootProcessor(phase),
 220   _serial_roots(phase),
 221   _vm_roots(phase),
 222   _cld_roots(phase, n_workers),
 223   _thread_roots(phase, n_workers > 1),
 224   _serial_weak_roots(phase),
 225   _weak_roots(phase),
 226   _dedup_roots(phase),
 227   _code_roots(phase) {
 228   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 229 }
 230 
 231 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
 232   CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
 233   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 234   CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 235                                               static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 236                                               static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
 237   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
 238   AlwaysTrueClosure always_true;
 239 
 240   // Process serial-claiming roots first
 241   _serial_roots.oops_do(oops, worker_id);
 242   _serial_weak_roots.weak_oops_do(oops, worker_id);
 243 
 244   // Process light-weight/limited parallel roots then
 245   _vm_roots.oops_do(oops, worker_id);
 246   _weak_roots.oops_do<OopClosure>(oops, worker_id);
 247   _dedup_roots.oops_do(&always_true, oops, worker_id);
 248   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
 249 
 250   // Process heavy-weight/fully parallel roots the last

 251   _code_roots.code_blobs_do(adjust_code_closure, worker_id);
 252   _thread_roots.oops_do(oops, NULL, worker_id);
 253 }
 254 
 255 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
 256    ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
 257    _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 258    _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
 259    _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 260    _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, 1),
 261    _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 262    _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 263    _dedup_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 264    _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
 265  }
 266 
 267  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
 268    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
 269    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
 270    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
 271    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
 272    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
 273    AlwaysTrueClosure always_true;
 274 
 275    ResourceMark rm;
 276 
 277    // Process serial-claiming roots first
 278    _serial_roots.oops_do(oops, 0);
 279    _serial_weak_roots.weak_oops_do(oops, 0);
 280 
 281    // Process light-weight/limited parallel roots then
 282    _vm_roots.oops_do(oops, 0);
 283    _weak_roots.oops_do<OopClosure>(oops, 0);
 284    _dedup_roots.oops_do(&always_true, oops, 0);
 285    _cld_roots.cld_do(&clds, 0);
 286 
 287    // Process heavy-weight/fully parallel roots the last

 288    _code_roots.code_blobs_do(&code, 0);
 289    _thread_roots.threads_do(&tc_cl, 0);
 290  }
< prev index next >