src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 55082 335f474becde
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    22  */
    22  */
    23 
    23 
    24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
    24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
    25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
    25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
    26 
    26 
       
    27 #include "classfile/classLoaderDataGraph.hpp"
       
    28 #include "classfile/stringTable.hpp"
       
    29 #include "classfile/systemDictionary.hpp"
       
    30 #include "gc/shared/oopStorageParState.inline.hpp"
    27 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    28 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
    32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
    29 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
    33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
    30 #include "gc/shenandoah/shenandoahUtils.hpp"
    34 #include "gc/shenandoah/shenandoahUtils.hpp"
    31 #include "memory/resourceArea.hpp"
    35 #include "memory/resourceArea.hpp"
    32 
    36 #include "prims/resolvedMethodTable.hpp"
    33 template <typename IsAlive, typename KeepAlive>
    37 #include "runtime/safepoint.hpp"
    34 void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
    38 
    35   _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
    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(OopStorageSet::jni_weak(), ShenandoahPhaseTimings::JNIWeakRoots),
       
    75   _string_table_roots(OopStorageSet::string_table_weak(), ShenandoahPhaseTimings::StringTableRoots),
       
    76   _resolved_method_table_roots(OopStorageSet::resolved_method_table_weak(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
       
    77   _vm_roots(OopStorageSet::vm_weak(), ShenandoahPhaseTimings::VMWeakRoots) {
       
    78 }
       
    79 
       
    80 template <bool CONCURRENT>
       
    81 template <typename Closure>
       
    82 void ShenandoahWeakRoots<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
       
    83   _jni_roots.oops_do(cl, worker_id);
       
    84   _string_table_roots.oops_do(cl, worker_id);
       
    85   _resolved_method_table_roots.oops_do(cl, worker_id);
       
    86   _vm_roots.oops_do(cl, worker_id);
       
    87 }
       
    88 
       
    89 inline ShenandoahWeakRoots<false /* concurrent */>::ShenandoahWeakRoots() :
       
    90   _jni_roots(OopStorageSet::jni_weak(), ShenandoahPhaseTimings::JNIWeakRoots),
       
    91   _string_table_roots(OopStorageSet::string_table_weak(), ShenandoahPhaseTimings::StringTableRoots),
       
    92   _resolved_method_table_roots(OopStorageSet::resolved_method_table_weak(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
       
    93   _vm_roots(OopStorageSet::vm_weak(), 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(OopStorageSet::jni_global(), ShenandoahPhaseTimings::JNIRoots),
       
   113   _vm_global_roots(OopStorageSet::vm_global(), 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 
       
   141 template <bool CONCURRENT, bool SINGLE_THREADED>
       
   142 void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
       
   143   if (SINGLE_THREADED) {
       
   144     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
       
   145     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
       
   146     ClassLoaderDataGraph::always_strong_cld_do(clds);
       
   147   } else if (CONCURRENT) {
       
   148      ClassLoaderDataGraph::always_strong_cld_do(clds);
       
   149   } else {
       
   150    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
       
   151    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
       
   152    ClassLoaderDataGraph::always_strong_cld_do(clds);
       
   153   }
       
   154 }
       
   155 
       
   156 template <bool CONCURRENT, bool SINGLE_THREADED>
       
   157 void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
       
   158   if (SINGLE_THREADED) {
       
   159     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
       
   160     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
       
   161     ClassLoaderDataGraph::cld_do(clds);
       
   162   } else if (CONCURRENT) {
       
   163     ClassLoaderDataGraph::cld_do(clds);
       
   164   }  else {
       
   165     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
       
   166     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
       
   167     ClassLoaderDataGraph::cld_do(clds);
       
   168   }
    36 }
   169 }
    37 
   170 
    38 template <typename ITR>
   171 template <typename ITR>
    39 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
   172 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
    40   nmethod::oops_do_marking_prologue();
   173   nmethod::oops_do_marking_prologue();
    91 
   224 
    92 template <typename ITR>
   225 template <typename ITR>
    93 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
   226 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
    94   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
   227   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
    95          !ShenandoahHeap::heap()->unload_classes() ||
   228          !ShenandoahHeap::heap()->unload_classes() ||
    96           ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
   229           ShenandoahHeap::heap()->is_traversal_mode(),
    97           "Expect class unloading or traversal when Shenandoah cycle is running");
   230           "Expect class unloading or traversal when Shenandoah cycle is running");
    98   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
   231   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
    99   ResourceMark rm;
   232   ResourceMark rm;
   100 
   233 
   101   _serial_roots.oops_do(oops, worker_id);
   234   _serial_roots.oops_do(oops, worker_id);
   102   _cld_roots.clds_do(clds, clds, 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 
   103   _thread_roots.threads_do(&tc_cl, worker_id);
   243   _thread_roots.threads_do(&tc_cl, worker_id);
   104 
   244 
   105   // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
   245   // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
   106   // and instead do that in concurrent phase under the relevant lock. This saves init mark
   246   // and instead do that in concurrent phase under the relevant lock. This saves init mark
   107   // pause time.
   247   // pause time.
   115   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
   255   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
   116   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
   256   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
   117   ResourceMark rm;
   257   ResourceMark rm;
   118 
   258 
   119   _serial_roots.oops_do(oops, worker_id);
   259   _serial_roots.oops_do(oops, worker_id);
   120   _cld_roots.clds_do(clds, NULL, worker_id);
   260   _vm_roots.oops_do(oops, worker_id);
       
   261   _cld_roots.always_strong_cld_do(clds, worker_id);
   121   _thread_roots.threads_do(&tc_cl, worker_id);
   262   _thread_roots.threads_do(&tc_cl, worker_id);
   122 }
   263 }
   123 
   264 
   124 template <typename IsAlive, typename KeepAlive>
   265 template <typename IsAlive, typename KeepAlive>
   125 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
   266 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
   126   CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
   267   CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
   127   CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
   268   CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
   128   CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
       
   129 
   269 
   130   _serial_roots.oops_do(keep_alive, worker_id);
   270   _serial_roots.oops_do(keep_alive, worker_id);
       
   271   _vm_roots.oops_do(keep_alive, worker_id);
   131 
   272 
   132   _thread_roots.oops_do(keep_alive, NULL, worker_id);
   273   _thread_roots.oops_do(keep_alive, NULL, worker_id);
   133   _cld_roots.clds_do(&clds, weak_clds, worker_id);
   274   _cld_roots.cld_do(&clds, worker_id);
   134 
   275   _code_roots.code_blobs_do(&update_blobs, worker_id);
   135   if(_update_code_cache) {
   276 
   136     _code_roots.code_blobs_do(&update_blobs, worker_id);
   277   _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
   137   }
   278   _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
   138 
       
   139   _weak_roots.oops_do<IsAlive, KeepAlive>(is_alive, keep_alive, worker_id);
       
   140   _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
   279   _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
   141 }
   280 }
   142 
   281 
   143 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
   282 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP