25 |
25 |
26 #include "classfile/classLoaderDataGraph.hpp" |
26 #include "classfile/classLoaderDataGraph.hpp" |
27 #include "classfile/stringTable.hpp" |
27 #include "classfile/stringTable.hpp" |
28 #include "classfile/systemDictionary.hpp" |
28 #include "classfile/systemDictionary.hpp" |
29 #include "code/codeCache.hpp" |
29 #include "code/codeCache.hpp" |
30 #include "gc/shenandoah/shenandoahClosures.inline.hpp" |
|
31 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" |
30 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" |
32 #include "gc/shenandoah/shenandoahHeap.hpp" |
31 #include "gc/shenandoah/shenandoahHeap.hpp" |
33 #include "gc/shenandoah/shenandoahHeuristics.hpp" |
|
34 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
35 #include "gc/shenandoah/shenandoahStringDedup.hpp" |
33 #include "gc/shenandoah/shenandoahStringDedup.hpp" |
36 #include "gc/shenandoah/shenandoahTimingTracker.hpp" |
34 #include "gc/shenandoah/shenandoahTimingTracker.hpp" |
37 #include "gc/shenandoah/shenandoahVMOperations.hpp" |
35 #include "gc/shenandoah/shenandoahVMOperations.hpp" |
38 #include "gc/shared/weakProcessor.inline.hpp" |
36 #include "jfr/jfr.hpp" |
39 #include "memory/allocation.inline.hpp" |
|
40 #include "memory/iterator.hpp" |
37 #include "memory/iterator.hpp" |
41 #include "memory/resourceArea.hpp" |
38 #include "memory/resourceArea.hpp" |
42 #include "memory/universe.hpp" |
39 #include "memory/universe.hpp" |
43 #include "runtime/thread.hpp" |
40 #include "runtime/thread.hpp" |
44 #include "services/management.hpp" |
41 #include "services/management.hpp" |
69 _management_root.oops_do(cl, worker_id); |
66 _management_root.oops_do(cl, worker_id); |
70 _system_dictionary_root.oops_do(cl, worker_id); |
67 _system_dictionary_root.oops_do(cl, worker_id); |
71 _jvmti_root.oops_do(cl, worker_id); |
68 _jvmti_root.oops_do(cl, worker_id); |
72 } |
69 } |
73 |
70 |
|
71 ShenandoahWeakSerialRoot::ShenandoahWeakSerialRoot(ShenandoahWeakSerialRoot::WeakOopsDo weak_oops_do, ShenandoahPhaseTimings::GCParPhases phase) : |
|
72 _weak_oops_do(weak_oops_do), _phase(phase) { |
|
73 } |
|
74 |
|
75 void ShenandoahWeakSerialRoot::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) { |
|
76 if (_claimed.try_set()) { |
|
77 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); |
|
78 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id); |
|
79 _weak_oops_do(is_alive, keep_alive); |
|
80 } |
|
81 } |
|
82 |
|
83 #if INCLUDE_JVMTI |
|
84 ShenandoahJVMTIWeakRoot::ShenandoahJVMTIWeakRoot() : |
|
85 ShenandoahWeakSerialRoot(&JvmtiExport::weak_oops_do, ShenandoahPhaseTimings::JVMTIWeakRoots) { |
|
86 } |
|
87 #endif // INCLUDE_JVMTI |
|
88 |
|
89 #if INCLUDE_JFR |
|
90 ShenandoahJFRWeakRoot::ShenandoahJFRWeakRoot() : |
|
91 ShenandoahWeakSerialRoot(&Jfr::weak_oops_do, ShenandoahPhaseTimings::JFRWeakRoots) { |
|
92 } |
|
93 #endif // INCLUDE_JFR |
|
94 |
|
95 void ShenandoahSerialWeakRoots::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) { |
|
96 JVMTI_ONLY(_jvmti_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);) |
|
97 JFR_ONLY(_jfr_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);) |
|
98 } |
|
99 |
|
100 void ShenandoahSerialWeakRoots::weak_oops_do(OopClosure* cl, uint worker_id) { |
|
101 AlwaysTrueClosure always_true; |
|
102 weak_oops_do(&always_true, cl, worker_id); |
|
103 } |
|
104 |
74 ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) { |
105 ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) { |
75 Threads::change_thread_claim_token(); |
106 Threads::change_thread_claim_token(); |
76 } |
107 } |
77 |
108 |
78 void ShenandoahThreadRoots::oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id) { |
109 void ShenandoahThreadRoots::oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id) { |
91 |
122 |
92 ShenandoahThreadRoots::~ShenandoahThreadRoots() { |
123 ShenandoahThreadRoots::~ShenandoahThreadRoots() { |
93 Threads::assert_all_threads_claimed(); |
124 Threads::assert_all_threads_claimed(); |
94 } |
125 } |
95 |
126 |
96 ShenandoahWeakRoots::ShenandoahWeakRoots(uint n_workers) : |
|
97 _process_timings(n_workers), |
|
98 _task(&_process_timings, n_workers) { |
|
99 } |
|
100 |
|
101 ShenandoahWeakRoots::~ShenandoahWeakRoots() { |
|
102 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); |
|
103 ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_process_timings, |
|
104 worker_times); |
|
105 } |
|
106 |
|
107 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() { |
127 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() { |
108 if (ShenandoahStringDedup::is_enabled()) { |
128 if (ShenandoahStringDedup::is_enabled()) { |
109 StringDedup::gc_prologue(false); |
129 StringDedup::gc_prologue(false); |
110 } |
130 } |
111 } |
131 } |
135 } |
155 } |
136 |
156 |
137 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) : |
157 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) : |
138 ShenandoahRootProcessor(phase), |
158 ShenandoahRootProcessor(phase), |
139 _thread_roots(n_workers > 1), |
159 _thread_roots(n_workers > 1), |
140 _weak_roots(n_workers), |
|
141 _include_concurrent_roots(include_concurrent_roots) { |
160 _include_concurrent_roots(include_concurrent_roots) { |
142 } |
161 } |
143 |
162 |
144 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) { |
163 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) { |
145 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations); |
164 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations); |
146 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); |
165 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); |
147 AlwaysTrueClosure always_true; |
166 AlwaysTrueClosure always_true; |
148 |
167 |
149 _serial_roots.oops_do(oops, worker_id); |
168 _serial_roots.oops_do(oops, worker_id); |
|
169 _serial_weak_roots.weak_oops_do(oops, worker_id); |
150 if (_include_concurrent_roots) { |
170 if (_include_concurrent_roots) { |
151 _jni_roots.oops_do<OopClosure>(oops, worker_id); |
171 _jni_roots.oops_do<OopClosure>(oops, worker_id); |
|
172 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
152 } |
173 } |
153 |
174 |
154 _thread_roots.oops_do(oops, NULL, worker_id); |
175 _thread_roots.oops_do(oops, NULL, worker_id); |
155 _cld_roots.cld_do(&clds, worker_id); |
176 _cld_roots.cld_do(&clds, worker_id); |
156 _code_roots.code_blobs_do(&blobsCl, worker_id); |
177 _code_roots.code_blobs_do(&blobsCl, worker_id); |
157 |
178 |
158 _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id); |
|
159 _dedup_roots.oops_do(&always_true, oops, worker_id); |
179 _dedup_roots.oops_do(&always_true, oops, worker_id); |
160 } |
180 } |
161 |
181 |
162 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache) : |
182 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache) : |
163 ShenandoahRootProcessor(phase), |
183 ShenandoahRootProcessor(phase), |
164 _thread_roots(n_workers > 1), |
184 _thread_roots(n_workers > 1), |
165 _weak_roots(n_workers), |
|
166 _update_code_cache(update_code_cache) { |
185 _update_code_cache(update_code_cache) { |
167 } |
186 } |
168 |
187 |
169 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) : |
188 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) : |
170 ShenandoahRootProcessor(phase), |
189 ShenandoahRootProcessor(phase), |
171 _thread_roots(n_workers > 1), |
190 _thread_roots(n_workers > 1) { |
172 _weak_roots(n_workers) { |
|
173 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only"); |
191 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only"); |
174 } |
192 } |
175 |
193 |
176 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { |
194 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { |
177 CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations); |
195 CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations); |
183 |
201 |
184 _thread_roots.oops_do(oops, NULL, worker_id); |
202 _thread_roots.oops_do(oops, NULL, worker_id); |
185 _cld_roots.cld_do(&adjust_cld_closure, worker_id); |
203 _cld_roots.cld_do(&adjust_cld_closure, worker_id); |
186 _code_roots.code_blobs_do(&adjust_code_closure, worker_id); |
204 _code_roots.code_blobs_do(&adjust_code_closure, worker_id); |
187 |
205 |
188 _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id); |
206 _serial_weak_roots.weak_oops_do(oops, worker_id); |
|
207 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
189 _dedup_roots.oops_do(&always_true, oops, worker_id); |
208 _dedup_roots.oops_do(&always_true, oops, worker_id); |
190 } |
209 } |
191 |
210 |
192 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() : |
211 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() : |
193 ShenandoahRootProcessor(ShenandoahPhaseTimings::_num_phases), |
212 ShenandoahRootProcessor(ShenandoahPhaseTimings::_num_phases), |