Skip to content

Commit

Permalink
2x VA for small pages to allow async uncommit and win workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
kstefanj committed Mar 15, 2024
1 parent 25730b2 commit 470ea48
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 47 deletions.
27 changes: 16 additions & 11 deletions src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@
#include "gc/z/zMapper_windows.hpp"
#include "gc/z/zSyscall_windows.hpp"
#include "gc/z/zVirtualMemory.inline.hpp"
#include "logging/log.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"

class ZVirtualMemoryManagerImpl : public CHeapObj<mtGC> {
public:
virtual void initialize_before_reserve() {}
virtual void initialize_after_reserve(ZMemoryManager* manager) {}
virtual void initialize_after_reserve(ZMemoryManager* manager, bool do_alloc) {}
virtual bool reserve(zaddress_unsafe addr, size_t size) = 0;
virtual void unreserve(zaddress_unsafe addr, size_t size) = 0;
};
Expand Down Expand Up @@ -82,12 +83,6 @@ class ZVirtualMemoryManagerSmallPages : public ZVirtualMemoryManagerImpl {
split_into_placeholder_granules(area->start(), size);
}

static void shrink_from_back_callback(const ZMemory* area, size_t size) {
assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
// Don't try split the last granule - VirtualFree will fail
split_into_placeholder_granules(to_zoffset(untype(area->end()) - size), size - ZGranuleSize);
}

static void grow_from_front_callback(const ZMemory* area, size_t size) {
assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
coalesce_into_one_placeholder(to_zoffset(untype(area->start()) - size), area->size() + size);
Expand Down Expand Up @@ -120,16 +115,26 @@ class ZVirtualMemoryManagerSmallPages : public ZVirtualMemoryManagerImpl {
callbacks._create = &create_callback;
callbacks._destroy = &destroy_callback;
callbacks._shrink_from_front = &shrink_from_front_callback;
callbacks._shrink_from_back = &shrink_from_back_callback;
callbacks._grow_from_front = &grow_from_front_callback;
callbacks._grow_from_back = &grow_from_back_callback;

manager->register_callbacks(callbacks);
}
};

virtual void initialize_after_reserve(ZMemoryManager* manager) {
virtual void initialize_after_reserve(ZMemoryManager* manager, bool do_alloc) {
PlaceholderCallbacks::register_with(manager);
if (do_alloc) {
// These callbacks rely on VirtualFree and preserving/coalescing placeholders.
// This can be problematic when multiple managers are used and when there is a
// contigous memory segment spanning the two managers. If so, trying to
// coalesce the first placeholder in the second manager relys on knowing the
// size and placement of the last one in the first. To avoid this situation, we
// waste a granule of address space at the bottom of every manager apart from
// the first one.
zoffset offset = manager->alloc(ZGranuleSize);
log_trace(gc, heap)("Wasted virtual address granule: " PTR_FORMAT, untype(offset));
}
}

virtual bool reserve(zaddress_unsafe addr, size_t size) {
Expand Down Expand Up @@ -179,8 +184,8 @@ void ZVirtualMemoryManager::pd_initialize_before_reserve() {
}

void ZVirtualMemoryManager::pd_initialize_after_reserve() {
_impl->initialize_after_reserve(&_small_manager);
_impl->initialize_after_reserve(&_shared_manager);
_impl->initialize_after_reserve(&_small_manager, false);
_impl->initialize_after_reserve(&_shared_manager, true);
}

bool ZVirtualMemoryManager::pd_reserve(zaddress_unsafe addr, size_t size) {
Expand Down
12 changes: 0 additions & 12 deletions src/hotspot/share/gc/z/zMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ void ZMemoryManager::shrink_from_front(ZMemory* area, size_t size) {
area->shrink_from_front(size);
}

void ZMemoryManager::shrink_from_back(ZMemory* area, size_t size) {
if (_callbacks._shrink_from_back != nullptr) {
_callbacks._shrink_from_back(area, size);
}
area->shrink_from_back(size);
}

void ZMemoryManager::grow_from_front(ZMemory* area, size_t size) {
if (_callbacks._grow_from_front != nullptr) {
_callbacks._grow_from_front(area, size);
Expand All @@ -73,18 +66,13 @@ ZMemoryManager::Callbacks::Callbacks()
: _create(nullptr),
_destroy(nullptr),
_shrink_from_front(nullptr),
_shrink_from_back(nullptr),
_grow_from_front(nullptr),
_grow_from_back(nullptr) {}

ZMemoryManager::ZMemoryManager()
: _freelist(),
_callbacks() {}

bool ZMemoryManager::free_is_contiguous() const {
return _freelist.size() == 1;
}

void ZMemoryManager::register_callbacks(const Callbacks& callbacks) {
_callbacks = callbacks;
}
Expand Down
5 changes: 0 additions & 5 deletions src/hotspot/share/gc/z/zMemory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class ZMemory : public CHeapObj<mtGC> {
size_t size() const;

void shrink_from_front(size_t size);
void shrink_from_back(size_t size);
void grow_from_front(size_t size);
void grow_from_back(size_t size);
};
Expand All @@ -59,7 +58,6 @@ class ZMemoryManager {
CreateDestroyCallback _create;
CreateDestroyCallback _destroy;
ResizeCallback _shrink_from_front;
ResizeCallback _shrink_from_back;
ResizeCallback _grow_from_front;
ResizeCallback _grow_from_back;

Expand All @@ -74,15 +72,12 @@ class ZMemoryManager {
ZMemory* create(zoffset start, size_t size);
void destroy(ZMemory* area);
void shrink_from_front(ZMemory* area, size_t size);
void shrink_from_back(ZMemory* area, size_t size);
void grow_from_front(ZMemory* area, size_t size);
void grow_from_back(ZMemory* area, size_t size);

public:
ZMemoryManager();

bool free_is_contiguous() const;

void register_callbacks(const Callbacks& callbacks);

zoffset alloc(size_t size);
Expand Down
5 changes: 0 additions & 5 deletions src/hotspot/share/gc/z/zMemory.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ inline void ZMemory::shrink_from_front(size_t size) {
_start += size;
}

inline void ZMemory::shrink_from_back(size_t size) {
assert(this->size() > size, "Too small");
_end -= size;
}

inline void ZMemory::grow_from_front(size_t size) {
assert(size_t(start()) >= size, "Too big");
_start -= size;
Expand Down
13 changes: 6 additions & 7 deletions src/hotspot/share/gc/z/zVirtualMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@

ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity)
: _reserved_segments(),
_small_manager(max_capacity),
_shared_manager(max_capacity * (ZVirtualToPhysicalRatio - 1)),
_small_manager(max_capacity * 2),
_shared_manager(max_capacity * (ZVirtualToPhysicalRatio - 2)),
_reserved(0),
_initialized(false) {

Expand All @@ -50,12 +50,12 @@ ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity)
return;
}

// Initialize platform specific parts after reserving address space
pd_initialize_after_reserve();

// Setup the sized managers from the initial one
distribute_reserved_segments();

// Initialize platform specific parts after reserving address space
pd_initialize_after_reserve();

// Successfully initialized
_initialized = true;
}
Expand Down Expand Up @@ -146,6 +146,7 @@ void ZSizedMemoryManager::initialize(zoffset &start, size_t &size) {
size_t to_add = MIN2(size, (_capacity - _size));
free(zoffset(start), to_add);

log_trace(gc, heap)("Initial free segment: " PTR_FORMAT " %zuM", untype(start), to_add / M);
// Update the state
_size += to_add;
_limit = zoffset_end(untype(start) + to_add);
Expand Down Expand Up @@ -267,10 +268,8 @@ ZVirtualMemory ZVirtualMemoryManager::alloc(size_t size, bool force_low_address)
// medium/large pages are allocated at higher addresses.
if (size <= ZPageSizeSmall || force_low_address) {
start = _small_manager.alloc(size);
log_trace(gc, heap)("Allocated %zu M from small address space at " PTR_FORMAT, size / M, untype(start));
} else {
start = _shared_manager.alloc(size);
log_trace(gc, heap)("Allocated %zu M from shared address space at " PTR_FORMAT, size / M, untype(start));
}

if (start == zoffset(UINTPTR_MAX)) {
Expand Down
7 changes: 0 additions & 7 deletions test/hotspot/gtest/gc/z/test_zMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,6 @@ TEST(ZMemory, resize) {
EXPECT_EQ(mem.size(), ZGranuleSize * 1);
mem.grow_from_front(ZGranuleSize);

mem.shrink_from_back(ZGranuleSize);
EXPECT_EQ(mem.start(), zoffset(ZGranuleSize * 2));
EXPECT_EQ(mem.end(), zoffset_end(ZGranuleSize * 3));
EXPECT_EQ(mem.size(), ZGranuleSize * 1);
mem.grow_from_back(ZGranuleSize);

mem.grow_from_front(ZGranuleSize);
EXPECT_EQ(mem.start(), zoffset(ZGranuleSize * 1));
EXPECT_EQ(mem.end(), zoffset_end(ZGranuleSize * 4));
Expand All @@ -101,5 +95,4 @@ TEST(ZMemory, resize) {
EXPECT_EQ(mem.start(), zoffset(ZGranuleSize * 2));
EXPECT_EQ(mem.end(), zoffset_end(ZGranuleSize * 5));
EXPECT_EQ(mem.size(), ZGranuleSize * 3);
mem.shrink_from_back(ZGranuleSize);
}

0 comments on commit 470ea48

Please sign in to comment.