1.1 --- a/src/share/vm/memory/genCollectedHeap.cpp Thu Mar 26 13:19:32 2015 +0100 1.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp Mon Dec 01 15:24:56 2014 +0100 1.3 @@ -26,6 +26,7 @@ 1.4 #include "classfile/symbolTable.hpp" 1.5 #include "classfile/systemDictionary.hpp" 1.6 #include "classfile/vmSymbols.hpp" 1.7 +#include "code/codeCache.hpp" 1.8 #include "code/icBuffer.hpp" 1.9 #include "gc_implementation/shared/collectorCounters.hpp" 1.10 #include "gc_implementation/shared/gcTrace.hpp" 1.11 @@ -49,6 +50,7 @@ 1.12 #include "runtime/handles.inline.hpp" 1.13 #include "runtime/java.hpp" 1.14 #include "runtime/vmThread.hpp" 1.15 +#include "services/management.hpp" 1.16 #include "services/memoryService.hpp" 1.17 #include "utilities/vmError.hpp" 1.18 #include "utilities/workgroup.hpp" 1.19 @@ -63,7 +65,15 @@ 1.20 1.21 // The set of potentially parallel tasks in root scanning. 1.22 enum GCH_strong_roots_tasks { 1.23 - // We probably want to parallelize both of these internally, but for now... 1.24 + GCH_PS_Universe_oops_do, 1.25 + GCH_PS_JNIHandles_oops_do, 1.26 + GCH_PS_ObjectSynchronizer_oops_do, 1.27 + GCH_PS_FlatProfiler_oops_do, 1.28 + GCH_PS_Management_oops_do, 1.29 + GCH_PS_SystemDictionary_oops_do, 1.30 + GCH_PS_ClassLoaderDataGraph_oops_do, 1.31 + GCH_PS_jvmti_oops_do, 1.32 + GCH_PS_CodeCache_oops_do, 1.33 GCH_PS_younger_gens, 1.34 // Leave this one last. 1.35 GCH_PS_NumElements 1.36 @@ -72,13 +82,9 @@ 1.37 GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) : 1.38 SharedHeap(policy), 1.39 _gen_policy(policy), 1.40 - _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)), 1.41 + _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)), 1.42 _full_collections_completed(0) 1.43 { 1.44 - if (_gen_process_roots_tasks == NULL || 1.45 - !_gen_process_roots_tasks->valid()) { 1.46 - vm_exit_during_initialization("Failed necessary allocation."); 1.47 - } 1.48 assert(policy != NULL, "Sanity check"); 1.49 } 1.50 1.51 @@ -589,29 +595,137 @@ 1.52 1.53 void GenCollectedHeap::set_par_threads(uint t) { 1.54 SharedHeap::set_par_threads(t); 1.55 - _gen_process_roots_tasks->set_n_threads(t); 1.56 + set_n_termination(t); 1.57 } 1.58 1.59 -void GenCollectedHeap:: 1.60 -gen_process_roots(int level, 1.61 - bool younger_gens_as_roots, 1.62 - bool activate_scope, 1.63 - SharedHeap::ScanningOption so, 1.64 - OopsInGenClosure* not_older_gens, 1.65 - OopsInGenClosure* weak_roots, 1.66 - OopsInGenClosure* older_gens, 1.67 - CLDClosure* cld_closure, 1.68 - CLDClosure* weak_cld_closure, 1.69 - CodeBlobClosure* code_closure) { 1.70 +void GenCollectedHeap::set_n_termination(uint t) { 1.71 + _process_strong_tasks->set_n_threads(t); 1.72 +} 1.73 + 1.74 +#ifdef ASSERT 1.75 +class AssertNonScavengableClosure: public OopClosure { 1.76 +public: 1.77 + virtual void do_oop(oop* p) { 1.78 + assert(!Universe::heap()->is_in_partial_collection(*p), 1.79 + "Referent should not be scavengable."); } 1.80 + virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 1.81 +}; 1.82 +static AssertNonScavengableClosure assert_is_non_scavengable_closure; 1.83 +#endif 1.84 + 1.85 +void GenCollectedHeap::process_roots(bool activate_scope, 1.86 + ScanningOption so, 1.87 + OopClosure* strong_roots, 1.88 + OopClosure* weak_roots, 1.89 + CLDClosure* strong_cld_closure, 1.90 + CLDClosure* weak_cld_closure, 1.91 + CodeBlobClosure* code_roots) { 1.92 + StrongRootsScope srs(this, activate_scope); 1.93 1.94 // General roots. 1.95 - SharedHeap::process_roots(activate_scope, so, 1.96 - not_older_gens, weak_roots, 1.97 - cld_closure, weak_cld_closure, 1.98 - code_closure); 1.99 + assert(_strong_roots_parity != 0, "must have called prologue code"); 1.100 + assert(code_roots != NULL, "code root closure should always be set"); 1.101 + // _n_termination for _process_strong_tasks should be set up stream 1.102 + // in a method not running in a GC worker. Otherwise the GC worker 1.103 + // could be trying to change the termination condition while the task 1.104 + // is executing in another GC worker. 1.105 + 1.106 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ClassLoaderDataGraph_oops_do)) { 1.107 + ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); 1.108 + } 1.109 + 1.110 + // Some CLDs contained in the thread frames should be considered strong. 1.111 + // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 1.112 + CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 1.113 + // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 1.114 + CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 1.115 + 1.116 + Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 1.117 + 1.118 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) { 1.119 + Universe::oops_do(strong_roots); 1.120 + } 1.121 + // Global (strong) JNI handles 1.122 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) { 1.123 + JNIHandles::oops_do(strong_roots); 1.124 + } 1.125 + 1.126 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) { 1.127 + ObjectSynchronizer::oops_do(strong_roots); 1.128 + } 1.129 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) { 1.130 + FlatProfiler::oops_do(strong_roots); 1.131 + } 1.132 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) { 1.133 + Management::oops_do(strong_roots); 1.134 + } 1.135 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) { 1.136 + JvmtiExport::oops_do(strong_roots); 1.137 + } 1.138 + 1.139 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) { 1.140 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1.141 + } 1.142 + 1.143 + // All threads execute the following. A specific chunk of buckets 1.144 + // from the StringTable are the individual tasks. 1.145 + if (weak_roots != NULL) { 1.146 + if (CollectedHeap::use_parallel_gc_threads()) { 1.147 + StringTable::possibly_parallel_oops_do(weak_roots); 1.148 + } else { 1.149 + StringTable::oops_do(weak_roots); 1.150 + } 1.151 + } 1.152 + 1.153 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) { 1.154 + if (so & SO_ScavengeCodeCache) { 1.155 + assert(code_roots != NULL, "must supply closure for code cache"); 1.156 + 1.157 + // We only visit parts of the CodeCache when scavenging. 1.158 + CodeCache::scavenge_root_nmethods_do(code_roots); 1.159 + } 1.160 + if (so & SO_AllCodeCache) { 1.161 + assert(code_roots != NULL, "must supply closure for code cache"); 1.162 + 1.163 + // CMSCollector uses this to do intermediate-strength collections. 1.164 + // We scan the entire code cache, since CodeCache::do_unloading is not called. 1.165 + CodeCache::blobs_do(code_roots); 1.166 + } 1.167 + // Verify that the code cache contents are not subject to 1.168 + // movement by a scavenging collection. 1.169 + DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); 1.170 + DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 1.171 + } 1.172 + 1.173 +} 1.174 + 1.175 +void GenCollectedHeap::gen_process_roots(int level, 1.176 + bool younger_gens_as_roots, 1.177 + bool activate_scope, 1.178 + ScanningOption so, 1.179 + bool only_strong_roots, 1.180 + OopsInGenClosure* not_older_gens, 1.181 + OopsInGenClosure* older_gens, 1.182 + CLDClosure* cld_closure) { 1.183 + const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1.184 + 1.185 + bool is_moving_collection = false; 1.186 + if (level == 0 || is_adjust_phase) { 1.187 + // young collections are always moving 1.188 + is_moving_collection = true; 1.189 + } 1.190 + 1.191 + MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1.192 + OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens; 1.193 + CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure; 1.194 + 1.195 + process_roots(activate_scope, so, 1.196 + not_older_gens, weak_roots, 1.197 + cld_closure, weak_cld_closure, 1.198 + &mark_code_closure); 1.199 1.200 if (younger_gens_as_roots) { 1.201 - if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1.202 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1.203 for (int i = 0; i < level; i++) { 1.204 not_older_gens->set_generation(_gens[i]); 1.205 _gens[i]->oop_iterate(not_older_gens); 1.206 @@ -627,43 +741,18 @@ 1.207 older_gens->reset_generation(); 1.208 } 1.209 1.210 - _gen_process_roots_tasks->all_tasks_completed(); 1.211 + _process_strong_tasks->all_tasks_completed(); 1.212 } 1.213 1.214 -void GenCollectedHeap:: 1.215 -gen_process_roots(int level, 1.216 - bool younger_gens_as_roots, 1.217 - bool activate_scope, 1.218 - SharedHeap::ScanningOption so, 1.219 - bool only_strong_roots, 1.220 - OopsInGenClosure* not_older_gens, 1.221 - OopsInGenClosure* older_gens, 1.222 - CLDClosure* cld_closure) { 1.223 1.224 - const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1.225 - 1.226 - bool is_moving_collection = false; 1.227 - if (level == 0 || is_adjust_phase) { 1.228 - // young collections are always moving 1.229 - is_moving_collection = true; 1.230 - } 1.231 - 1.232 - MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1.233 - CodeBlobClosure* code_closure = &mark_code_closure; 1.234 - 1.235 - gen_process_roots(level, 1.236 - younger_gens_as_roots, 1.237 - activate_scope, so, 1.238 - not_older_gens, only_strong_roots ? NULL : not_older_gens, 1.239 - older_gens, 1.240 - cld_closure, only_strong_roots ? NULL : cld_closure, 1.241 - code_closure); 1.242 - 1.243 -} 1.244 +class AlwaysTrueClosure: public BoolObjectClosure { 1.245 +public: 1.246 + bool do_object_b(oop p) { return true; } 1.247 +}; 1.248 +static AlwaysTrueClosure always_true; 1.249 1.250 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) { 1.251 - SharedHeap::process_weak_roots(root_closure); 1.252 - // "Local" "weak" refs 1.253 + JNIHandles::weak_oops_do(&always_true, root_closure); 1.254 for (int i = 0; i < _n_gens; i++) { 1.255 _gens[i]->ref_processor()->weak_oops_do(root_closure); 1.256 }