Skip to content

Commit 1f10ffb

Browse files
committedMar 4, 2025
8350851: ZGC: Reduce size of ZAddressOffsetMax scaling data structures
Reviewed-by: eosterlund, jsikstro
1 parent 4fc72b8 commit 1f10ffb

10 files changed

+81
-9
lines changed
 

‎src/hotspot/share/gc/z/zIndexDistributor.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#ifndef SHARE_GC_Z_ZINDEXDISTRIBUTOR_HPP
2525
#define SHARE_GC_Z_ZINDEXDISTRIBUTOR_HPP
2626

27+
#include <utilities/globalDefinitions.hpp>
28+
2729
class ZIndexDistributor {
2830
private:
2931
void* _strategy;
@@ -39,6 +41,10 @@ class ZIndexDistributor {
3941

4042
template <typename Function>
4143
void do_indices(Function function);
44+
45+
// Returns a count that is max_count or larger and upholds the requirements
46+
// for using the ZIndexDistributor strategy specfied by ZIndexDistributorStrategy
47+
static size_t get_count(size_t max_count);
4248
};
4349

4450
#endif // SHARE_GC_Z_ZINDEXDISTRIBUTOR_HPP

‎src/hotspot/share/gc/z/zIndexDistributor.inline.hpp

+32-7
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@
3232
#include "runtime/os.hpp"
3333
#include "runtime/thread.hpp"
3434
#include "utilities/align.hpp"
35+
#include "utilities/powerOfTwo.hpp"
3536

3637
class ZIndexDistributorStriped : public CHeapObj<mtGC> {
3738
static const int MemSize = 4096;
39+
static const int StripeCount = MemSize / ZCacheLineSize;
3840

39-
const int _max_index;
41+
const int _count;
4042
// For claiming a stripe
4143
volatile int _claim_stripe;
4244
// For claiming inside a stripe
@@ -51,20 +53,19 @@ class ZIndexDistributorStriped : public CHeapObj<mtGC> {
5153
}
5254

5355
public:
54-
ZIndexDistributorStriped(int max_index)
55-
: _max_index(max_index),
56+
ZIndexDistributorStriped(int count)
57+
: _count(count),
5658
_claim_stripe(0),
5759
_mem() {
5860
memset(_mem, 0, MemSize + ZCacheLineSize);
5961
}
6062

6163
template <typename Function>
6264
void do_indices(Function function) {
63-
const int count = MemSize / ZCacheLineSize;
64-
const int stripe_max = _max_index / count;
65+
const int stripe_max = _count / StripeCount;
6566

6667
// Use claiming
67-
for (int i; (i = claim_stripe()) < count;) {
68+
for (int i; (i = claim_stripe()) < StripeCount;) {
6869
for (int index; (index = Atomic::fetch_then_add(claim_addr(i), 1, memory_order_relaxed)) < stripe_max;) {
6970
if (!function(i * stripe_max + index)) {
7071
return;
@@ -73,14 +74,19 @@ class ZIndexDistributorStriped : public CHeapObj<mtGC> {
7374
}
7475

7576
// Use stealing
76-
for (int i = 0; i < count; i++) {
77+
for (int i = 0; i < StripeCount; i++) {
7778
for (int index; (index = Atomic::fetch_then_add(claim_addr(i), 1, memory_order_relaxed)) < stripe_max;) {
7879
if (!function(i * stripe_max + index)) {
7980
return;
8081
}
8182
}
8283
}
8384
}
85+
86+
static size_t get_count(size_t max_count) {
87+
// Must be multiple of the StripeCount
88+
return align_up(max_count, StripeCount);
89+
}
8490
};
8591

8692
class ZIndexDistributorClaimTree : public CHeapObj<mtGC> {
@@ -290,6 +296,12 @@ class ZIndexDistributorClaimTree : public CHeapObj<mtGC> {
290296
claim_and_do(function, indices, 0 /* level */);
291297
steal_and_do(function, indices, 0 /* level */);
292298
}
299+
300+
static size_t get_count(size_t max_count) {
301+
// Must be at least claim_level_size(ClaimLevels) and a power of two
302+
const size_t min_count = claim_level_size(ClaimLevels);
303+
return round_up_power_of_2(MAX2(max_count, min_count));
304+
}
293305
};
294306

295307
// Using dynamically allocated objects just to be able to evaluate
@@ -328,4 +340,17 @@ inline void ZIndexDistributor::do_indices(Function function) {
328340
};
329341
}
330342

343+
inline size_t ZIndexDistributor::get_count(size_t max_count) {
344+
size_t required_count;
345+
switch (ZIndexDistributorStrategy) {
346+
case 0: required_count = ZIndexDistributorClaimTree::get_count(max_count); break;
347+
case 1: required_count = ZIndexDistributorStriped::get_count(max_count); break;
348+
default: fatal("Unknown ZIndexDistributorStrategy");
349+
};
350+
351+
assert(max_count <= required_count, "unsupported max_count: %zu", max_count);
352+
353+
return required_count;
354+
}
355+
331356
#endif // SHARE_GC_Z_ZINDEXDISTRIBUTOR_INLINE_HPP

‎src/hotspot/share/gc/z/zMemory.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ zoffset ZMemoryManager::peek_low_address() const {
100100
return zoffset(UINTPTR_MAX);
101101
}
102102

103+
zoffset_end ZMemoryManager::peak_high_address_end() const {
104+
ZLocker<ZLock> locker(&_lock);
105+
106+
const ZMemory* const area = _freelist.last();
107+
if (area != nullptr) {
108+
return area->end();
109+
}
110+
111+
// Out of memory
112+
return zoffset_end(UINTPTR_MAX);
113+
}
114+
103115
zoffset ZMemoryManager::alloc_low_address(size_t size) {
104116
ZLocker<ZLock> locker(&_lock);
105117

‎src/hotspot/share/gc/z/zMemory.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class ZMemoryManager {
8686
void register_callbacks(const Callbacks& callbacks);
8787

8888
zoffset peek_low_address() const;
89+
zoffset_end peak_high_address_end() const;
8990
zoffset alloc_low_address(size_t size);
9091
zoffset alloc_low_address_at_most(size_t size, size_t* allocated);
9192
zoffset alloc_high_address(size_t size);

‎src/hotspot/share/gc/z/zPageTable.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,22 @@
2323

2424
#include "gc/z/zAddress.hpp"
2525
#include "gc/z/zGranuleMap.inline.hpp"
26+
#include "gc/z/zIndexDistributor.inline.hpp"
2627
#include "gc/z/zPage.inline.hpp"
2728
#include "gc/z/zPageTable.inline.hpp"
2829
#include "runtime/orderAccess.hpp"
2930
#include "utilities/debug.hpp"
3031

32+
static size_t get_max_offset_for_map() {
33+
// The page table has (ZAddressOffsetMax >> ZGranuleSizeShift) slots
34+
const size_t max_count = ZAddressOffsetMax >> ZGranuleSizeShift;
35+
const size_t required_count = ZIndexDistributor::get_count(max_count);
36+
37+
return required_count << ZGranuleSizeShift;
38+
}
39+
3140
ZPageTable::ZPageTable()
32-
: _map(ZAddressOffsetMax) {}
41+
: _map(get_max_offset_for_map()) {}
3342

3443
void ZPageTable::insert(ZPage* page) {
3544
const zoffset offset = page->start();

‎src/hotspot/share/gc/z/zPageTable.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class ZPageTable {
4545
public:
4646
ZPageTable();
4747

48+
int count() const;
49+
4850
ZPage* get(zaddress addr) const;
4951
ZPage* get(volatile zpointer* p) const;
5052

‎src/hotspot/share/gc/z/zPageTable.inline.hpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@
3232
#include "gc/z/zPage.inline.hpp"
3333
#include "gc/z/zPageAllocator.inline.hpp"
3434

35+
#include <limits>
36+
37+
inline int ZPageTable::count() const {
38+
const size_t size = _map._size;
39+
assert(size <= std::numeric_limits<int>::max(), "Invalid page table size");
40+
41+
return static_cast<int>(size);
42+
}
43+
3544
inline ZPage* ZPageTable::get(zaddress addr) const {
3645
assert(!is_null(addr), "Invalid address");
3746
return _map.get(ZAddress::offset(addr));
@@ -64,7 +73,7 @@ inline bool ZPageTableIterator::next(ZPage** page) {
6473

6574
inline ZPageTableParallelIterator::ZPageTableParallelIterator(const ZPageTable* table)
6675
: _table(table),
67-
_index_distributor(int(ZAddressOffsetMax >> ZGranuleSizeShift)) {}
76+
_index_distributor(table->count()) {}
6877

6978
template <typename Function>
7079
inline void ZPageTableParallelIterator::do_pages(Function function) {

‎src/hotspot/share/gc/z/zVirtualMemory.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity)
4848
return;
4949
}
5050

51+
// Set ZAddressOffsetMax to the highest address end available after reservation
52+
ZAddressOffsetMax = untype(highest_available_address_end());
53+
5154
// Initialize platform specific parts after reserving address space
5255
pd_initialize_after_reserve();
5356

‎src/hotspot/share/gc/z/zVirtualMemory.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class ZVirtualMemoryManager {
7777

7878
size_t reserved() const;
7979
zoffset lowest_available_address() const;
80+
zoffset_end highest_available_address_end() const;
8081

8182
ZVirtualMemory alloc(size_t size, bool force_low_address);
8283
void free(const ZVirtualMemory& vmem);

‎src/hotspot/share/gc/z/zVirtualMemory.inline.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,8 @@ inline zoffset ZVirtualMemoryManager::lowest_available_address() const {
6565
return _manager.peek_low_address();
6666
}
6767

68+
inline zoffset_end ZVirtualMemoryManager::highest_available_address_end() const {
69+
return _manager.peak_high_address_end();
70+
}
71+
6872
#endif // SHARE_GC_Z_ZVIRTUALMEMORY_INLINE_HPP

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Mar 4, 2025

@openjdk-notifier[bot]
Please sign in to comment.