src/hotspot/share/gc/g1/g1RootProcessor.cpp
changeset 58777 18c246ad2ff9
parent 58375 a1eba2e37671
equal deleted inserted replaced
58776:ea153023d832 58777:18c246ad2ff9
    43 #include "memory/universe.hpp"
    43 #include "memory/universe.hpp"
    44 #include "runtime/mutex.hpp"
    44 #include "runtime/mutex.hpp"
    45 #include "services/management.hpp"
    45 #include "services/management.hpp"
    46 #include "utilities/macros.hpp"
    46 #include "utilities/macros.hpp"
    47 
    47 
    48 void G1RootProcessor::worker_has_discovered_all_strong_nmethods() {
       
    49   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
       
    50 
       
    51   uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
       
    52   if (new_value == n_workers()) {
       
    53     // This thread is last. Notify the others.
       
    54     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
       
    55     _lock.notify_all();
       
    56   }
       
    57 }
       
    58 
       
    59 void G1RootProcessor::wait_until_all_strong_nmethods_discovered() {
       
    60   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
       
    61 
       
    62   if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
       
    63     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
       
    64     while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
       
    65       ml.wait(0);
       
    66     }
       
    67   }
       
    68 }
       
    69 
       
    70 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
    48 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
    71     _g1h(g1h),
    49     _g1h(g1h),
    72     _process_strong_tasks(G1RP_PS_NumElements),
    50     _process_strong_tasks(G1RP_PS_NumElements),
    73     _srs(n_workers),
    51     _srs(n_workers) {}
    74     _lock(Mutex::leaf, "G1 Root Scan barrier lock", false, Mutex::_safepoint_check_never),
       
    75     _n_workers_discovered_strong_classes(0) {}
       
    76 
    52 
    77 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_id) {
    53 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_id) {
    78   G1GCPhaseTimes* phase_times = _g1h->phase_times();
    54   G1GCPhaseTimes* phase_times = _g1h->phase_times();
    79 
    55 
    80   G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_id);
    56   G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_id);
    81 
    57 
    82   G1EvacuationRootClosures* closures = pss->closures();
    58   G1EvacuationRootClosures* closures = pss->closures();
    83   process_java_roots(closures, phase_times, worker_id, closures->trace_metadata() /* notify_claimed_nmethods_done */);
    59   process_java_roots(closures, phase_times, worker_id);
    84 
    60 
    85   process_vm_roots(closures, phase_times, worker_id);
    61   process_vm_roots(closures, phase_times, worker_id);
    86 
    62 
    87   {
    63   {
    88     // Now the CM ref_processor roots.
    64     // Now the CM ref_processor roots.
    94       // until they can be processed at the end of marking.
    70       // until they can be processed at the end of marking.
    95       _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
    71       _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
    96     }
    72     }
    97   }
    73   }
    98 
    74 
    99   if (closures->trace_metadata()) {
       
   100     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongRoots, worker_id);
       
   101     // Wait to make sure all workers passed the strong nmethods phase.
       
   102     wait_until_all_strong_nmethods_discovered();
       
   103   }
       
   104 
       
   105   _process_strong_tasks.all_tasks_completed(n_workers());
    75   _process_strong_tasks.all_tasks_completed(n_workers());
   106 }
    76 }
   107 
    77 
   108 // Adaptor to pass the closures to the strong roots in the VM.
    78 // Adaptor to pass the closures to the strong roots in the VM.
   109 class StrongRootsClosures : public G1RootClosures {
    79 class StrongRootsClosures : public G1RootClosures {
   169   _process_strong_tasks.all_tasks_completed(n_workers());
   139   _process_strong_tasks.all_tasks_completed(n_workers());
   170 }
   140 }
   171 
   141 
   172 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
   142 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
   173                                          G1GCPhaseTimes* phase_times,
   143                                          G1GCPhaseTimes* phase_times,
   174                                          uint worker_id,
   144                                          uint worker_id) {
   175                                          bool notify_claimed_nmethods_done) {
       
   176   // We need to make make sure that the "strong" nmethods are processed first
   145   // We need to make make sure that the "strong" nmethods are processed first
   177   // using the strong closure. Only after that we process the weakly reachable
   146   // using the strong closure. Only after that we process the weakly reachable
   178   // nmethods.
   147   // nmethods.
   179   // We need to strictly separate the strong and weak nmethod processing because
   148   // We need to strictly separate the strong and weak nmethod processing because
   180   // any processing claims that nmethod, i.e. will not be iterated again.
   149   // any processing claims that nmethod, i.e. will not be iterated again.
   195     Threads::possibly_parallel_oops_do(is_par,
   164     Threads::possibly_parallel_oops_do(is_par,
   196                                        closures->strong_oops(),
   165                                        closures->strong_oops(),
   197                                        closures->strong_codeblobs());
   166                                        closures->strong_codeblobs());
   198   }
   167   }
   199 
   168 
   200   // This is the point where this worker thread will not find more strong nmethods.
       
   201   // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
       
   202   if (notify_claimed_nmethods_done) {
       
   203     worker_has_discovered_all_strong_nmethods();
       
   204   }
       
   205 
       
   206   {
   169   {
   207     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_id);
   170     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_id);
   208     if (_process_strong_tasks.try_claim_task(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
   171     if (_process_strong_tasks.try_claim_task(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
   209       ClassLoaderDataGraph::roots_cld_do(closures->strong_clds(), closures->weak_clds());
   172       ClassLoaderDataGraph::roots_cld_do(closures->strong_clds(), closures->weak_clds());
   210     }
   173     }