8374682: ZGC: Convert zLiveMap to use Atomic<T>

Reviewed-by: stefank, tschatzl
This commit is contained in:
Axel Boldt-Christmas 2026-01-26 15:05:24 +00:00
parent 61b722d59a
commit 99b4e05d50
3 changed files with 20 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,6 @@
#include "gc/z/zStat.hpp" #include "gc/z/zStat.hpp"
#include "gc/z/zUtils.hpp" #include "gc/z/zUtils.hpp"
#include "logging/log.hpp" #include "logging/log.hpp"
#include "runtime/atomicAccess.hpp"
#include "utilities/debug.hpp" #include "utilities/debug.hpp"
#include "utilities/powerOfTwo.hpp" #include "utilities/powerOfTwo.hpp"
#include "utilities/spinYield.hpp" #include "utilities/spinYield.hpp"
@ -60,18 +59,18 @@ void ZLiveMap::reset(ZGenerationId id) {
// Multiple threads can enter here, make sure only one of them // Multiple threads can enter here, make sure only one of them
// resets the marking information while the others busy wait. // resets the marking information while the others busy wait.
for (uint32_t seqnum = AtomicAccess::load_acquire(&_seqnum); for (uint32_t seqnum = _seqnum.load_acquire();
seqnum != generation->seqnum(); seqnum != generation->seqnum();
seqnum = AtomicAccess::load_acquire(&_seqnum)) { seqnum = _seqnum.load_acquire()) {
if (seqnum != seqnum_initializing) { if (seqnum != seqnum_initializing) {
// No one has claimed initialization of the livemap yet // No one has claimed initialization of the livemap yet
if (AtomicAccess::cmpxchg(&_seqnum, seqnum, seqnum_initializing) == seqnum) { if (_seqnum.compare_set(seqnum, seqnum_initializing)) {
// This thread claimed the initialization // This thread claimed the initialization
// Reset marking information // Reset marking information
_live_bytes = 0; _live_bytes.store_relaxed(0u);
_live_objects = 0; _live_objects.store_relaxed(0u);
// Clear segment claimed/live bits // Clear segment claimed/live bits
segment_live_bits().clear(); segment_live_bits().clear();
@ -81,13 +80,13 @@ void ZLiveMap::reset(ZGenerationId id) {
// a bit is about to be set for the first time. // a bit is about to be set for the first time.
initialize_bitmap(); initialize_bitmap();
assert(_seqnum == seqnum_initializing, "Invalid"); assert(_seqnum.load_relaxed() == seqnum_initializing, "Invalid");
// Make sure the newly reset marking information is ordered // Make sure the newly reset marking information is ordered
// before the update of the page seqnum, such that when the // before the update of the page seqnum, such that when the
// up-to-date seqnum is load acquired, the bit maps will not // up-to-date seqnum is load acquired, the bit maps will not
// contain stale information. // contain stale information.
AtomicAccess::release_store(&_seqnum, generation->seqnum()); _seqnum.release_store(generation->seqnum());
break; break;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@
#include "gc/z/zBitMap.hpp" #include "gc/z/zBitMap.hpp"
#include "gc/z/zGenerationId.hpp" #include "gc/z/zGenerationId.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
class ObjectClosure; class ObjectClosure;
@ -41,9 +42,9 @@ private:
const uint32_t _segment_size; const uint32_t _segment_size;
const int _segment_shift; const int _segment_shift;
volatile uint32_t _seqnum; Atomic<uint32_t> _seqnum;
volatile uint32_t _live_objects; Atomic<uint32_t> _live_objects;
volatile size_t _live_bytes; Atomic<size_t> _live_bytes;
BitMap::bm_word_t _segment_live_bits; BitMap::bm_word_t _segment_live_bits;
BitMap::bm_word_t _segment_claim_bits; BitMap::bm_word_t _segment_claim_bits;
ZBitMap _bitmap; ZBitMap _bitmap;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,24 +31,23 @@
#include "gc/z/zGeneration.inline.hpp" #include "gc/z/zGeneration.inline.hpp"
#include "gc/z/zMark.hpp" #include "gc/z/zMark.hpp"
#include "gc/z/zUtils.inline.hpp" #include "gc/z/zUtils.inline.hpp"
#include "runtime/atomicAccess.hpp"
#include "utilities/bitMap.inline.hpp" #include "utilities/bitMap.inline.hpp"
#include "utilities/debug.hpp" #include "utilities/debug.hpp"
inline void ZLiveMap::reset() { inline void ZLiveMap::reset() {
_seqnum = 0; _seqnum.store_relaxed(0u);
} }
inline bool ZLiveMap::is_marked(ZGenerationId id) const { inline bool ZLiveMap::is_marked(ZGenerationId id) const {
return AtomicAccess::load_acquire(&_seqnum) == ZGeneration::generation(id)->seqnum(); return _seqnum.load_acquire() == ZGeneration::generation(id)->seqnum();
} }
inline uint32_t ZLiveMap::live_objects() const { inline uint32_t ZLiveMap::live_objects() const {
return _live_objects; return _live_objects.load_relaxed();
} }
inline size_t ZLiveMap::live_bytes() const { inline size_t ZLiveMap::live_bytes() const {
return _live_bytes; return _live_bytes.load_relaxed();
} }
inline const BitMapView ZLiveMap::segment_live_bits() const { inline const BitMapView ZLiveMap::segment_live_bits() const {
@ -116,8 +115,8 @@ inline bool ZLiveMap::set(ZGenerationId id, BitMap::idx_t index, bool finalizabl
} }
inline void ZLiveMap::inc_live(uint32_t objects, size_t bytes) { inline void ZLiveMap::inc_live(uint32_t objects, size_t bytes) {
AtomicAccess::add(&_live_objects, objects); _live_objects.add_then_fetch(objects);
AtomicAccess::add(&_live_bytes, bytes); _live_bytes.add_then_fetch(bytes);
} }
inline BitMap::idx_t ZLiveMap::segment_start(BitMap::idx_t segment) const { inline BitMap::idx_t ZLiveMap::segment_start(BitMap::idx_t segment) const {