Hi all,

  please review these changes that convert `MutableSpace` classes to use `Atomic<T>`.

Testing: gha

Thanks,
  Thomas
This commit is contained in:
Thomas Schatzl 2026-01-26 17:31:13 +01:00
parent 37cb22826a
commit 6ad0d1cc94
5 changed files with 23 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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
@ -31,7 +31,7 @@
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/atomic.hpp"
#include "runtime/java.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/os.inline.hpp"
@ -489,7 +489,7 @@ HeapWord* MutableNUMASpace::cas_allocate(size_t size) {
if (p != nullptr) {
HeapWord* cur_top, *cur_chunk_top = p + size;
while ((cur_top = top()) < cur_chunk_top) { // Keep _top updated.
if (AtomicAccess::cmpxchg(top_addr(), cur_top, cur_chunk_top) == cur_top) {
if (top_addr()->compare_set(cur_top, cur_chunk_top)) {
break;
}
}

View File

@ -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
@ -28,7 +28,6 @@
#include "memory/iterator.inline.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/safepoint.hpp"
#include "utilities/align.hpp"
@ -123,7 +122,7 @@ void MutableSpace::initialize(MemRegion mr,
// makes the new space available for allocation by other threads. So this
// assignment must follow all other configuration and initialization that
// might be done for expansion.
AtomicAccess::release_store(end_addr(), mr.end());
_end.release_store(mr.end());
if (clear_space) {
clear(mangle_space);
@ -140,7 +139,7 @@ void MutableSpace::clear(bool mangle_space) {
#ifndef PRODUCT
void MutableSpace::mangle_unused_area() {
mangle_region(MemRegion(_top, _end));
mangle_region(MemRegion(top(), end()));
}
void MutableSpace::mangle_region(MemRegion mr) {
@ -155,14 +154,10 @@ HeapWord* MutableSpace::cas_allocate(size_t size) {
// If end is read first, other threads may advance end and top such that
// current top > old end and current top + size > current end. Then
// pointer_delta underflows, allowing installation of top > current end.
HeapWord* obj = AtomicAccess::load_acquire(top_addr());
HeapWord* obj = _top.load_acquire();
if (pointer_delta(end(), obj) >= size) {
HeapWord* new_top = obj + size;
HeapWord* result = AtomicAccess::cmpxchg(top_addr(), obj, new_top);
// result can be one of two:
// the old top value: the exchange succeeded
// otherwise: the new value of the top is returned.
if (result != obj) {
if (!_top.compare_set(obj, new_top)) {
continue; // another thread beat us to the allocation, try again
}
assert(is_object_aligned(obj) && is_object_aligned(new_top),
@ -177,7 +172,7 @@ HeapWord* MutableSpace::cas_allocate(size_t size) {
// Try to deallocate previous allocation. Returns true upon success.
bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) {
HeapWord* expected_top = obj + size;
return AtomicAccess::cmpxchg(top_addr(), expected_top, obj) == expected_top;
return _top.compare_set(expected_top, obj);
}
void MutableSpace::oop_iterate(OopIterateClosure* cl) {

View File

@ -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
@ -28,6 +28,7 @@
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
#include "memory/memRegion.hpp"
#include "runtime/atomic.hpp"
#include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
@ -53,8 +54,8 @@ class MutableSpace: public CHeapObj<mtGC> {
MemRegion _last_setup_region;
size_t _page_size;
HeapWord* _bottom;
HeapWord* volatile _top;
HeapWord* _end;
Atomic<HeapWord*> _top;
Atomic<HeapWord*> _end;
void numa_setup_pages(MemRegion mr, bool clear_space);
@ -64,21 +65,20 @@ class MutableSpace: public CHeapObj<mtGC> {
protected:
size_t page_size() const { return _page_size; }
Atomic<HeapWord*>* top_addr() { return &_top; }
public:
virtual ~MutableSpace() = default;
MutableSpace(size_t page_size);
// Accessors
HeapWord* bottom() const { return _bottom; }
HeapWord* top() const { return _top; }
HeapWord* end() const { return _end; }
HeapWord* top() const { return _top.load_relaxed(); }
HeapWord* end() const { return _end.load_relaxed(); }
void set_bottom(HeapWord* value) { _bottom = value; }
virtual void set_top(HeapWord* value) { _top = value; }
void set_end(HeapWord* value) { _end = value; }
HeapWord* volatile* top_addr() { return &_top; }
HeapWord** end_addr() { return &_end; }
virtual void set_top(HeapWord* value) { _top.store_relaxed(value); }
void set_end(HeapWord* value) { _end.store_relaxed(value); }
MemRegion region() const { return MemRegion(bottom(), end()); }
@ -110,7 +110,7 @@ public:
// Boolean queries.
bool is_empty() const { return used_in_words() == 0; }
bool not_empty() const { return used_in_words() > 0; }
bool contains(const void* p) const { return _bottom <= p && p < _end; }
bool contains(const void* p) const { return _bottom <= p && p < end(); }
// Size computations. Sizes are in bytes.
size_t used_in_bytes() const { return used_in_words() * HeapWordSize; }

View File

@ -47,8 +47,8 @@
nonstatic_field(PSVirtualSpace, _committed_high_addr, char*) \
\
nonstatic_field(MutableSpace, _bottom, HeapWord*) \
nonstatic_field(MutableSpace, _end, HeapWord*) \
volatile_nonstatic_field(MutableSpace, _top, HeapWord*) \
nonstatic_field(MutableSpace, _end, Atomic<HeapWord*>) \
volatile_nonstatic_field(MutableSpace, _top, Atomic<HeapWord*>) \
\
nonstatic_field(PSYoungGen, _reserved, MemRegion) \
nonstatic_field(PSYoungGen, _virtual_space, PSVirtualSpace*) \

View File

@ -901,6 +901,7 @@
/*****************************/ \
\
declare_toplevel_type(void*) \
declare_toplevel_type(Atomic<HeapWord*>) \
declare_toplevel_type(int*) \
declare_toplevel_type(char*) \
declare_toplevel_type(char**) \