153 if (cld->has_modified_oops()) {
154 cld->oops_do(_cl, true, true);
155 }
156 }
157 };
158
159 class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
160 private:
161 ShenandoahRootProcessor* _rp;
162 ShenandoahHeap* _heap;
163 public:
164 ShenandoahInitTraversalCollectionTask(ShenandoahRootProcessor* rp) :
165 AbstractGangTask("Shenandoah Init Traversal Collection"),
166 _rp(rp),
167 _heap(ShenandoahHeap::heap()) {}
168
169 void work(uint worker_id) {
170 ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues();
171 ShenandoahObjToScanQueue* q = queues->queue(worker_id);
172
173 // Initialize live data.
174 jushort* ld = _heap->traversal_gc()->get_liveness(worker_id);
175 Copy::fill_to_bytes(ld, _heap->num_regions() * sizeof(jushort));
176
177 bool process_refs = _heap->shenandoahPolicy()->process_references();
178 bool unload_classes = _heap->shenandoahPolicy()->unload_classes();
179 ReferenceProcessor* rp = NULL;
180 if (process_refs) {
181 rp = _heap->ref_processor();
182 }
183
184 // Step 1: Process ordinary GC roots.
185 {
186 ShenandoahTraversalClosure roots_cl(q, rp);
187 ShenandoahMarkCLDClosure cld_cl(&roots_cl);
188 MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
189 if (unload_classes) {
190 _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, NULL, &code_cl, NULL, worker_id);
191 } else {
192 _rp->process_all_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, NULL, worker_id);
193 }
194 }
195 }
196 };
338 }
339 }
340
341 log_info(gc,ergo)("Got "SIZE_FORMAT" collection set regions", collection_set->count());
342 }
343
344 void ShenandoahTraversalGC::init_traversal_collection() {
345 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC");
346
347 if (ShenandoahVerify) {
348 _heap->verifier()->verify_before_traversal();
349 }
350
351 {
352 ShenandoahGCPhase phase_prepare(ShenandoahPhaseTimings::traversal_gc_prepare);
353 ShenandoahHeapLocker lock(_heap->lock());
354 prepare();
355 }
356
357 _heap->set_concurrent_traversal_in_progress(true);
358
359 bool process_refs = _heap->shenandoahPolicy()->process_references();
360 if (process_refs) {
361 ReferenceProcessor* rp = _heap->ref_processor();
362 rp->enable_discovery(true /*verify_no_refs*/);
363 rp->setup_policy(false);
364 }
365
366 {
367 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work);
368 assert(_task_queues->is_empty(), "queues must be empty before traversal GC");
369
370 #if defined(COMPILER2) || INCLUDE_JVMCI
371 DerivedPointerTable::clear();
372 #endif
373
374 {
375 uint nworkers = _heap->workers()->active_workers();
376 task_queues()->reserve(nworkers);
377 ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
|
153 if (cld->has_modified_oops()) {
154 cld->oops_do(_cl, true, true);
155 }
156 }
157 };
158
159 class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
160 private:
161 ShenandoahRootProcessor* _rp;
162 ShenandoahHeap* _heap;
163 public:
164 ShenandoahInitTraversalCollectionTask(ShenandoahRootProcessor* rp) :
165 AbstractGangTask("Shenandoah Init Traversal Collection"),
166 _rp(rp),
167 _heap(ShenandoahHeap::heap()) {}
168
169 void work(uint worker_id) {
170 ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues();
171 ShenandoahObjToScanQueue* q = queues->queue(worker_id);
172
173 bool process_refs = _heap->shenandoahPolicy()->process_references();
174 bool unload_classes = _heap->shenandoahPolicy()->unload_classes();
175 ReferenceProcessor* rp = NULL;
176 if (process_refs) {
177 rp = _heap->ref_processor();
178 }
179
180 // Step 1: Process ordinary GC roots.
181 {
182 ShenandoahTraversalClosure roots_cl(q, rp);
183 ShenandoahMarkCLDClosure cld_cl(&roots_cl);
184 MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
185 if (unload_classes) {
186 _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, NULL, &code_cl, NULL, worker_id);
187 } else {
188 _rp->process_all_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, NULL, worker_id);
189 }
190 }
191 }
192 };
334 }
335 }
336
337 log_info(gc,ergo)("Got "SIZE_FORMAT" collection set regions", collection_set->count());
338 }
339
340 void ShenandoahTraversalGC::init_traversal_collection() {
341 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC");
342
343 if (ShenandoahVerify) {
344 _heap->verifier()->verify_before_traversal();
345 }
346
347 {
348 ShenandoahGCPhase phase_prepare(ShenandoahPhaseTimings::traversal_gc_prepare);
349 ShenandoahHeapLocker lock(_heap->lock());
350 prepare();
351 }
352
353 _heap->set_concurrent_traversal_in_progress(true);
354
355 // Initialize liveness arrays.
356 for (uint worker_id = 0; worker_id < _heap->max_workers(); worker_id++) {
357 jushort* ld = get_liveness(worker_id);
358 Copy::fill_to_bytes(ld, _heap->num_regions() * sizeof(jushort));
359 }
360
361 bool process_refs = _heap->shenandoahPolicy()->process_references();
362 if (process_refs) {
363 ReferenceProcessor* rp = _heap->ref_processor();
364 rp->enable_discovery(true /*verify_no_refs*/);
365 rp->setup_policy(false);
366 }
367
368 {
369 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work);
370 assert(_task_queues->is_empty(), "queues must be empty before traversal GC");
371
372 #if defined(COMPILER2) || INCLUDE_JVMCI
373 DerivedPointerTable::clear();
374 #endif
375
376 {
377 uint nworkers = _heap->workers()->active_workers();
378 task_queues()->reserve(nworkers);
379 ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
|