182 ShenandoahRootProcessor(phase),
183 _vm_roots(phase),
184 _cld_roots(phase, n_workers, false /*heap iteration*/),
185 _thread_roots(phase, n_workers > 1),
186 _weak_roots(phase),
187 _code_roots(phase) {
188 }
189
190 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
191 ShenandoahRootProcessor(phase),
192 _vm_roots(phase),
193 _cld_roots(phase, n_workers, false /*heap iteration*/),
194 _thread_roots(phase, n_workers > 1),
195 _weak_roots(phase),
196 _code_roots(phase) {
197 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
198 }
199
200 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
201 NMethodToOopClosure code_blob_cl(oops, NMethodToOopClosure::FixRelocations);
202 ShenandoahNMethodAndDisarmClosure nmethods_and_disarm_Cl(oops);
203 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
204
205 // Process light-weight/limited parallel roots then
206 _vm_roots.oops_do(oops, worker_id);
207 _weak_roots.oops_do<OopClosure>(oops, worker_id);
208 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
209
210 // Process heavy-weight/fully parallel roots the last
211 _code_roots.nmethods_do(&nmethods_and_disarm_Cl, worker_id);
212 _thread_roots.oops_do(oops, nullptr, worker_id);
213 }
214
215 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner(uint n_workers) :
216 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
217 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
218 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
219 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, n_workers, true /*heap iteration*/),
220 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
221 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
222 }
223
224 class ShenandoahMarkNMethodClosure : public NMethodClosure {
225 private:
226 OopClosure* const _oops;
227 BarrierSetNMethod* const _bs_nm;
228
229 public:
230 ShenandoahMarkNMethodClosure(OopClosure* oops) :
231 _oops(oops),
232 _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
233
234 virtual void do_nmethod(nmethod* nm) {
235 assert(nm != nullptr, "Sanity");
236 if (_bs_nm != nullptr) {
237 // Make sure it only sees to-space objects
238 _bs_nm->nmethod_entry_barrier(nm);
239 }
240 ShenandoahNMethod* const snm = ShenandoahNMethod::gc_data(nm);
241 assert(snm != nullptr, "Sanity");
242 snm->oops_do(_oops, false /*fix_relocations*/);
243 }
244 };
245
246 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
247 // Must use _claim_other to avoid interfering with concurrent CLDG iteration
248 CLDToOopClosure clds(oops, ClassLoaderData::_claim_other);
249 ShenandoahMarkNMethodClosure code(oops);
250 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, nullptr);
251
252 ResourceMark rm;
253
254 // Process light-weight/limited parallel roots then
255 _vm_roots.oops_do(oops, 0);
256 _weak_roots.oops_do<OopClosure>(oops, 0);
257 _cld_roots.cld_do(&clds, 0);
258
259 // Process heavy-weight/fully parallel roots the last
260 _code_roots.nmethods_do(&code, 0);
261 _thread_roots.threads_do(&tc_cl, 0);
262 }
|
182 ShenandoahRootProcessor(phase),
183 _vm_roots(phase),
184 _cld_roots(phase, n_workers, false /*heap iteration*/),
185 _thread_roots(phase, n_workers > 1),
186 _weak_roots(phase),
187 _code_roots(phase) {
188 }
189
190 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
191 ShenandoahRootProcessor(phase),
192 _vm_roots(phase),
193 _cld_roots(phase, n_workers, false /*heap iteration*/),
194 _thread_roots(phase, n_workers > 1),
195 _weak_roots(phase),
196 _code_roots(phase) {
197 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
198 }
199
200 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
201 NMethodToOopClosure code_blob_cl(oops, NMethodToOopClosure::FixRelocations);
202 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
203
204 // Process light-weight/limited parallel roots then
205 _vm_roots.oops_do(oops, worker_id);
206 _weak_roots.oops_do<OopClosure>(oops, worker_id);
207 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
208
209 // Process heavy-weight/fully parallel roots the last
210 _code_roots.nmethods_do(&code_blob_cl, worker_id);
211 _thread_roots.oops_do(oops, nullptr, worker_id);
212 }
213
214 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner(uint n_workers) :
215 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
216 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
217 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
218 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, n_workers, true /*heap iteration*/),
219 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
220 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
221 }
222
223 class ShenandoahMarkNMethodClosure : public NMethodClosure {
224 private:
225 OopClosure* const _oops;
226 BarrierSetNMethod* const _bs_nm;
227
228 public:
229 ShenandoahMarkNMethodClosure(OopClosure* oops) :
230 _oops(oops),
231 _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
232
233 virtual void do_nmethod(nmethod* nm) {
234 assert(nm != nullptr, "Sanity");
235 if (_bs_nm != nullptr) {
236 // Make sure it only sees to-space objects
237 _bs_nm->nmethod_entry_barrier(nm);
238 }
239 ShenandoahNMethod* const snm = ShenandoahNMethod::gc_data(nm);
240 assert(snm != nullptr, "Sanity");
241 snm->oops_do(_oops, /* fix_relocations = */ false, /* icic = */ nullptr);
242 }
243 };
244
245 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
246 // Must use _claim_other to avoid interfering with concurrent CLDG iteration
247 CLDToOopClosure clds(oops, ClassLoaderData::_claim_other);
248 ShenandoahMarkNMethodClosure code(oops);
249 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, nullptr);
250
251 ResourceMark rm;
252
253 // Process light-weight/limited parallel roots then
254 _vm_roots.oops_do(oops, 0);
255 _weak_roots.oops_do<OopClosure>(oops, 0);
256 _cld_roots.cld_do(&clds, 0);
257
258 // Process heavy-weight/fully parallel roots the last
259 _code_roots.nmethods_do(&code, 0);
260 _thread_roots.threads_do(&tc_cl, 0);
261 }
|