< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp

Print this page
rev 55920 : 8229206: Shenandoah: ShenandoahWeakRoot::oops_do() uses wrong timing phase
rev 55921 : 8229213: Shenandoah: Allow VM global oop storage to be processed concurrently


  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
  25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
  26 
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/oopStorageParState.inline.hpp"
  31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
  32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  34 #include "gc/shenandoah/shenandoahUtils.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "prims/resolvedMethodTable.hpp"
  37 #include "runtime/safepoint.hpp"
  38 
  39 template <bool CONCURRENT>
  40 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
  41   _itr(storage), _phase(phase) {
  42 }
  43 
  44 template <bool CONCURRENT>
  45 template <typename Closure>
  46 inline void ShenandoahWeakRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
  47   if (CONCURRENT) {
  48     _itr.oops_do(cl);
  49   } else {
  50     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
  51     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
  52     _itr.oops_do(cl);
  53   }
  54 }
  55 





  56 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
  57   _itr(storage), _phase(phase) {
  58 }
  59 
  60 template <typename IsAliveClosure, typename KeepAliveClosure>
  61 void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
  62   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
  63   ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
  64   _itr.weak_oops_do(is_alive, keep_alive);
  65 }
  66 
  67 template <bool CONCURRENT>
  68 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
  69   _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
  70   _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
  71   _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
  72   _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
  73 }
  74 
  75 template <bool CONCURRENT>


  86   _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
  87   _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
  88   _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
  89 }
  90 
  91 template <typename IsAliveClosure, typename KeepAliveClosure>
  92 void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
  93   _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
  94   _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
  95   _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
  96   _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
  97 }
  98 
  99 template <typename Closure>
 100 void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
 101   AlwaysTrueClosure always_true;
 102   weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
 103 }
 104 
 105 template <bool CONCURRENT>
 106 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
 107   _itr(JNIHandles::global_handles()) {

 108 }
 109 
 110 template <bool CONCURRENT>
 111 template <typename T>
 112 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
 113   if (CONCURRENT) {
 114     _itr.oops_do(cl);
 115   } else {
 116     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
 117     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
 118     _itr.oops_do(cl);
 119   }
 120 }
 121 
 122 template <bool CONCURRENT, bool SINGLE_THREADED>
 123 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
 124   if (!SINGLE_THREADED) {
 125     ClassLoaderDataGraph::clear_claimed_marks();
 126   }
 127   if (CONCURRENT) {
 128     ClassLoaderDataGraph_lock->lock();
 129   }
 130 }
 131 
 132 template <bool CONCURRENT, bool SINGLE_THREADED>
 133 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
 134   if (CONCURRENT) {
 135     ClassLoaderDataGraph_lock->unlock();
 136   }
 137 }
 138 
 139 


 214   roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 215 }
 216 
 217 template <typename ITR>
 218 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
 219   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 220   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 221   strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 222 }
 223 
 224 template <typename ITR>
 225 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
 226   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
 227          !ShenandoahHeap::heap()->unload_classes() ||
 228           ShenandoahHeap::heap()->is_traversal_mode(),
 229           "Expect class unloading or traversal when Shenandoah cycle is running");
 230   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 231   ResourceMark rm;
 232 
 233   _serial_roots.oops_do(oops, worker_id);
 234   _jni_roots.oops_do(oops, worker_id);
 235 
 236   if (clds != NULL) {
 237     _cld_roots.cld_do(clds, worker_id);
 238   } else {
 239     assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC");
 240   }
 241 
 242   _thread_roots.threads_do(&tc_cl, worker_id);
 243 
 244   // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
 245   // and instead do that in concurrent phase under the relevant lock. This saves init mark
 246   // pause time.
 247   if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
 248     _code_roots.code_blobs_do(code, worker_id);
 249   }
 250 }
 251 
 252 template <typename ITR>
 253 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
 254   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
 255   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 256   ResourceMark rm;
 257 
 258   _serial_roots.oops_do(oops, worker_id);
 259   _jni_roots.oops_do(oops, worker_id);
 260   _cld_roots.always_strong_cld_do(clds, worker_id);
 261   _thread_roots.threads_do(&tc_cl, worker_id);
 262 }
 263 
 264 template <typename IsAlive, typename KeepAlive>
 265 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
 266   CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
 267   CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
 268 
 269   _serial_roots.oops_do(keep_alive, worker_id);
 270   _jni_roots.oops_do(keep_alive, worker_id);
 271 
 272   _thread_roots.oops_do(keep_alive, NULL, worker_id);
 273   _cld_roots.cld_do(&clds, worker_id);
 274 
 275   if(_update_code_cache) {
 276     _code_roots.code_blobs_do(&update_blobs, worker_id);
 277   }
 278 
 279   _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 280   _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 281   _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
 282 }
 283 
 284 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP


  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
  25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
  26 
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/oopStorageParState.inline.hpp"
  31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
  32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  34 #include "gc/shenandoah/shenandoahUtils.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "prims/resolvedMethodTable.hpp"
  37 #include "runtime/safepoint.hpp"
  38 
  39 template <bool CONCURRENT>
  40 inline ShenandoahVMRoot<CONCURRENT>::ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
  41   _itr(storage), _phase(phase) {
  42 }
  43 
  44 template <bool CONCURRENT>
  45 template <typename Closure>
  46 inline void ShenandoahVMRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
  47   if (CONCURRENT) {
  48     _itr.oops_do(cl);
  49   } else {
  50     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
  51     ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
  52     _itr.oops_do(cl);
  53   }
  54 }
  55 
  56 template <bool CONCURRENT>
  57 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
  58   ShenandoahVMRoot<CONCURRENT>(storage, phase) {
  59 }
  60 
  61 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
  62   _itr(storage), _phase(phase) {
  63 }
  64 
  65 template <typename IsAliveClosure, typename KeepAliveClosure>
  66 void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
  67   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
  68   ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
  69   _itr.weak_oops_do(is_alive, keep_alive);
  70 }
  71 
  72 template <bool CONCURRENT>
  73 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
  74   _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
  75   _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
  76   _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
  77   _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
  78 }
  79 
  80 template <bool CONCURRENT>


  91   _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
  92   _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
  93   _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
  94 }
  95 
  96 template <typename IsAliveClosure, typename KeepAliveClosure>
  97 void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
  98   _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
  99   _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 100   _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 101   _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 102 }
 103 
 104 template <typename Closure>
 105 void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
 106   AlwaysTrueClosure always_true;
 107   weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
 108 }
 109 
 110 template <bool CONCURRENT>
 111 ShenandoahVMRoots<CONCURRENT>::ShenandoahVMRoots() :
 112   _jni_handle_roots(JNIHandles::global_handles(), ShenandoahPhaseTimings::JNIRoots),
 113   _vm_global_roots(SystemDictionary::vm_global_oop_storage(), ShenandoahPhaseTimings::VMGlobalRoots) {
 114 }
 115 
 116 template <bool CONCURRENT>
 117 template <typename T>
 118 void ShenandoahVMRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
 119   _jni_handle_roots.oops_do(cl, worker_id);
 120   _vm_global_roots.oops_do(cl, worker_id);





 121 }
 122 
 123 template <bool CONCURRENT, bool SINGLE_THREADED>
 124 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
 125   if (!SINGLE_THREADED) {
 126     ClassLoaderDataGraph::clear_claimed_marks();
 127   }
 128   if (CONCURRENT) {
 129     ClassLoaderDataGraph_lock->lock();
 130   }
 131 }
 132 
 133 template <bool CONCURRENT, bool SINGLE_THREADED>
 134 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
 135   if (CONCURRENT) {
 136     ClassLoaderDataGraph_lock->unlock();
 137   }
 138 }
 139 
 140 


 215   roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 216 }
 217 
 218 template <typename ITR>
 219 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
 220   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 221   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 222   strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 223 }
 224 
 225 template <typename ITR>
 226 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
 227   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
 228          !ShenandoahHeap::heap()->unload_classes() ||
 229           ShenandoahHeap::heap()->is_traversal_mode(),
 230           "Expect class unloading or traversal when Shenandoah cycle is running");
 231   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 232   ResourceMark rm;
 233 
 234   _serial_roots.oops_do(oops, worker_id);
 235   _vm_roots.oops_do(oops, worker_id);
 236 
 237   if (clds != NULL) {
 238     _cld_roots.cld_do(clds, worker_id);
 239   } else {
 240     assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC");
 241   }
 242 
 243   _thread_roots.threads_do(&tc_cl, worker_id);
 244 
 245   // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
 246   // and instead do that in concurrent phase under the relevant lock. This saves init mark
 247   // pause time.
 248   if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
 249     _code_roots.code_blobs_do(code, worker_id);
 250   }
 251 }
 252 
 253 template <typename ITR>
 254 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
 255   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
 256   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 257   ResourceMark rm;
 258 
 259   _serial_roots.oops_do(oops, worker_id);
 260   _vm_roots.oops_do(oops, worker_id);
 261   _cld_roots.always_strong_cld_do(clds, worker_id);
 262   _thread_roots.threads_do(&tc_cl, worker_id);
 263 }
 264 
 265 template <typename IsAlive, typename KeepAlive>
 266 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
 267   CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
 268   CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
 269 
 270   _serial_roots.oops_do(keep_alive, worker_id);
 271   _vm_roots.oops_do(keep_alive, worker_id);
 272 
 273   _thread_roots.oops_do(keep_alive, NULL, worker_id);
 274   _cld_roots.cld_do(&clds, worker_id);
 275 
 276   if(_update_code_cache) {
 277     _code_roots.code_blobs_do(&update_blobs, worker_id);
 278   }
 279 
 280   _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 281   _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
 282   _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
 283 }
 284 
 285 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
< prev index next >