259 TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
260 task_queues()->reserve(nworkers);
261
262 if (heap->has_forwarded_objects()) {
263 ShenandoahInitMarkRootsTask<RESOLVE> mark_roots(&root_proc, _heap->process_references());
264 workers->run_task(&mark_roots);
265 } else {
266 // No need to update references, which means the heap is stable.
267 // Can save time not walking through forwarding pointers.
268 ShenandoahInitMarkRootsTask<NONE> mark_roots(&root_proc, _heap->process_references());
269 workers->run_task(&mark_roots);
270 }
271
272 if (ShenandoahConcurrentScanCodeRoots) {
273 clear_claim_codecache();
274 }
275 }
276
277 void ShenandoahConcurrentMark::update_roots(ShenandoahPhaseTimings::Phase root_phase) {
278 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
279
280 bool update_code_cache = true; // initialize to safer value
281 switch (root_phase) {
282 case ShenandoahPhaseTimings::update_roots:
283 case ShenandoahPhaseTimings::final_update_refs_roots:
284 update_code_cache = false;
285 break;
286 case ShenandoahPhaseTimings::full_gc_roots:
287 case ShenandoahPhaseTimings::degen_gc_update_roots:
288 update_code_cache = true;
289 break;
290 default:
291 ShouldNotReachHere();
292 }
293
294 ShenandoahGCPhase phase(root_phase);
295
296 #if COMPILER2_OR_JVMCI
297 DerivedPointerTable::clear();
298 #endif
299
300 uint nworkers = _heap->workers()->active_workers();
301
302 ShenandoahRootUpdater root_updater(nworkers, root_phase, update_code_cache);
303 ShenandoahUpdateRootsTask update_roots(&root_updater);
304 _heap->workers()->run_task(&update_roots);
305
306 #if COMPILER2_OR_JVMCI
307 DerivedPointerTable::update_pointers();
308 #endif
309 }
310
311 class ShenandoahUpdateThreadRootsTask : public AbstractGangTask {
312 private:
313 ShenandoahThreadRoots _thread_roots;
314 ShenandoahPhaseTimings::Phase _phase;
315 public:
316 ShenandoahUpdateThreadRootsTask(bool is_par, ShenandoahPhaseTimings::Phase phase) :
317 AbstractGangTask("Shenandoah Update Thread Roots"),
318 _thread_roots(is_par),
319 _phase(phase) {
320 ShenandoahHeap::heap()->phase_timings()->record_workers_start(_phase);
321 }
322
|
259 TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
260 task_queues()->reserve(nworkers);
261
262 if (heap->has_forwarded_objects()) {
263 ShenandoahInitMarkRootsTask<RESOLVE> mark_roots(&root_proc, _heap->process_references());
264 workers->run_task(&mark_roots);
265 } else {
266 // No need to update references, which means the heap is stable.
267 // Can save time not walking through forwarding pointers.
268 ShenandoahInitMarkRootsTask<NONE> mark_roots(&root_proc, _heap->process_references());
269 workers->run_task(&mark_roots);
270 }
271
272 if (ShenandoahConcurrentScanCodeRoots) {
273 clear_claim_codecache();
274 }
275 }
276
277 void ShenandoahConcurrentMark::update_roots(ShenandoahPhaseTimings::Phase root_phase) {
278 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
279 assert(root_phase == ShenandoahPhaseTimings::full_gc_roots ||
280 root_phase == ShenandoahPhaseTimings::degen_gc_update_roots,
281 "Only for these phases");
282
283 ShenandoahGCPhase phase(root_phase);
284
285 #if COMPILER2_OR_JVMCI
286 DerivedPointerTable::clear();
287 #endif
288
289 uint nworkers = _heap->workers()->active_workers();
290
291 ShenandoahRootUpdater root_updater(nworkers, root_phase);
292 ShenandoahUpdateRootsTask update_roots(&root_updater);
293 _heap->workers()->run_task(&update_roots);
294
295 #if COMPILER2_OR_JVMCI
296 DerivedPointerTable::update_pointers();
297 #endif
298 }
299
300 class ShenandoahUpdateThreadRootsTask : public AbstractGangTask {
301 private:
302 ShenandoahThreadRoots _thread_roots;
303 ShenandoahPhaseTimings::Phase _phase;
304 public:
305 ShenandoahUpdateThreadRootsTask(bool is_par, ShenandoahPhaseTimings::Phase phase) :
306 AbstractGangTask("Shenandoah Update Thread Roots"),
307 _thread_roots(is_par),
308 _phase(phase) {
309 ShenandoahHeap::heap()->phase_timings()->record_workers_start(_phase);
310 }
311
|