jdk-24/test/hotspot/gtest/gc/z/test_zMapper_windows.cpp
Stefan Johansson 8031dabf83 8331094: ZGC: GTest fails due to incompatible Windows version
Reviewed-by: aboldtch, tschatzl
2024-04-25 10:43:07 +00:00

189 lines
5.3 KiB
C++

/*
* Copyright (c) 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "precompiled.hpp"
#ifdef _WINDOWS
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zList.inline.hpp"
#include "gc/z/zMemory.inline.hpp"
#include "gc/z/zSyscall_windows.hpp"
#include "gc/z/zVirtualMemory.hpp"
#include "runtime/os.hpp"
#include "unittest.hpp"
using namespace testing;
#define EXPECT_ALLOC_OK(offset) EXPECT_NE(offset, zoffset(UINTPTR_MAX))
class ZMapperTest : public Test {
private:
static constexpr size_t ZMapperTestReservationSize = 32 * M;
static bool _initialized;
static ZMemoryManager* _va;
ZVirtualMemoryManager* _vmm;
public:
bool reserve_for_test() {
// Initialize platform specific parts before reserving address space
_vmm->pd_initialize_before_reserve();
// Reserve address space
if (!_vmm->pd_reserve(ZOffset::address_unsafe(zoffset(0)), ZMapperTestReservationSize)) {
return false;
}
// Make the address range free before setting up callbacks below
_va->free(zoffset(0), ZMapperTestReservationSize);
// Initialize platform specific parts after reserving address space
_vmm->pd_initialize_after_reserve();
return true;
}
virtual void SetUp() {
// Only run test on supported Windows versions
if (!ZSyscall::is_supported()) {
GTEST_SKIP() << "Requires Windows version 1803 or later";
return;
}
ZSyscall::initialize();
ZGlobalsPointers::initialize();
// Fake a ZVirtualMemoryManager
_vmm = (ZVirtualMemoryManager*)os::malloc(sizeof(ZVirtualMemoryManager), mtTest);
// Construct its internal ZMemoryManager
_va = new (&_vmm->_manager) ZMemoryManager();
// Reserve address space for the test
if (!reserve_for_test()) {
GTEST_SKIP() << "Failed to reserve address space";
return;
}
_initialized = true;
}
virtual void TearDown() {
if (!ZSyscall::is_supported()) {
// Test skipped, nothing to cleanup
return;
}
if (_initialized) {
_vmm->pd_unreserve(ZOffset::address_unsafe(zoffset(0)), 0);
}
os::free(_vmm);
}
static void test_alloc_low_address() {
// Verify that we get placeholder for first granule
zoffset bottom = _va->alloc_low_address(ZGranuleSize);
EXPECT_ALLOC_OK(bottom);
_va->free(bottom, ZGranuleSize);
// Alloc something larger than a granule and free it
bottom = _va->alloc_low_address(ZGranuleSize * 3);
EXPECT_ALLOC_OK(bottom);
_va->free(bottom, ZGranuleSize * 3);
// Free with more memory allocated
bottom = _va->alloc_low_address(ZGranuleSize);
EXPECT_ALLOC_OK(bottom);
zoffset next = _va->alloc_low_address(ZGranuleSize);
EXPECT_ALLOC_OK(next);
_va->free(bottom, ZGranuleSize);
_va->free(next, ZGranuleSize);
}
static void test_alloc_high_address() {
// Verify that we get placeholder for last granule
zoffset high = _va->alloc_high_address(ZGranuleSize);
EXPECT_ALLOC_OK(high);
zoffset prev = _va->alloc_high_address(ZGranuleSize);
EXPECT_ALLOC_OK(prev);
_va->free(high, ZGranuleSize);
_va->free(prev, ZGranuleSize);
// Alloc something larger than a granule and return it
high = _va->alloc_high_address(ZGranuleSize * 2);
EXPECT_ALLOC_OK(high);
_va->free(high, ZGranuleSize * 2);
}
static void test_alloc_whole_area() {
// Alloc the whole reservation
zoffset bottom = _va->alloc_low_address(ZMapperTestReservationSize);
EXPECT_ALLOC_OK(bottom);
// Free two chunks and then allocate them again
_va->free(bottom, ZGranuleSize * 4);
_va->free(bottom + ZGranuleSize * 6, ZGranuleSize * 6);
zoffset offset = _va->alloc_low_address(ZGranuleSize * 4);
EXPECT_ALLOC_OK(offset);
offset = _va->alloc_low_address(ZGranuleSize * 6);
EXPECT_ALLOC_OK(offset);
// Now free it all, and verify it can be re-allocated
_va->free(bottom, ZMapperTestReservationSize);
bottom = _va->alloc_low_address(ZMapperTestReservationSize);
EXPECT_ALLOC_OK(bottom);
_va->free(bottom, ZMapperTestReservationSize);
}
};
bool ZMapperTest::_initialized = false;
ZMemoryManager* ZMapperTest::_va = nullptr;
TEST_VM_F(ZMapperTest, test_alloc_low_address) {
test_alloc_low_address();
}
TEST_VM_F(ZMapperTest, test_alloc_high_address) {
test_alloc_high_address();
}
TEST_VM_F(ZMapperTest, test_alloc_whole_area) {
test_alloc_whole_area();
}
#endif // _WINDOWS