8377043: Shenandoah: Convert ShenandoahHeapRegion related code to use Atomic<T>

Reviewed-by: xpeng, cslucas, kdnilsen, wkemper
This commit is contained in:
Ben Taylor 2026-02-09 20:00:51 +00:00 committed by Xiaolong Peng
parent 161aa5d528
commit 57eb9c79b0
4 changed files with 35 additions and 35 deletions

View File

@ -43,7 +43,6 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
@ -384,7 +383,7 @@ size_t ShenandoahHeapRegion::get_plab_allocs() const {
void ShenandoahHeapRegion::set_live_data(size_t s) {
assert(Thread::current()->is_VM_thread(), "by VM thread");
_live_data = (s >> LogHeapWordSize);
_live_data.store_relaxed(s >> LogHeapWordSize);
}
void ShenandoahHeapRegion::print_on(outputStream* st) const {
@ -435,7 +434,7 @@ void ShenandoahHeapRegion::print_on(outputStream* st) const {
st->print("|TAMS " SHR_PTR_FORMAT,
p2i(ShenandoahHeap::heap()->marking_context()->top_at_mark_start(const_cast<ShenandoahHeapRegion*>(this))));
st->print("|UWM " SHR_PTR_FORMAT,
p2i(_update_watermark));
p2i(_update_watermark.load_relaxed()));
st->print("|U %5zu%1s", byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used()));
st->print("|T %5zu%1s", byte_size_in_proper_unit(get_tlab_allocs()), proper_unit_for_byte_size(get_tlab_allocs()));
st->print("|G %5zu%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs()));
@ -839,20 +838,20 @@ void ShenandoahHeapRegion::set_state(RegionState to) {
evt.set_to(to);
evt.commit();
}
AtomicAccess::store(&_state, to);
_state.store_relaxed(to);
}
void ShenandoahHeapRegion::record_pin() {
AtomicAccess::add(&_critical_pins, (size_t)1);
_critical_pins.add_then_fetch((size_t)1);
}
void ShenandoahHeapRegion::record_unpin() {
assert(pin_count() > 0, "Region %zu should have non-zero pins", index());
AtomicAccess::sub(&_critical_pins, (size_t)1);
_critical_pins.sub_then_fetch((size_t)1);
}
size_t ShenandoahHeapRegion::pin_count() const {
return AtomicAccess::load(&_critical_pins);
return _critical_pins.load_relaxed();
}
void ShenandoahHeapRegion::set_affiliation(ShenandoahAffiliation new_affiliation) {
@ -864,7 +863,7 @@ void ShenandoahHeapRegion::set_affiliation(ShenandoahAffiliation new_affiliation
log_debug(gc)("Setting affiliation of Region %zu from %s to %s, top: " PTR_FORMAT ", TAMS: " PTR_FORMAT
", watermark: " PTR_FORMAT ", top_bitmap: " PTR_FORMAT,
index(), shenandoah_affiliation_name(region_affiliation), shenandoah_affiliation_name(new_affiliation),
p2i(top()), p2i(ctx->top_at_mark_start(this)), p2i(_update_watermark), p2i(ctx->top_bitmap(this)));
p2i(top()), p2i(ctx->top_at_mark_start(this)), p2i(_update_watermark.load_relaxed()), p2i(ctx->top_bitmap(this)));
}
#ifdef ASSERT

View File

@ -34,6 +34,7 @@
#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahPadding.hpp"
#include "runtime/atomic.hpp"
#include "utilities/sizes.hpp"
class VMStructs;
@ -217,7 +218,7 @@ public:
bool is_alloc_allowed() const { auto cur_state = state(); return is_empty_state(cur_state) || cur_state == _regular || cur_state == _pinned; }
bool is_stw_move_allowed() const { auto cur_state = state(); return cur_state == _regular || cur_state == _cset || (ShenandoahHumongousMoves && cur_state == _humongous_start); }
RegionState state() const { return AtomicAccess::load(&_state); }
RegionState state() const { return _state.load_relaxed(); }
int state_ordinal() const { return region_state_to_ordinal(state()); }
void record_pin();
@ -247,7 +248,7 @@ private:
HeapWord* _top_before_promoted;
// Seldom updated fields
volatile RegionState _state;
Atomic<RegionState> _state;
HeapWord* _coalesce_and_fill_boundary; // for old regions not selected as collection set candidates.
// Frequently updated fields
@ -257,12 +258,12 @@ private:
size_t _gclab_allocs;
size_t _plab_allocs;
volatile size_t _live_data;
volatile size_t _critical_pins;
Atomic<size_t> _live_data;
Atomic<size_t> _critical_pins;
size_t _mixed_candidate_garbage_words;
HeapWord* volatile _update_watermark;
Atomic<HeapWord*> _update_watermark;
uint _age;
bool _promoted_in_place;

View File

@ -32,7 +32,6 @@
#include "gc/shenandoah/shenandoahGenerationalHeap.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahOldGeneration.hpp"
#include "runtime/atomicAccess.hpp"
HeapWord* ShenandoahHeapRegion::allocate_aligned(size_t size, ShenandoahAllocRequest &req, size_t alignment_in_bytes) {
shenandoah_assert_heaplocked_or_safepoint();
@ -147,16 +146,16 @@ inline void ShenandoahHeapRegion::increase_live_data_gc_words(size_t s) {
}
inline void ShenandoahHeapRegion::internal_increase_live_data(size_t s) {
AtomicAccess::add(&_live_data, s, memory_order_relaxed);
_live_data.add_then_fetch(s, memory_order_relaxed);
}
inline void ShenandoahHeapRegion::clear_live_data() {
AtomicAccess::store(&_live_data, (size_t)0);
_live_data.store_relaxed((size_t)0);
_promoted_in_place = false;
}
inline size_t ShenandoahHeapRegion::get_live_data_words() const {
return AtomicAccess::load(&_live_data);
return _live_data.load_relaxed();
}
inline size_t ShenandoahHeapRegion::get_live_data_bytes() const {
@ -205,21 +204,21 @@ inline size_t ShenandoahHeapRegion::garbage_before_padded_for_promote() const {
}
inline HeapWord* ShenandoahHeapRegion::get_update_watermark() const {
HeapWord* watermark = AtomicAccess::load_acquire(&_update_watermark);
HeapWord* watermark = _update_watermark.load_acquire();
assert(bottom() <= watermark && watermark <= top(), "within bounds");
return watermark;
}
inline void ShenandoahHeapRegion::set_update_watermark(HeapWord* w) {
assert(bottom() <= w && w <= top(), "within bounds");
AtomicAccess::release_store(&_update_watermark, w);
_update_watermark.release_store(w);
}
// Fast version that avoids synchronization, only to be used at safepoints.
inline void ShenandoahHeapRegion::set_update_watermark_at_safepoint(HeapWord* w) {
assert(bottom() <= w && w <= top(), "within bounds");
assert(SafepointSynchronize::is_at_safepoint(), "Should be at Shenandoah safepoint");
_update_watermark = w;
_update_watermark.store_relaxed(w);
}
inline ShenandoahAffiliation ShenandoahHeapRegion::affiliation() const {

View File

@ -29,21 +29,22 @@
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
#include "runtime/atomic.hpp"
#define VM_STRUCTS_SHENANDOAH(nonstatic_field, volatile_nonstatic_field, static_field) \
nonstatic_field(ShenandoahHeap, _num_regions, size_t) \
nonstatic_field(ShenandoahHeap, _regions, ShenandoahHeapRegion**) \
nonstatic_field(ShenandoahHeap, _log_min_obj_alignment_in_bytes, int) \
nonstatic_field(ShenandoahHeap, _free_set, ShenandoahFreeSet*) \
volatile_nonstatic_field(ShenandoahHeap, _committed, size_t) \
static_field(ShenandoahHeapRegion, RegionSizeBytes, size_t) \
static_field(ShenandoahHeapRegion, RegionSizeBytesShift, size_t) \
volatile_nonstatic_field(ShenandoahHeapRegion, _state, ShenandoahHeapRegion::RegionState) \
nonstatic_field(ShenandoahHeapRegion, _index, size_t const) \
nonstatic_field(ShenandoahHeapRegion, _bottom, HeapWord* const) \
nonstatic_field(ShenandoahHeapRegion, _top, HeapWord*) \
nonstatic_field(ShenandoahHeapRegion, _end, HeapWord* const) \
nonstatic_field(ShenandoahFreeSet, _total_global_used, size_t) \
#define VM_STRUCTS_SHENANDOAH(nonstatic_field, volatile_nonstatic_field, static_field) \
nonstatic_field(ShenandoahHeap, _num_regions, size_t) \
nonstatic_field(ShenandoahHeap, _regions, ShenandoahHeapRegion**) \
nonstatic_field(ShenandoahHeap, _log_min_obj_alignment_in_bytes, int) \
nonstatic_field(ShenandoahHeap, _free_set, ShenandoahFreeSet*) \
volatile_nonstatic_field(ShenandoahHeap, _committed, size_t) \
static_field(ShenandoahHeapRegion, RegionSizeBytes, size_t) \
static_field(ShenandoahHeapRegion, RegionSizeBytesShift, size_t) \
nonstatic_field(ShenandoahHeapRegion, _state, Atomic<ShenandoahHeapRegion::RegionState>) \
nonstatic_field(ShenandoahHeapRegion, _index, size_t const) \
nonstatic_field(ShenandoahHeapRegion, _bottom, HeapWord* const) \
nonstatic_field(ShenandoahHeapRegion, _top, HeapWord*) \
nonstatic_field(ShenandoahHeapRegion, _end, HeapWord* const) \
nonstatic_field(ShenandoahFreeSet, _total_global_used, size_t) \
#define VM_INT_CONSTANTS_SHENANDOAH(declare_constant, declare_constant_with_value) \
declare_constant(ShenandoahHeapRegion::_empty_uncommitted) \
@ -65,7 +66,7 @@
declare_toplevel_type(ShenandoahHeapRegion) \
declare_toplevel_type(ShenandoahHeap*) \
declare_toplevel_type(ShenandoahHeapRegion*) \
declare_toplevel_type(ShenandoahHeapRegion::RegionState) \
declare_toplevel_type(Atomic<ShenandoahHeapRegion::RegionState>) \
declare_toplevel_type(ShenandoahFreeSet) \
declare_toplevel_type(ShenandoahFreeSet*) \