mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8376357
Hi all, please review these changes that convert `MutableSpace` classes to use `Atomic<T>`. Testing: gha Thanks, Thomas
This commit is contained in:
parent
37cb22826a
commit
6ad0d1cc94
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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*) \
|
||||
|
||||
@ -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**) \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user