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/shenandoahConcurrentRoots.hpp" |
30 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" |
32 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" |
31 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
33 #include "gc/shenandoah/shenandoahHeap.hpp" |
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
34 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
33 #include "gc/shenandoah/shenandoahStringDedup.hpp" |
35 #include "gc/shenandoah/shenandoahStringDedup.hpp" |
34 #include "gc/shenandoah/shenandoahTimingTracker.hpp" |
36 #include "gc/shenandoah/shenandoahTimingTracker.hpp" |
35 #include "gc/shenandoah/shenandoahVMOperations.hpp" |
37 #include "gc/shenandoah/shenandoahVMOperations.hpp" |
36 #include "jfr/jfr.hpp" |
38 #include "jfr/jfr.hpp" |
157 ShenandoahRootProcessor::~ShenandoahRootProcessor() { |
159 ShenandoahRootProcessor::~ShenandoahRootProcessor() { |
158 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint"); |
160 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint"); |
159 _heap->phase_timings()->record_workers_end(_phase); |
161 _heap->phase_timings()->record_workers_end(_phase); |
160 } |
162 } |
161 |
163 |
162 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) : |
164 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, |
|
165 ShenandoahPhaseTimings::Phase phase, |
|
166 bool include_concurrent_roots, |
|
167 bool include_concurrent_code_roots) : |
163 ShenandoahRootProcessor(phase), |
168 ShenandoahRootProcessor(phase), |
164 _thread_roots(n_workers > 1), |
169 _thread_roots(n_workers > 1), |
165 _include_concurrent_roots(include_concurrent_roots) { |
170 _include_concurrent_roots(include_concurrent_roots), |
|
171 _include_concurrent_code_roots(include_concurrent_code_roots) { |
166 } |
172 } |
167 |
173 |
168 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) { |
174 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) { |
169 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations); |
175 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations); |
|
176 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops); |
|
177 CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ? |
|
178 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) : |
|
179 static_cast<CodeBlobToOopClosure*>(&blobsCl); |
170 AlwaysTrueClosure always_true; |
180 AlwaysTrueClosure always_true; |
171 |
181 |
172 _serial_roots.oops_do(oops, worker_id); |
182 _serial_roots.oops_do(oops, worker_id); |
173 _serial_weak_roots.weak_oops_do(oops, worker_id); |
183 _serial_weak_roots.weak_oops_do(oops, worker_id); |
174 if (_include_concurrent_roots) { |
184 if (_include_concurrent_roots) { |
176 _vm_roots.oops_do<OopClosure>(oops, worker_id); |
186 _vm_roots.oops_do<OopClosure>(oops, worker_id); |
177 _cld_roots.cld_do(&clds, worker_id); |
187 _cld_roots.cld_do(&clds, worker_id); |
178 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
188 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
179 } |
189 } |
180 |
190 |
181 _thread_roots.oops_do(oops, NULL, worker_id); |
191 if (_include_concurrent_code_roots) { |
182 _code_roots.code_blobs_do(&blobsCl, worker_id); |
192 _code_roots.code_blobs_do(codes_cl, worker_id); |
|
193 _thread_roots.oops_do(oops, NULL, worker_id); |
|
194 } else { |
|
195 _thread_roots.oops_do(oops, codes_cl, worker_id); |
|
196 } |
183 |
197 |
184 _dedup_roots.oops_do(&always_true, oops, worker_id); |
198 _dedup_roots.oops_do(&always_true, oops, worker_id); |
185 } |
199 } |
186 |
200 |
187 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) : |
201 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) : |
206 _thread_roots(n_workers > 1) { |
220 _thread_roots(n_workers > 1) { |
207 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only"); |
221 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only"); |
208 } |
222 } |
209 |
223 |
210 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { |
224 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { |
211 CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations); |
225 CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations); |
|
226 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops); |
|
227 CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ? |
|
228 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) : |
|
229 static_cast<CodeBlobToOopClosure*>(&code_blob_cl); |
212 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong); |
230 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong); |
213 AlwaysTrueClosure always_true; |
231 AlwaysTrueClosure always_true; |
214 |
232 |
215 _serial_roots.oops_do(oops, worker_id); |
233 _serial_roots.oops_do(oops, worker_id); |
216 _vm_roots.oops_do(oops, worker_id); |
234 _vm_roots.oops_do(oops, worker_id); |
217 |
235 |
218 _thread_roots.oops_do(oops, NULL, worker_id); |
236 _thread_roots.oops_do(oops, NULL, worker_id); |
219 _cld_roots.cld_do(&adjust_cld_closure, worker_id); |
237 _cld_roots.cld_do(&adjust_cld_closure, worker_id); |
220 _code_roots.code_blobs_do(&adjust_code_closure, worker_id); |
238 _code_roots.code_blobs_do(adjust_code_closure, worker_id); |
221 |
239 |
222 _serial_weak_roots.weak_oops_do(oops, worker_id); |
240 _serial_weak_roots.weak_oops_do(oops, worker_id); |
223 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
241 _weak_roots.oops_do<OopClosure>(oops, worker_id); |
224 _dedup_roots.oops_do(&always_true, oops, worker_id); |
242 _dedup_roots.oops_do(&always_true, oops, worker_id); |
225 } |
243 } |