8375747: ZGC: ZForwardingTest is unable to commit memory on Windows

Reviewed-by: jsikstro, eosterlund
This commit is contained in:
Stefan Karlsson 2026-01-29 08:39:32 +00:00
parent 06d1345f29
commit 92072a93bf
3 changed files with 73 additions and 13 deletions

View File

@ -199,18 +199,18 @@ CREATE_ZOFFSET_OPERATORS(zoffset)
inline uintptr_t untype(zbacking_offset offset) {
const uintptr_t value = static_cast<uintptr_t>(offset);
assert(value < ZBackingOffsetMax, "Offset out of bounds (" PTR_FORMAT " < " PTR_FORMAT ")", value, ZAddressOffsetMax);
assert(value < ZBackingOffsetMax, "Offset out of bounds (" PTR_FORMAT " < " PTR_FORMAT ")", value, ZBackingOffsetMax);
return value;
}
inline uintptr_t untype(zbacking_offset_end offset) {
const uintptr_t value = static_cast<uintptr_t>(offset);
assert(value <= ZBackingOffsetMax, "Offset out of bounds (" PTR_FORMAT " <= " PTR_FORMAT ")", value, ZAddressOffsetMax);
assert(value <= ZBackingOffsetMax, "Offset out of bounds (" PTR_FORMAT " <= " PTR_FORMAT ")", value, ZBackingOffsetMax);
return value;
}
inline zbacking_offset to_zbacking_offset(uintptr_t value) {
assert(value < ZBackingOffsetMax, "Value out of bounds (" PTR_FORMAT " < " PTR_FORMAT ")", value, ZAddressOffsetMax);
assert(value < ZBackingOffsetMax, "Value out of bounds (" PTR_FORMAT " < " PTR_FORMAT ")", value, ZBackingOffsetMax);
return zbacking_offset(value);
}
@ -227,7 +227,7 @@ inline zbacking_offset_end to_zbacking_offset_end(zbacking_offset start, size_t
}
inline zbacking_offset_end to_zbacking_offset_end(uintptr_t value) {
assert(value <= ZBackingOffsetMax, "Value out of bounds (" PTR_FORMAT " <= " PTR_FORMAT ")", value, ZAddressOffsetMax);
assert(value <= ZBackingOffsetMax, "Value out of bounds (" PTR_FORMAT " <= " PTR_FORMAT ")", value, ZBackingOffsetMax);
return zbacking_offset_end(value);
}

View File

@ -44,11 +44,12 @@ using namespace testing;
class ZForwardingTest : public ZTest {
public:
// Setup and tear down
ZHeap* _old_heap;
ZGenerationOld* _old_old;
ZGenerationYoung* _old_young;
ZAddressReserver _zaddress_reserver;
zoffset _page_offset;
ZHeap* _old_heap;
ZGenerationOld* _old_old;
ZGenerationYoung* _old_young;
ZAddressReserver _zaddress_reserver;
ZPhysicalMemoryBackingMocker _physical_backing;
zoffset _page_offset;
virtual void SetUp() {
_old_heap = ZHeap::_heap;
@ -73,8 +74,16 @@ public:
GTEST_SKIP() << "Unable to reserve memory";
}
char* const addr = (char*)untype(ZOffset::address_unsafe(_page_offset));
os::commit_memory(addr, ZGranuleSize, /* executable */ false);
// Setup backing storage
_physical_backing.SetUp(ZGranuleSize);
size_t committed = _physical_backing()->commit(zbacking_offset(0), ZGranuleSize, 0);
if (committed != ZGranuleSize) {
GTEST_SKIP() << "Unable to commit memory";
}
_physical_backing()->map(ZOffset::address_unsafe(_page_offset), ZGranuleSize, zbacking_offset(0));
}
virtual void TearDown() {
@ -84,10 +93,12 @@ public:
ZGeneration::_young = _old_young;
if (_page_offset != zoffset::invalid) {
char* const addr = (char*)untype(ZOffset::address_unsafe(_page_offset));
os::uncommit_memory(addr, ZGranuleSize, false /* executable */);
_physical_backing()->unmap(ZOffset::address_unsafe(_page_offset), ZGranuleSize);
_physical_backing()->uncommit(zbacking_offset(0), ZGranuleSize);
}
_physical_backing.TearDown();
_zaddress_reserver.TearDown();
}

View File

@ -28,6 +28,7 @@
#include "gc/z/zArguments.hpp"
#include "gc/z/zInitialize.hpp"
#include "gc/z/zNUMA.hpp"
#include "gc/z/zPhysicalMemoryManager.hpp"
#include "gc/z/zRangeRegistry.hpp"
#include "gc/z/zVirtualMemory.inline.hpp"
#include "gc/z/zVirtualMemoryManager.hpp"
@ -104,6 +105,54 @@ public:
}
};
class ZPhysicalMemoryBackingMocker {
size_t _old_max;
ZPhysicalMemoryBacking* _backing;
bool _active;
static size_t set_max(size_t max_capacity) {
size_t old_max = ZBackingOffsetMax;
ZBackingOffsetMax = max_capacity;
ZBackingIndexMax = checked_cast<uint32_t>(ZBackingOffsetMax >> ZGranuleSizeShift);
return old_max;
}
public:
ZPhysicalMemoryBackingMocker()
: _old_max(0),
_backing(nullptr),
_active(false) {}
void SetUp(size_t max_capacity) {
GTEST_EXPECT_FALSE(_active) << "SetUp called twice without a TearDown";
_old_max = set_max(max_capacity);
char* const mem = (char*)os::malloc(sizeof(ZPhysicalMemoryBacking), mtTest);
_backing = new (mem) ZPhysicalMemoryBacking(ZGranuleSize);
_active = true;
}
void TearDown() {
GTEST_EXPECT_TRUE(_active) << "TearDown called without a preceding SetUp";
_active = false;
_backing->~ZPhysicalMemoryBacking();
os::free(_backing);
_backing = nullptr;
set_max(_old_max);
}
ZPhysicalMemoryBacking* operator()() {
return _backing;
}
};
private:
ZAddressOffsetMaxSetter _zaddress_offset_max_setter;
unsigned int _rand_seed;