--- old/src/hotspot/share/gc/z/zVirtualMemory.cpp 2019-08-09 10:45:18.388770256 +0200 +++ new/src/hotspot/share/gc/z/zVirtualMemory.cpp 2019-08-09 10:45:18.124770265 +0200 @@ -22,11 +22,51 @@ */ #include "precompiled.hpp" +#include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zVirtualMemory.inline.hpp" #include "logging/log.hpp" #include "services/memTracker.hpp" +bool ZVirtualMemoryManager::reserve_range(uintptr_t start, size_t size) { + // Reserve address space + char* const marked0_addr = (char*)ZAddress::marked0(start); + char* const marked1_addr = (char*)ZAddress::marked1(start); + char* const remapped_addr = (char*)ZAddress::remapped(start); + + if (!os::attempt_reserve_memory_at(size, marked0_addr)) { + return false; + } + + if (!os::attempt_reserve_memory_at(size, marked1_addr)) { + os::release_memory(marked0_addr, size); + return false; + } + + if (!os::attempt_reserve_memory_at(size, remapped_addr)) { + os::release_memory(marked0_addr, size); + os::release_memory(marked1_addr, size); + return false; + } + + // Make the address view free + _manager.free(start, size); + return true; +} + +size_t ZVirtualMemoryManager::reserve(uintptr_t start, size_t size) { + if (reserve_range(start, size)) { + return size; + } + + if (size <= ZGranuleSize) { + return 0; + } + + const size_t range = size / 2; + return reserve(start, range) + reserve(start + range, range); +} + ZVirtualMemoryManager::ZVirtualMemoryManager() : _manager(), _initialized(false) { @@ -35,25 +75,15 @@ ZAddressSpaceStart, ZAddressSpaceEnd, ZAddressSpaceSize / K / G); // Reserve address space - if (!reserve(ZAddressSpaceStart, ZAddressSpaceSize)) { + if (reserve(0, ZAddressOffsetMax) < MaxHeapSize) { + log_error(gc)("Failed to reserve enough address space for Java heap"); return; } - // Make the complete address view free - _manager.free(0, ZAddressOffsetMax); - - // Register address space with native memory tracker - nmt_reserve(ZAddressSpaceStart, ZAddressSpaceSize); - // Successfully initialized _initialized = true; } -void ZVirtualMemoryManager::nmt_reserve(uintptr_t start, size_t size) { - MemTracker::record_virtual_memory_reserve((void*)start, size, CALLER_PC); - MemTracker::record_virtual_memory_type((void*)start, mtJavaHeap); -} - bool ZVirtualMemoryManager::is_initialized() const { return _initialized; } --- old/src/hotspot/share/gc/z/zVirtualMemory.hpp 2019-08-09 10:45:19.336770223 +0200 +++ new/src/hotspot/share/gc/z/zVirtualMemory.hpp 2019-08-09 10:45:19.064770232 +0200 @@ -50,8 +50,8 @@ ZMemoryManager _manager; bool _initialized; - bool reserve(uintptr_t start, size_t size); - void nmt_reserve(uintptr_t start, size_t size); + bool reserve_range(uintptr_t start, size_t size); + size_t reserve(uintptr_t start, size_t size); public: ZVirtualMemoryManager(); --- old/src/hotspot/os/linux/gc/z/zVirtualMemory_linux.cpp 2019-08-09 10:45:20.180770193 +0200 +++ /dev/null 2019-02-06 06:50:20.578913862 +0100 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015, 2017, 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" -#include "gc/z/zVirtualMemory.hpp" -#include "logging/log.hpp" - -#include -#include - -bool ZVirtualMemoryManager::reserve(uintptr_t start, size_t size) { - // Reserve address space - const uintptr_t actual_start = (uintptr_t)mmap((void*)start, size, PROT_NONE, - MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); - if (actual_start != start) { - log_error(gc)("Failed to reserve address space for Java heap"); - return false; - } - - return true; -}