8253332: ZGC: Make heap views reservation platform independent

Reviewed-by: shade, pliden
This commit is contained in:
Stefan Karlsson 2020-09-21 12:48:18 +00:00
parent dad6edbf83
commit fbfb62dffe
4 changed files with 59 additions and 75 deletions

View File

@ -33,21 +33,16 @@ void ZVirtualMemoryManager::initialize_os() {
// Does nothing
}
static void unmap(uintptr_t start, size_t size) {
const int res = munmap((void*)start, size);
assert(res == 0, "Failed to unmap memory");
}
static bool map(uintptr_t start, size_t size) {
const void* const res = mmap((void*)start, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
if (res == MAP_FAILED) {
bool ZVirtualMemoryManager::os_reserve(uintptr_t addr, size_t size) {
const uintptr_t res = (uintptr_t)mmap((void*)addr, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
if (res == (uintptr_t)MAP_FAILED) {
// Failed to reserve memory
return false;
}
if ((uintptr_t)res != start) {
if (res != addr) {
// Failed to reserve memory at the requested address
unmap((uintptr_t)res, size);
munmap((void*)res, size);
return false;
}
@ -55,31 +50,7 @@ static bool map(uintptr_t start, size_t size) {
return true;
}
bool ZVirtualMemoryManager::reserve_contiguous_platform(uintptr_t start, size_t size) {
// Reserve address views
const uintptr_t marked0 = ZAddress::marked0(start);
const uintptr_t marked1 = ZAddress::marked1(start);
const uintptr_t remapped = ZAddress::remapped(start);
if (!map(marked0, size)) {
return false;
}
if (!map(marked1, size)) {
unmap(marked0, size);
return false;
}
if (!map(remapped, size)) {
unmap(marked0, size);
unmap(marked1, size);
return false;
}
// Register address views with native memory tracker
nmt_reserve(marked0, size);
nmt_reserve(marked1, size);
nmt_reserve(remapped, size);
return true;
void ZVirtualMemoryManager::os_unreserve(uintptr_t addr, size_t size) {
const int res = munmap((void*)addr, size);
assert(res == 0, "Failed to unmap memory");
}

View File

@ -116,34 +116,13 @@ void ZVirtualMemoryManager::initialize_os() {
_manager.register_callbacks(callbacks);
}
bool ZVirtualMemoryManager::reserve_contiguous_platform(uintptr_t start, size_t size) {
assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
bool ZVirtualMemoryManager::os_reserve(uintptr_t addr, size_t size) {
uintptr_t res = ZMapper::reserve(addr, size);
// Reserve address views
const uintptr_t marked0 = ZAddress::marked0(start);
const uintptr_t marked1 = ZAddress::marked1(start);
const uintptr_t remapped = ZAddress::remapped(start);
// Reserve address space
if (ZMapper::reserve(marked0, size) != marked0) {
return false;
}
if (ZMapper::reserve(marked1, size) != marked1) {
ZMapper::unreserve(marked0, size);
return false;
}
if (ZMapper::reserve(remapped, size) != remapped) {
ZMapper::unreserve(marked0, size);
ZMapper::unreserve(marked1, size);
return false;
}
// Register address views with native memory tracker
nmt_reserve(marked0, size);
nmt_reserve(marked1, size);
nmt_reserve(remapped, size);
return true;
assert(res == addr || res == NULL, "Should not reserve other memory than requested");
return res == addr;
}
void ZVirtualMemoryManager::os_unreserve(uintptr_t addr, size_t size) {
ZMapper::unreserve(addr, size);
}

View File

@ -23,12 +23,13 @@
#include "precompiled.hpp"
#include "gc/shared/gcLogPrecious.hpp"
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zAddressSpaceLimit.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zVirtualMemory.inline.hpp"
#include "services/memTracker.hpp"
#include "utilities/debug.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity) :
_manager(),
@ -62,9 +63,7 @@ size_t ZVirtualMemoryManager::reserve_discontiguous(uintptr_t start, size_t size
assert(is_aligned(size, ZGranuleSize), "Misaligned");
if (reserve_contiguous_platform(start, size)) {
// Make the address range free
_manager.free(start, size);
if (reserve_contiguous(start, size)) {
return size;
}
@ -99,16 +98,48 @@ size_t ZVirtualMemoryManager::reserve_discontiguous(size_t size) {
return reserved;
}
bool ZVirtualMemoryManager::reserve_contiguous(uintptr_t start, size_t size) {
assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
// Reserve address views
const uintptr_t marked0 = ZAddress::marked0(start);
const uintptr_t marked1 = ZAddress::marked1(start);
const uintptr_t remapped = ZAddress::remapped(start);
// Reserve address space
if (!os_reserve(marked0, size)) {
return false;
}
if (!os_reserve(marked1, size)) {
os_unreserve(marked0, size);
return false;
}
if (!os_reserve(remapped, size)) {
os_unreserve(marked0, size);
os_unreserve(marked1, size);
return false;
}
// Register address views with native memory tracker
nmt_reserve(marked0, size);
nmt_reserve(marked1, size);
nmt_reserve(remapped, size);
// Make the address range free
_manager.free(start, size);
return true;
}
bool ZVirtualMemoryManager::reserve_contiguous(size_t size) {
// Allow at most 8192 attempts spread evenly across [0, ZAddressOffsetMax)
const size_t unused = ZAddressOffsetMax - size;
const size_t increment = MAX2(align_up(unused / 8192, ZGranuleSize), ZGranuleSize);
for (size_t start = 0; start + size <= ZAddressOffsetMax; start += increment) {
if (reserve_contiguous_platform(start, size)) {
// Make the address range free
_manager.free(start, size);
if (reserve_contiguous(start, size)) {
// Success
return true;
}

View File

@ -50,9 +50,12 @@ private:
ZMemoryManager _manager;
bool _initialized;
// OS specific implementation
void initialize_os();
bool os_reserve(uintptr_t addr, size_t size);
void os_unreserve(uintptr_t addr, size_t size);
bool reserve_contiguous_platform(uintptr_t start, size_t size);
bool reserve_contiguous(uintptr_t start, size_t size);
bool reserve_contiguous(size_t size);
size_t reserve_discontiguous(uintptr_t start, size_t size, size_t min_range);
size_t reserve_discontiguous(size_t size);