8379404: G1: Hide ConcurrentMarkThread reference from outside ConcurrentMark

Reviewed-by: stefank, iwalulya
This commit is contained in:
Thomas Schatzl 2026-03-09 09:14:56 +00:00
parent d6943c532e
commit 7101a0507c
4 changed files with 42 additions and 26 deletions

View File

@ -1652,21 +1652,13 @@ jint G1CollectedHeap::initialize() {
return JNI_OK;
}
bool G1CollectedHeap::concurrent_mark_is_terminating() const {
assert(_cm != nullptr, "_cm must have been created");
assert(_cm->is_fully_initialized(), "thread must exist in order to check if mark is terminating");
return _cm->cm_thread()->should_terminate();
}
void G1CollectedHeap::stop() {
// Stop all concurrent threads. We do this to make sure these threads
// do not continue to execute and access resources (e.g. logging)
// that are destroyed during shutdown.
_cr->stop();
_service_thread->stop();
if (_cm->is_fully_initialized()) {
_cm->cm_thread()->stop();
}
_cm->stop();
}
void G1CollectedHeap::safepoint_synchronize_begin() {
@ -1857,12 +1849,12 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent,
record_whole_heap_examined_timestamp();
}
// We need to clear the "in_progress" flag in the CM thread before
// We need to tell G1ConcurrentMark to update the state before
// we wake up any waiters (especially when ExplicitInvokesConcurrent
// is set) so that if a waiter requests another System.gc() it doesn't
// incorrectly see that a marking cycle is still in progress.
if (concurrent) {
_cm->cm_thread()->set_idle();
_cm->notify_concurrent_cycle_completed();
}
// Notify threads waiting in System.gc() (with ExplicitGCInvokesConcurrent)
@ -2565,11 +2557,9 @@ void G1CollectedHeap::start_concurrent_cycle(bool concurrent_operation_is_full_m
assert(!_cm->in_progress(), "Can not start concurrent operation while in progress");
MutexLocker x(G1CGC_lock, Mutex::_no_safepoint_check_flag);
if (concurrent_operation_is_full_mark) {
_cm->post_concurrent_mark_start();
_cm->cm_thread()->start_full_mark();
_cm->start_full_concurrent_cycle();
} else {
_cm->post_concurrent_undo_start();
_cm->cm_thread()->start_undo_mark();
_cm->start_undo_concurrent_cycle();
}
G1CGC_lock->notify();
}

View File

@ -915,9 +915,6 @@ public:
// specified by the policy object.
jint initialize() override;
// Returns whether concurrent mark threads (and the VM) are about to terminate.
bool concurrent_mark_is_terminating() const;
void safepoint_synchronize_begin() override;
void safepoint_synchronize_end() override;

View File

@ -581,6 +581,11 @@ PartialArrayStateManager* G1ConcurrentMark::partial_array_state_manager() const
return _partial_array_state_manager;
}
G1ConcurrentMarkThread* G1ConcurrentMark::cm_thread() const {
assert(is_fully_initialized(), "must be");
return _cm_thread;
}
void G1ConcurrentMark::reset() {
_has_aborted.store_relaxed(false);
@ -715,7 +720,6 @@ public:
private:
// Heap region closure used for clearing the _mark_bitmap.
class G1ClearBitmapHRClosure : public G1HeapRegionClosure {
private:
G1ConcurrentMark* _cm;
G1CMBitMap* _bitmap;
bool _suspendible; // If suspendible, do yield checks.
@ -959,7 +963,7 @@ void G1ConcurrentMark::pre_concurrent_start(GCCause::Cause cause) {
_gc_tracer_cm->set_gc_cause(cause);
}
void G1ConcurrentMark::post_concurrent_mark_start() {
void G1ConcurrentMark::start_full_concurrent_cycle() {
// Start Concurrent Marking weak-reference discovery.
ReferenceProcessor* rp = _g1h->ref_processor_cm();
rp->start_discovery(false /* always_clear */);
@ -976,10 +980,26 @@ void G1ConcurrentMark::post_concurrent_mark_start() {
// when marking is on. So, it's also called at the end of the
// concurrent start pause to update the heap end, if the heap expands
// during it. No need to call it here.
// Signal the thread to start work.
cm_thread()->start_full_mark();
}
void G1ConcurrentMark::post_concurrent_undo_start() {
void G1ConcurrentMark::start_undo_concurrent_cycle() {
root_regions()->cancel_scan();
// Signal the thread to start work.
cm_thread()->start_undo_mark();
}
void G1ConcurrentMark::notify_concurrent_cycle_completed() {
cm_thread()->set_idle();
}
void G1ConcurrentMark::stop() {
if (is_fully_initialized()) {
cm_thread()->stop();
}
}
/*
@ -1943,7 +1963,7 @@ bool G1ConcurrentMark::concurrent_cycle_abort() {
// has been signalled is already rare), and this work should be negligible compared
// to actual full gc work.
if (!is_fully_initialized() || (!cm_thread()->in_progress() && !_g1h->concurrent_mark_is_terminating())) {
if (!is_fully_initialized() || (!cm_thread()->in_progress() && !cm_thread()->should_terminate())) {
return false;
}

View File

@ -352,6 +352,7 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
friend class G1CMRemarkTask;
friend class G1CMRootRegionScanTask;
friend class G1CMTask;
friend class G1ClearBitMapTask;
friend class G1ConcurrentMarkThread;
G1ConcurrentMarkThread* _cm_thread; // The thread doing the work
@ -524,6 +525,9 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
Atomic<HeapWord*>* _top_at_rebuild_starts;
// True when Remark pause selected regions for rebuilding.
bool _needs_remembered_set_rebuild;
G1ConcurrentMarkThread* cm_thread() const;
public:
// To be called when an object is marked the first time, e.g. after a successful
// mark_in_bitmap call. Updates various statistics data.
@ -602,8 +606,6 @@ public:
G1RegionToSpaceMapper* bitmap_storage);
~G1ConcurrentMark();
G1ConcurrentMarkThread* cm_thread() { return _cm_thread; }
G1CMBitMap* mark_bitmap() const { return (G1CMBitMap*)&_mark_bitmap; }
// Calculates the number of concurrent GC threads to be used in the marking phase.
@ -632,8 +634,15 @@ public:
// These two methods do the work that needs to be done at the start and end of the
// concurrent start pause.
void pre_concurrent_start(GCCause::Cause cause);
void post_concurrent_mark_start();
void post_concurrent_undo_start();
// Start the particular type of concurrent cycle. After this call threads may be running.
void start_full_concurrent_cycle();
void start_undo_concurrent_cycle();
void notify_concurrent_cycle_completed();
// Stop active components/the concurrent mark thread.
void stop();
// Scan all the root regions and mark everything reachable from
// them.