src/hotspot/share/gc/g1/g1RootProcessor.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54786 ebf733a324d4
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    42 #include "memory/allocation.inline.hpp"
    42 #include "memory/allocation.inline.hpp"
    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 #if INCLUDE_JVMCI
    47 
    48 #include "jvmci/jvmci.hpp"
    48 void G1RootProcessor::worker_has_discovered_all_strong_nmethods() {
    49 #endif
       
    50 
       
    51 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
       
    52   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
    49   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
    53 
    50 
    54   uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
    51   uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
    55   if (new_value == n_workers()) {
    52   if (new_value == n_workers()) {
    56     // This thread is last. Notify the others.
    53     // This thread is last. Notify the others.
    57     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
    54     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
    58     _lock.notify_all();
    55     _lock.notify_all();
    59   }
    56   }
    60 }
    57 }
    61 
    58 
    62 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
    59 void G1RootProcessor::wait_until_all_strong_nmethods_discovered() {
    63   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
    60   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
    64 
    61 
    65   if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
    62   if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
    66     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
    63     MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
    67     while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
    64     while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
    72 
    69 
    73 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
    70 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
    74     _g1h(g1h),
    71     _g1h(g1h),
    75     _process_strong_tasks(G1RP_PS_NumElements),
    72     _process_strong_tasks(G1RP_PS_NumElements),
    76     _srs(n_workers),
    73     _srs(n_workers),
    77     _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
    74     _lock(Mutex::leaf, "G1 Root Scan barrier lock", false, Mutex::_safepoint_check_never),
    78     _n_workers_discovered_strong_classes(0) {}
    75     _n_workers_discovered_strong_classes(0) {}
    79 
    76 
    80 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_i) {
    77 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_id) {
    81   G1GCPhaseTimes* phase_times = _g1h->phase_times();
    78   G1GCPhaseTimes* phase_times = _g1h->phase_times();
    82 
    79 
    83   G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_i);
    80   G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_id);
    84 
    81 
    85   G1EvacuationRootClosures* closures = pss->closures();
    82   G1EvacuationRootClosures* closures = pss->closures();
    86   process_java_roots(closures, phase_times, worker_i);
    83   process_java_roots(closures, phase_times, worker_id, closures->trace_metadata() /* notify_claimed_nmethods_done */);
    87 
    84 
    88   // This is the point where this worker thread will not find more strong CLDs/nmethods.
    85   process_vm_roots(closures, phase_times, worker_id);
    89   // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
       
    90   if (closures->trace_metadata()) {
       
    91     worker_has_discovered_all_strong_classes();
       
    92   }
       
    93 
       
    94   process_vm_roots(closures, phase_times, worker_i);
       
    95 
    86 
    96   {
    87   {
    97     // Now the CM ref_processor roots.
    88     // Now the CM ref_processor roots.
    98     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
    89     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_id);
    99     if (_process_strong_tasks.try_claim_task(G1RP_PS_refProcessor_oops_do)) {
    90     if (_process_strong_tasks.try_claim_task(G1RP_PS_refProcessor_oops_do)) {
   100       // We need to treat the discovered reference lists of the
    91       // We need to treat the discovered reference lists of the
   101       // concurrent mark ref processor as roots and keep entries
    92       // concurrent mark ref processor as roots and keep entries
   102       // (which are added by the marking threads) on them live
    93       // (which are added by the marking threads) on them live
   103       // until they can be processed at the end of marking.
    94       // until they can be processed at the end of marking.
   104       _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
    95       _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
   105     }
    96     }
   106   }
    97   }
   107 
    98 
   108   if (closures->trace_metadata()) {
    99   if (closures->trace_metadata()) {
   109     {
   100     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongRoots, worker_id);
   110       G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
   101     // Wait to make sure all workers passed the strong nmethods phase.
   111       // Barrier to make sure all workers passed
   102     wait_until_all_strong_nmethods_discovered();
   112       // the strong CLD and strong nmethods phases.
       
   113       wait_until_all_strong_classes_discovered();
       
   114     }
       
   115 
       
   116     // Now take the complement of the strong CLDs.
       
   117     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
       
   118     assert(closures->second_pass_weak_clds() != NULL, "Should be non-null if we are tracing metadata.");
       
   119     ClassLoaderDataGraph::roots_cld_do(NULL, closures->second_pass_weak_clds());
       
   120   } else {
       
   121     phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
       
   122     phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
       
   123     assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata.");
       
   124   }
   103   }
   125 
   104 
   126   _process_strong_tasks.all_tasks_completed(n_workers());
   105   _process_strong_tasks.all_tasks_completed(n_workers());
   127 }
   106 }
   128 
   107 
   190   _process_strong_tasks.all_tasks_completed(n_workers());
   169   _process_strong_tasks.all_tasks_completed(n_workers());
   191 }
   170 }
   192 
   171 
   193 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
   172 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
   194                                          G1GCPhaseTimes* phase_times,
   173                                          G1GCPhaseTimes* phase_times,
   195                                          uint worker_i) {
   174                                          uint worker_id,
   196   // Iterating over the CLDG and the Threads are done early to allow us to
   175                                          bool notify_claimed_nmethods_done) {
   197   // first process the strong CLDs and nmethods and then, after a barrier,
   176   // We need to make make sure that the "strong" nmethods are processed first
   198   // let the thread process the weak CLDs and nmethods.
   177   // using the strong closure. Only after that we process the weakly reachable
   199   {
   178   // nmethods.
   200     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
   179   // We need to strictly separate the strong and weak nmethod processing because
   201     if (_process_strong_tasks.try_claim_task(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
   180   // any processing claims that nmethod, i.e. will not be iterated again.
   202       ClassLoaderDataGraph::roots_cld_do(closures->strong_clds(), closures->weak_clds());
   181   // Which means if an nmethod is processed first and claimed, the strong processing
   203     }
   182   // will not happen, and the oops reachable by that nmethod will not be marked
   204   }
   183   // properly.
   205 
   184   //
   206   {
   185   // That is why we process strong nmethods first, synchronize all threads via a
   207     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
   186   // barrier, and only then allow weak processing. To minimize the wait time at
       
   187   // that barrier we do the strong nmethod processing first, and immediately after-
       
   188   // wards indicate that that thread is done. Hopefully other root processing after
       
   189   // nmethod processing is enough so there is no need to wait.
       
   190   //
       
   191   // This is only required in the concurrent start pause with class unloading enabled.
       
   192   {
       
   193     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_id);
   208     bool is_par = n_workers() > 1;
   194     bool is_par = n_workers() > 1;
   209     Threads::possibly_parallel_oops_do(is_par,
   195     Threads::possibly_parallel_oops_do(is_par,
   210                                        closures->strong_oops(),
   196                                        closures->strong_oops(),
   211                                        closures->strong_codeblobs());
   197                                        closures->strong_codeblobs());
   212   }
   198   }
       
   199 
       
   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   {
       
   207     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_id);
       
   208     if (_process_strong_tasks.try_claim_task(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
       
   209       ClassLoaderDataGraph::roots_cld_do(closures->strong_clds(), closures->weak_clds());
       
   210     }
       
   211   }
   213 }
   212 }
   214 
   213 
   215 void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
   214 void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
   216                                        G1GCPhaseTimes* phase_times,
   215                                        G1GCPhaseTimes* phase_times,
   217                                        uint worker_i) {
   216                                        uint worker_id) {
   218   OopClosure* strong_roots = closures->strong_oops();
   217   OopClosure* strong_roots = closures->strong_oops();
   219 
   218 
   220   {
   219   {
   221     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
   220     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_id);
   222     if (_process_strong_tasks.try_claim_task(G1RP_PS_Universe_oops_do)) {
   221     if (_process_strong_tasks.try_claim_task(G1RP_PS_Universe_oops_do)) {
   223       Universe::oops_do(strong_roots);
   222       Universe::oops_do(strong_roots);
   224     }
   223     }
   225   }
   224   }
   226 
   225 
   227   {
   226   {
   228     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i);
   227     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_id);
   229     if (_process_strong_tasks.try_claim_task(G1RP_PS_JNIHandles_oops_do)) {
   228     if (_process_strong_tasks.try_claim_task(G1RP_PS_JNIHandles_oops_do)) {
   230       JNIHandles::oops_do(strong_roots);
   229       JNIHandles::oops_do(strong_roots);
   231     }
   230     }
   232   }
   231   }
   233 
   232 
   234   {
   233   {
   235     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i);
   234     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_id);
   236     if (_process_strong_tasks.try_claim_task(G1RP_PS_ObjectSynchronizer_oops_do)) {
   235     if (_process_strong_tasks.try_claim_task(G1RP_PS_ObjectSynchronizer_oops_do)) {
   237       ObjectSynchronizer::oops_do(strong_roots);
   236       ObjectSynchronizer::oops_do(strong_roots);
   238     }
   237     }
   239   }
   238   }
   240 
   239 
   241   {
   240   {
   242     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i);
   241     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_id);
   243     if (_process_strong_tasks.try_claim_task(G1RP_PS_Management_oops_do)) {
   242     if (_process_strong_tasks.try_claim_task(G1RP_PS_Management_oops_do)) {
   244       Management::oops_do(strong_roots);
   243       Management::oops_do(strong_roots);
   245     }
   244     }
   246   }
   245   }
   247 
   246 
   248   {
   247   {
   249     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i);
   248     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_id);
   250     if (_process_strong_tasks.try_claim_task(G1RP_PS_jvmti_oops_do)) {
   249     if (_process_strong_tasks.try_claim_task(G1RP_PS_jvmti_oops_do)) {
   251       JvmtiExport::oops_do(strong_roots);
   250       JvmtiExport::oops_do(strong_roots);
   252     }
   251     }
   253   }
   252   }
   254 
   253 
   255 #if INCLUDE_AOT
   254 #if INCLUDE_AOT
   256   if (UseAOT) {
   255   if (UseAOT) {
   257     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::AOTCodeRoots, worker_i);
   256     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::AOTCodeRoots, worker_id);
   258     if (_process_strong_tasks.try_claim_task(G1RP_PS_aot_oops_do)) {
   257     if (_process_strong_tasks.try_claim_task(G1RP_PS_aot_oops_do)) {
   259         AOTLoader::oops_do(strong_roots);
   258         AOTLoader::oops_do(strong_roots);
   260     }
   259     }
   261   }
   260   }
   262 #endif
   261 #endif
   263 
   262 
   264 #if INCLUDE_JVMCI
   263   {
   265   if (EnableJVMCI) {
   264     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_id);
   266     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMCIRoots, worker_i);
       
   267     if (_process_strong_tasks.try_claim_task(G1RP_PS_JVMCI_oops_do)) {
       
   268       JVMCI::oops_do(strong_roots);
       
   269     }
       
   270   }
       
   271 #endif
       
   272 
       
   273   {
       
   274     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
       
   275     if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {
   265     if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {
   276       SystemDictionary::oops_do(strong_roots);
   266       SystemDictionary::oops_do(strong_roots);
   277     }
   267     }
   278   }
   268   }
   279 }
   269 }
   280 
   270 
   281 void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
   271 void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
   282                                                G1GCPhaseTimes* phase_times,
   272                                                G1GCPhaseTimes* phase_times,
   283                                                uint worker_i) {
   273                                                uint worker_id) {
   284   if (_process_strong_tasks.try_claim_task(G1RP_PS_CodeCache_oops_do)) {
   274   if (_process_strong_tasks.try_claim_task(G1RP_PS_CodeCache_oops_do)) {
   285     CodeCache::blobs_do(code_closure);
   275     CodeCache::blobs_do(code_closure);
   286   }
   276   }
   287 }
   277 }
   288 
   278