1.1 --- a/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp Mon Dec 01 15:24:56 2014 +0100 1.2 +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp Thu Mar 19 15:25:54 2015 +0100 1.3 @@ -128,6 +128,7 @@ 1.4 uint worker_i) { 1.5 // First scan the shared roots. 1.6 double ext_roots_start = os::elapsedTime(); 1.7 + G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); 1.8 1.9 BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); 1.10 BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); 1.11 @@ -142,7 +143,9 @@ 1.12 trace_metadata ? scan_strong_clds : NULL, 1.13 scan_strong_clds, 1.14 trace_metadata ? NULL : scan_weak_clds, 1.15 - &root_code_blobs); 1.16 + &root_code_blobs, 1.17 + phase_times, 1.18 + worker_i); 1.19 1.20 // This is the point where this worker thread will not find more strong CLDs/nmethods. 1.21 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. 1.22 @@ -150,24 +153,34 @@ 1.23 worker_has_discovered_all_strong_classes(); 1.24 } 1.25 1.26 - process_vm_roots(strong_roots, weak_roots); 1.27 + process_vm_roots(strong_roots, weak_roots, phase_times, worker_i); 1.28 1.29 - // Now the CM ref_processor roots. 1.30 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) { 1.31 - // We need to treat the discovered reference lists of the 1.32 - // concurrent mark ref processor as roots and keep entries 1.33 - // (which are added by the marking threads) on them live 1.34 - // until they can be processed at the end of marking. 1.35 - _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); 1.36 + { 1.37 + // Now the CM ref_processor roots. 1.38 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i); 1.39 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) { 1.40 + // We need to treat the discovered reference lists of the 1.41 + // concurrent mark ref processor as roots and keep entries 1.42 + // (which are added by the marking threads) on them live 1.43 + // until they can be processed at the end of marking. 1.44 + _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); 1.45 + } 1.46 } 1.47 1.48 if (trace_metadata) { 1.49 - // Barrier to make sure all workers passed 1.50 - // the strong CLD and strong nmethods phases. 1.51 - wait_until_all_strong_classes_discovered(); 1.52 + { 1.53 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i); 1.54 + // Barrier to make sure all workers passed 1.55 + // the strong CLD and strong nmethods phases. 1.56 + wait_until_all_strong_classes_discovered(); 1.57 + } 1.58 1.59 // Now take the complement of the strong CLDs. 1.60 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i); 1.61 ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds); 1.62 + } else { 1.63 + phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0); 1.64 + phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0); 1.65 } 1.66 1.67 // Finish up any enqueued closure apps (attributed as object copy time). 1.68 @@ -177,7 +190,6 @@ 1.69 double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds() 1.70 + buf_scan_non_heap_weak_roots.closure_app_seconds(); 1.71 1.72 - G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); 1.73 phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); 1.74 1.75 double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; 1.76 @@ -201,8 +213,8 @@ 1.77 CLDClosure* clds, 1.78 CodeBlobClosure* blobs) { 1.79 1.80 - process_java_roots(oops, clds, clds, NULL, blobs); 1.81 - process_vm_roots(oops, NULL); 1.82 + process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0); 1.83 + process_vm_roots(oops, NULL, NULL, 0); 1.84 1.85 _process_strong_tasks->all_tasks_completed(); 1.86 } 1.87 @@ -211,8 +223,8 @@ 1.88 CLDClosure* clds, 1.89 CodeBlobClosure* blobs) { 1.90 1.91 - process_java_roots(oops, NULL, clds, clds, NULL); 1.92 - process_vm_roots(oops, oops); 1.93 + process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0); 1.94 + process_vm_roots(oops, oops, NULL, 0); 1.95 1.96 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) { 1.97 CodeCache::blobs_do(blobs); 1.98 @@ -225,60 +237,95 @@ 1.99 CLDClosure* thread_stack_clds, 1.100 CLDClosure* strong_clds, 1.101 CLDClosure* weak_clds, 1.102 - CodeBlobClosure* strong_code) { 1.103 + CodeBlobClosure* strong_code, 1.104 + G1GCPhaseTimes* phase_times, 1.105 + uint worker_i) { 1.106 assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set"); 1.107 // Iterating over the CLDG and the Threads are done early to allow us to 1.108 // first process the strong CLDs and nmethods and then, after a barrier, 1.109 // let the thread process the weak CLDs and nmethods. 1.110 - 1.111 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) { 1.112 - ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); 1.113 + { 1.114 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i); 1.115 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) { 1.116 + ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); 1.117 + } 1.118 } 1.119 1.120 - Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code); 1.121 + { 1.122 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i); 1.123 + Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code); 1.124 + } 1.125 } 1.126 1.127 void G1RootProcessor::process_vm_roots(OopClosure* strong_roots, 1.128 - OopClosure* weak_roots) { 1.129 - 1.130 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) { 1.131 - Universe::oops_do(strong_roots); 1.132 + OopClosure* weak_roots, 1.133 + G1GCPhaseTimes* phase_times, 1.134 + uint worker_i) { 1.135 + { 1.136 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i); 1.137 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) { 1.138 + Universe::oops_do(strong_roots); 1.139 + } 1.140 } 1.141 1.142 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) { 1.143 - JNIHandles::oops_do(strong_roots); 1.144 + { 1.145 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i); 1.146 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) { 1.147 + JNIHandles::oops_do(strong_roots); 1.148 + } 1.149 } 1.150 1.151 - if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) { 1.152 - ObjectSynchronizer::oops_do(strong_roots); 1.153 + { 1.154 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i); 1.155 + if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) { 1.156 + ObjectSynchronizer::oops_do(strong_roots); 1.157 + } 1.158 } 1.159 1.160 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) { 1.161 - FlatProfiler::oops_do(strong_roots); 1.162 + { 1.163 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::FlatProfilerRoots, worker_i); 1.164 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) { 1.165 + FlatProfiler::oops_do(strong_roots); 1.166 + } 1.167 } 1.168 1.169 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) { 1.170 - Management::oops_do(strong_roots); 1.171 + { 1.172 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i); 1.173 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) { 1.174 + Management::oops_do(strong_roots); 1.175 + } 1.176 } 1.177 1.178 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) { 1.179 - JvmtiExport::oops_do(strong_roots); 1.180 + { 1.181 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i); 1.182 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) { 1.183 + JvmtiExport::oops_do(strong_roots); 1.184 + } 1.185 } 1.186 1.187 - if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) { 1.188 - SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1.189 + { 1.190 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i); 1.191 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) { 1.192 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1.193 + } 1.194 } 1.195 1.196 - // All threads execute the following. A specific chunk of buckets 1.197 - // from the StringTable are the individual tasks. 1.198 - if (weak_roots != NULL) { 1.199 - StringTable::possibly_parallel_oops_do(weak_roots); 1.200 + { 1.201 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i); 1.202 + // All threads execute the following. A specific chunk of buckets 1.203 + // from the StringTable are the individual tasks. 1.204 + if (weak_roots != NULL) { 1.205 + StringTable::possibly_parallel_oops_do(weak_roots); 1.206 + } 1.207 } 1.208 } 1.209 1.210 void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, 1.211 OopClosure* scan_non_heap_weak_roots, 1.212 uint worker_i) { 1.213 + G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); 1.214 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CodeCacheRoots, worker_i); 1.215 + 1.216 // Now scan the complement of the collection set. 1.217 G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); 1.218