8297487: G1 Remark: no need to keep alive oop constants of nmethods on stack

Reviewed-by: tschatzl, ayang, eosterlund
This commit is contained in:
Richard Reingruber 2023-01-10 10:32:32 +00:00
parent c8a8388aba
commit eab1e6260d
2 changed files with 3 additions and 15 deletions

View File

@ -1779,30 +1779,17 @@ public:
class G1RemarkThreadsClosure : public ThreadClosure {
G1SATBMarkQueueSet& _qset;
G1CMOopClosure _cm_cl;
MarkingCodeBlobClosure _code_cl;
uintx _claim_token;
public:
G1RemarkThreadsClosure(G1CollectedHeap* g1h, G1CMTask* task) :
_qset(G1BarrierSet::satb_mark_queue_set()),
_cm_cl(g1h, task),
_code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations, true /* keepalive nmethods */),
_claim_token(Threads::thread_claim_token()) {}
void do_thread(Thread* thread) {
if (thread->claim_threads_do(true, _claim_token)) {
// Transfer any partial buffer to the qset for completed buffer processing.
_qset.flush_queue(G1ThreadLocalData::satb_mark_queue(thread));
if (thread->is_Java_thread()) {
// In theory it should not be necessary to explicitly walk the nmethods to find roots for concurrent marking
// however the liveness of oops reachable from nmethods have very complex lifecycles:
// * Alive if on the stack of an executing method
// * Weakly reachable otherwise
// Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
// live by the SATB invariant but other oops recorded in nmethods may behave differently.
JavaThread::cast(thread)->nmethods_do(&_code_cl);
}
}
}
};

View File

@ -57,8 +57,9 @@ static BarrierSetNMethod* select_barrier_set_nmethod(BarrierSetNMethod* barrier_
// The GC needs nmethod entry barriers to do concurrent GC
return barrier_set_nmethod;
} else {
// The GC needs nmethod entry barriers to deal with continuations
// and code cache unloading
// The GC needs nmethod entry barriers for code cache unloading (recently
// used heuristics) and, if it's a SATB GC, to keep alive constant objects
// of nmethods because they are weakly referenced.
return new BarrierSetNMethod();
}
}