< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp
Print this page
rev 47986 : Fix/improve traversal CLD processing
@@ -93,10 +93,35 @@
JavaThread::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(_satb_cl);
}
}
};
+// Like CLDToOopClosure, but clears has_modified_oops, so that we can record modified CLDs during traversal
+// and remark them later during final-traversal.
+class ShenandoahMarkCLDClosure : public CLDClosure {
+private:
+ OopClosure* _cl;
+public:
+ ShenandoahMarkCLDClosure(OopClosure* cl) : _cl(cl) {}
+ void do_cld(ClassLoaderData* cld) {
+ cld->oops_do(_cl, true, true);
+ }
+};
+
+// Like CLDToOopClosure, but only process modified CLDs
+class ShenandoahRemarkCLDClosure : public CLDClosure {
+private:
+ OopClosure* _cl;
+public:
+ ShenandoahRemarkCLDClosure(OopClosure* cl) : _cl(cl) {}
+ void do_cld(ClassLoaderData* cld) {
+ if (cld->has_modified_oops()) {
+ cld->oops_do(_cl, true, true);
+ }
+ }
+};
+
class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
private:
ShenandoahRootProcessor* _rp;
ShenandoahHeap* _heap;
public:
@@ -121,14 +146,14 @@
}
// Step 1: Process ordinary GC roots.
{
ShenandoahTraversalClosure roots_cl(q, rp);
- CLDToOopClosure cld_cl(&roots_cl);
+ ShenandoahMarkCLDClosure cld_cl(&roots_cl);
MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
if (unload_classes) {
- _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, NULL, worker_id);
+ _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, NULL, &code_cl, NULL, worker_id);
} else {
_rp->process_all_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, NULL, worker_id);
}
}
}
@@ -194,11 +219,12 @@
ShenandoahTraversalClosure roots_cl(q, rp);
CLDToOopClosure cld_cl(&roots_cl);
MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
ShenandoahTraversalSATBThreadsClosure tc(&satb_cl);
if (unload_classes) {
- _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, &tc, worker_id);
+ ShenandoahRemarkCLDClosure weak_cld_cl(&roots_cl);
+ _rp->process_strong_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &weak_cld_cl, &code_cl, &tc, worker_id);
} else {
_rp->process_all_roots(&roots_cl, process_refs ? NULL : &roots_cl, &cld_cl, &code_cl, &tc, worker_id);
}
}
@@ -466,22 +492,10 @@
_task_queues->clear();
}
assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
}
-class ShenandoahRemarkCLDClosure : public CLDClosure {
-private:
- OopClosure* _cl;
-public:
- ShenandoahRemarkCLDClosure(OopClosure* cl) : _cl(cl) {}
- void do_cld(ClassLoaderData* cld) {
- if (cld->has_modified_oops()) {
- cld->oops_do(_cl, false, true);
- }
- }
-};
-
void ShenandoahTraversalGC::final_traversal_collection() {
_heap->make_tlabs_parsable(true);
if (!_heap->cancelled_concgc()) {
@@ -490,22 +504,10 @@
#endif
ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
uint nworkers = _heap->workers()->active_workers();
task_queues()->reserve(nworkers);
- {
- bool process_refs = _heap->shenandoahPolicy()->process_references();
- ReferenceProcessor* rp = NULL;
- if (process_refs) {
- rp = _heap->ref_processor();
- }
-
- ShenandoahTraversalClosure roots_cl(task_queues()->queue(0), rp);
- ShenandoahRemarkCLDClosure remark_clds(&roots_cl);
- ClassLoaderDataGraph::cld_do(&remark_clds);
- }
-
// Finish traversal
ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
if (UseShenandoahOWST) {
ShenandoahTaskTerminator terminator(nworkers, task_queues());
ShenandoahFinalTraversalCollectionTask traversal_task(&rp, &terminator);
< prev index next >