< prev index next >

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

Print this page
rev 52753 : [backport] 8221435: Shenandoah should not mark through weak roots
Reviewed-by: rkennke, shade
rev 52754 : [backport] 8221629: Shenandoah: Cleanup class unloading logic
Reviewed-by: rkennke


  59 
  60 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  61   delete _process_strong_tasks;
  62   if (ShenandoahStringDedup::is_enabled()) {
  63     StringDedup::gc_epilogue();
  64   }
  65 
  66   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
  67 }
  68 
  69 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
  70   CLDToOopClosure clds(oops);
  71   CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
  72 
  73   CodeCache::blobs_do(&blobs);
  74   ClassLoaderDataGraph::cld_do(&clds);
  75   Universe::oops_do(oops);
  76   Management::oops_do(oops);
  77   JvmtiExport::oops_do(oops);
  78   JNIHandles::oops_do(oops);
  79   WeakProcessor::oops_do(oops);
  80   ObjectSynchronizer::oops_do(oops);
  81   SystemDictionary::oops_do(oops);
  82   StringTable::oops_do(oops);
  83 
  84   if (ShenandoahStringDedup::is_enabled()) {
  85     ShenandoahStringDedup::oops_do_slow(oops);
  86   }
  87 
  88   // Do thread roots the last. This allows verification code to find
  89   // any broken objects from those special roots first, not the accidental
  90   // dangling reference from the thread root.
  91   Threads::possibly_parallel_oops_do(false, oops, &blobs);
  92 }
  93 
  94 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
  95                                                    OopClosure* weak_oops,
  96                                                    CLDClosure* clds,
  97                                                    CLDClosure* weak_clds,
  98                                                    CodeBlobClosure* blobs,
  99                                                    ThreadClosure* thread_cl,
 100                                                    uint worker_id) {
 101 
 102   process_java_roots(oops, clds, weak_clds, blobs, thread_cl, worker_id);
 103   process_vm_roots(oops, NULL, weak_oops, worker_id);
 104 
 105   _process_strong_tasks->all_tasks_completed(n_workers());
 106 }
 107 
 108 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
 109                                                 OopClosure* weak_oops,
 110                                                 CLDClosure* clds,
 111                                                 CodeBlobClosure* blobs,
 112                                                 ThreadClosure* thread_cl,
 113                                                 uint worker_id) {
 114 
 115   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 116   process_java_roots(oops, clds, clds, blobs, thread_cl, worker_id);
 117   process_vm_roots(oops, oops, weak_oops, worker_id);
 118 
 119   if (blobs != NULL) {
 120     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
 121     _coderoots_all_iterator.possibly_parallel_blobs_do(blobs);
 122   }
 123 







 124   _process_strong_tasks->all_tasks_completed(n_workers());

 125 }
 126 
 127 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
 128 private:
 129   OopClosure* _f;
 130   CodeBlobClosure* _cf;
 131   ThreadClosure* _thread_cl;
 132 public:
 133   ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
 134     _f(f), _cf(cf), _thread_cl(thread_cl) {}
 135 
 136   void do_thread(Thread* t) {
 137     if (_thread_cl != NULL) {
 138       _thread_cl->do_thread(t);
 139     }
 140     t->oops_do(_f, _cf);
 141   }
 142 };
 143 
 144 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,


 150 {
 151   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 152   // Iterating over the CLDG and the Threads are done early to allow us to
 153   // first process the strong CLDs and nmethods and then, after a barrier,
 154   // let the thread process the weak CLDs and nmethods.
 155   {
 156     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
 157     _cld_iterator.root_cld_do(strong_clds, weak_clds);
 158   }
 159 
 160   {
 161     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
 162     bool is_par = n_workers() > 1;
 163     ResourceMark rm;
 164     ShenandoahParallelOopsDoThreadClosure cl(strong_roots, strong_code, thread_cl);
 165     Threads::possibly_parallel_threads_do(is_par, &cl);
 166   }
 167 }
 168 
 169 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
 170                                                OopClosure* weak_roots,
 171                                                OopClosure* jni_weak_roots,
 172                                                uint worker_id)
 173 {
 174   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 175   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
 176     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id);
 177     Universe::oops_do(strong_roots);
 178   }
 179 
 180   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 181     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
 182     JNIHandles::oops_do(strong_roots);
 183   }
 184   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Management_oops_do)) {
 185     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
 186     Management::oops_do(strong_roots);
 187   }
 188   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_jvmti_oops_do)) {
 189     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
 190     JvmtiExport::oops_do(strong_roots);
 191   }
 192   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
 193     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
 194     SystemDictionary::oops_do(strong_roots);
 195   }
 196   if (jni_weak_roots != NULL) {
 197     if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_weak_oops_do)) {
 198       ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id);
 199       WeakProcessor::oops_do(jni_weak_roots);
 200     }
 201   }
 202 
 203   if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
 204     ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
 205   }
 206 
 207   {
 208     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
 209     if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
 210        ObjectSynchronizer::oops_do(strong_roots);
 211     }
 212   }
 213 
 214   // All threads execute the following. A specific chunk of buckets
 215   // from the StringTable are the individual tasks.
 216   if (weak_roots != NULL) {
 217     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
 218     StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
 219   }
 220 }
 221 
 222 uint ShenandoahRootProcessor::n_workers() const {
 223   return _srs.n_threads();
 224 }
 225 
 226 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 227   _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
 228   _srs(n_workers),
 229   _phase(phase),
 230   _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator())
 231 {
 232   heap->phase_timings()->record_workers_start(_phase);
 233 }
 234 
 235 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
 236   delete _evacuation_tasks;
 237   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
 238 }




  59 
  60 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  61   delete _process_strong_tasks;
  62   if (ShenandoahStringDedup::is_enabled()) {
  63     StringDedup::gc_epilogue();
  64   }
  65 
  66   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
  67 }
  68 
  69 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
  70   CLDToOopClosure clds(oops);
  71   CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
  72 
  73   CodeCache::blobs_do(&blobs);
  74   ClassLoaderDataGraph::cld_do(&clds);
  75   Universe::oops_do(oops);
  76   Management::oops_do(oops);
  77   JvmtiExport::oops_do(oops);
  78   JNIHandles::oops_do(oops);

  79   ObjectSynchronizer::oops_do(oops);
  80   SystemDictionary::oops_do(oops);
  81   StringTable::oops_do(oops);
  82 




  83   // Do thread roots the last. This allows verification code to find
  84   // any broken objects from those special roots first, not the accidental
  85   // dangling reference from the thread root.
  86   Threads::possibly_parallel_oops_do(false, oops, &blobs);
  87 }
  88 
  89 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,

  90                                                    CLDClosure* clds,

  91                                                    CodeBlobClosure* blobs,
  92                                                    ThreadClosure* thread_cl,
  93                                                    uint worker_id) {
  94 
  95   process_java_roots(oops, clds, NULL, blobs, thread_cl, worker_id);
  96   process_vm_roots(oops, worker_id);
  97 
  98   _process_strong_tasks->all_tasks_completed(n_workers());
  99 }
 100 
 101 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,

 102                                                 CLDClosure* clds,
 103                                                 CodeBlobClosure* blobs,
 104                                                 ThreadClosure* thread_cl,
 105                                                 uint worker_id) {
 106 
 107   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 108   process_java_roots(oops, clds, clds, blobs, thread_cl, worker_id);
 109   process_vm_roots(oops, worker_id);
 110 
 111   if (blobs != NULL) {
 112     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
 113     _coderoots_all_iterator.possibly_parallel_blobs_do(blobs);
 114   }
 115 
 116   // All threads execute the following. A specific chunk of buckets
 117   // from the StringTable are the individual tasks.
 118   {
 119     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
 120     StringTable::possibly_parallel_oops_do(&_par_state_string, oops);
 121   }
 122 
 123   _process_strong_tasks->all_tasks_completed(n_workers());
 124 
 125 }
 126 
 127 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
 128 private:
 129   OopClosure* _f;
 130   CodeBlobClosure* _cf;
 131   ThreadClosure* _thread_cl;
 132 public:
 133   ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
 134     _f(f), _cf(cf), _thread_cl(thread_cl) {}
 135 
 136   void do_thread(Thread* t) {
 137     if (_thread_cl != NULL) {
 138       _thread_cl->do_thread(t);
 139     }
 140     t->oops_do(_f, _cf);
 141   }
 142 };
 143 
 144 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,


 150 {
 151   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 152   // Iterating over the CLDG and the Threads are done early to allow us to
 153   // first process the strong CLDs and nmethods and then, after a barrier,
 154   // let the thread process the weak CLDs and nmethods.
 155   {
 156     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
 157     _cld_iterator.root_cld_do(strong_clds, weak_clds);
 158   }
 159 
 160   {
 161     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
 162     bool is_par = n_workers() > 1;
 163     ResourceMark rm;
 164     ShenandoahParallelOopsDoThreadClosure cl(strong_roots, strong_code, thread_cl);
 165     Threads::possibly_parallel_threads_do(is_par, &cl);
 166   }
 167 }
 168 
 169 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
 170                                                uint worker_id) {



 171   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 172   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
 173     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id);
 174     Universe::oops_do(strong_roots);
 175   }
 176 
 177   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 178     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
 179     JNIHandles::oops_do(strong_roots);
 180   }
 181   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Management_oops_do)) {
 182     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
 183     Management::oops_do(strong_roots);
 184   }
 185   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_jvmti_oops_do)) {
 186     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
 187     JvmtiExport::oops_do(strong_roots);
 188   }
 189   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
 190     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
 191     SystemDictionary::oops_do(strong_roots);
 192   }










 193 
 194   {
 195     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
 196     if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
 197        ObjectSynchronizer::oops_do(strong_roots);
 198     }







 199   }
 200 }
 201 
 202 uint ShenandoahRootProcessor::n_workers() const {
 203   return _srs.n_threads();
 204 }
 205 
 206 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 207   _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
 208   _srs(n_workers),
 209   _phase(phase),
 210   _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator())
 211 {
 212   heap->phase_timings()->record_workers_start(_phase);
 213 }
 214 
 215 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
 216   delete _evacuation_tasks;
 217   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
 218 }


< prev index next >