@@ -78,16 +78,17 @@ typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
7878typedef PSRootsClosure</* promote_immediately=*/ true > PSPromoteRootsClosure;
7979
8080// Scavenges a single oop in a ClassLoaderData.
81- class PSScavengeFromCLDClosure : public OopClosure {
82- private:
81+ class PSScavengeCLDOopClosure : public OopClosure {
8382 PSPromotionManager* _pm;
84- // Used to redirty a scanned cld if it has oops
85- // pointing to the young generation after being scanned.
86- ClassLoaderData* _scanned_cld;
83+
8784public:
88- PSScavengeFromCLDClosure (PSPromotionManager* pm) : _pm(pm), _scanned_cld(nullptr ) { }
85+ // Records whether this CLD contains oops pointing into young-gen after scavenging.
86+ bool _has_oops_into_young_gen;
87+
88+ PSScavengeCLDOopClosure (PSPromotionManager* pm) : _pm(pm), _has_oops_into_young_gen(false ) {}
89+
8990 void do_oop (narrowOop* p) { ShouldNotReachHere (); }
90- void do_oop (oop* p) {
91+ void do_oop (oop* p) {
9192 ParallelScavengeHeap* psh = ParallelScavengeHeap::heap ();
9293 assert (!psh->is_in_reserved (p), " GC barrier needed" );
9394 if (PSScavenge::should_scavenge (p)) {
@@ -97,43 +98,33 @@ class PSScavengeFromCLDClosure: public OopClosure {
9798 oop new_obj = _pm->copy_to_survivor_space </* promote_immediately=*/ false >(o);
9899 RawAccess<IS_NOT_NULL>::oop_store (p, new_obj);
99100
100- if (PSScavenge::is_obj_in_young (new_obj)) {
101- do_cld_barrier () ;
101+ if (PSScavenge::is_obj_in_young (new_obj) && !_has_oops_into_young_gen ) {
102+ _has_oops_into_young_gen = true ;
102103 }
103104 }
104105 }
105-
106- void set_scanned_cld (ClassLoaderData* cld) {
107- assert (_scanned_cld == nullptr || cld == nullptr , " Should always only handling one cld at a time" );
108- _scanned_cld = cld;
109- }
110-
111- private:
112- void do_cld_barrier () {
113- assert (_scanned_cld != nullptr , " Should not be called without having a scanned cld" );
114- _scanned_cld->record_modified_oops ();
115- }
116106};
117107
118108// Scavenges the oop in a ClassLoaderData.
119109class PSScavengeCLDClosure : public CLDClosure {
120- private:
121- PSScavengeFromCLDClosure _oop_closure;
110+ PSPromotionManager* _pm;
111+
122112public:
123- PSScavengeCLDClosure (PSPromotionManager* pm) : _oop_closure(pm) { }
124- void do_cld (ClassLoaderData* cld) {
125- // If the cld has not been dirtied we know that there's
126- // no references into the young gen and we can skip it.
113+ PSScavengeCLDClosure (PSPromotionManager* pm) : _pm(pm) { }
127114
128- if (cld->has_modified_oops ()) {
129- // Setup the promotion manager to redirty this cld
130- // if references are left in the young gen.
131- _oop_closure.set_scanned_cld (cld);
115+ void do_cld (ClassLoaderData* cld) {
116+ // If the cld has not been dirtied we know that there are
117+ // no references into the young gen, so we can skip it.
118+ if (!cld->has_modified_oops ()) {
119+ return ;
120+ }
132121
133- // Clean the cld since we're going to scavenge all the metadata.
134- cld->oops_do (&_oop_closure, ClassLoaderData::_claim_none, /* clear_modified_oops*/ true );
122+ PSScavengeCLDOopClosure oop_closure{_pm};
123+ // Clean the cld since we're going to scavenge all the metadata.
124+ cld->oops_do (&oop_closure, ClassLoaderData::_claim_none, /* clear_modified_oops*/ true );
135125
136- _oop_closure.set_scanned_cld (nullptr );
126+ if (oop_closure._has_oops_into_young_gen ) {
127+ cld->record_modified_oops ();
137128 }
138129 }
139130};
0 commit comments