From fe102918dd4f33ba030c4c4301a676ac8497fd90 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 20 Jan 2026 10:34:16 +0000 Subject: [PATCH] 8375630: G1: Convert G1ConcurrentMark to use Atomic Reviewed-by: kbarrett, shade --- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 27 ++++++++++---------- src/hotspot/share/gc/g1/g1ConcurrentMark.hpp | 9 ++++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 456d543fa10..1077939f953 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,6 @@ #include "nmt/memTracker.hpp" #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomicAccess.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" @@ -148,25 +147,25 @@ bool G1CMMarkStack::initialize() { } G1CMMarkStack::TaskQueueEntryChunk* G1CMMarkStack::ChunkAllocator::allocate_new_chunk() { - if (_size >= _max_capacity) { + if (_size.load_relaxed() >= _max_capacity) { return nullptr; } - size_t cur_idx = AtomicAccess::fetch_then_add(&_size, 1u); + size_t cur_idx = _size.fetch_then_add(1u); if (cur_idx >= _max_capacity) { return nullptr; } size_t bucket = get_bucket(cur_idx); - if (AtomicAccess::load_acquire(&_buckets[bucket]) == nullptr) { + if (_buckets[bucket].load_acquire() == nullptr) { if (!_should_grow) { // Prefer to restart the CM. return nullptr; } MutexLocker x(G1MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag); - if (AtomicAccess::load_acquire(&_buckets[bucket]) == nullptr) { + if (_buckets[bucket].load_acquire() == nullptr) { size_t desired_capacity = bucket_size(bucket) * 2; if (!try_expand_to(desired_capacity)) { return nullptr; @@ -175,7 +174,7 @@ G1CMMarkStack::TaskQueueEntryChunk* G1CMMarkStack::ChunkAllocator::allocate_new_ } size_t bucket_idx = get_bucket_index(cur_idx); - TaskQueueEntryChunk* result = ::new (&_buckets[bucket][bucket_idx]) TaskQueueEntryChunk; + TaskQueueEntryChunk* result = ::new (&_buckets[bucket].load_relaxed()[bucket_idx]) TaskQueueEntryChunk; result->next = nullptr; return result; } @@ -197,10 +196,10 @@ bool G1CMMarkStack::ChunkAllocator::initialize(size_t initial_capacity, size_t m _max_capacity = max_capacity; _num_buckets = get_bucket(_max_capacity) + 1; - _buckets = NEW_C_HEAP_ARRAY(TaskQueueEntryChunk*, _num_buckets, mtGC); + _buckets = NEW_C_HEAP_ARRAY(Atomic, _num_buckets, mtGC); for (size_t i = 0; i < _num_buckets; i++) { - _buckets[i] = nullptr; + _buckets[i].store_relaxed(nullptr); } size_t new_capacity = bucket_size(0); @@ -240,9 +239,9 @@ G1CMMarkStack::ChunkAllocator::~ChunkAllocator() { } for (size_t i = 0; i < _num_buckets; i++) { - if (_buckets[i] != nullptr) { - MmapArrayAllocator::free(_buckets[i], bucket_size(i)); - _buckets[i] = nullptr; + if (_buckets[i].load_relaxed() != nullptr) { + MmapArrayAllocator::free(_buckets[i].load_relaxed(), bucket_size(i)); + _buckets[i].store_relaxed(nullptr); } } @@ -259,7 +258,7 @@ bool G1CMMarkStack::ChunkAllocator::reserve(size_t new_capacity) { // and the new capacity (new_capacity). This step ensures that there are no gaps in the // array and that the capacity accurately reflects the reserved memory. for (; i <= highest_bucket; i++) { - if (AtomicAccess::load_acquire(&_buckets[i]) != nullptr) { + if (_buckets[i].load_acquire() != nullptr) { continue; // Skip over already allocated buckets. } @@ -279,7 +278,7 @@ bool G1CMMarkStack::ChunkAllocator::reserve(size_t new_capacity) { return false; } _capacity += bucket_capacity; - AtomicAccess::release_store(&_buckets[i], bucket_base); + _buckets[i].release_store(bucket_base); } return true; } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 752082ce629..1a0cfcd8caa 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ #include "gc/shared/workerThread.hpp" #include "gc/shared/workerUtils.hpp" #include "memory/allocation.hpp" +#include "runtime/atomic.hpp" #include "utilities/compilerWarnings.hpp" #include "utilities/numberSeq.hpp" @@ -172,9 +173,9 @@ private: size_t _capacity; size_t _num_buckets; bool _should_grow; - TaskQueueEntryChunk* volatile* _buckets; + Atomic* _buckets; char _pad0[DEFAULT_PADDING_SIZE]; - volatile size_t _size; + Atomic _size; char _pad4[DEFAULT_PADDING_SIZE - sizeof(size_t)]; size_t bucket_size(size_t bucket) { @@ -212,7 +213,7 @@ private: bool initialize(size_t initial_capacity, size_t max_capacity); void reset() { - _size = 0; + _size.store_relaxed(0); _should_grow = false; }