Skip to content

Commit 13d0bac

Browse files
committed
8224820: ZGC: Support discontiguous heap reservations
Reviewed-by: pliden, stefank
1 parent 8743f0b commit 13d0bac

File tree

5 files changed

+106
-54
lines changed

5 files changed

+106
-54
lines changed

src/hotspot/os/linux/gc/z/zVirtualMemory_linux.cpp

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include "precompiled.hpp"
25+
#include "gc/z/zAddress.inline.hpp"
26+
#include "gc/z/zVirtualMemory.hpp"
27+
#include "logging/log.hpp"
28+
29+
#include <sys/mman.h>
30+
#include <sys/types.h>
31+
32+
static void unmap(uintptr_t start, size_t size) {
33+
const int res = munmap((void*)start, size);
34+
assert(res == 0, "Failed to unmap memory");
35+
}
36+
37+
static bool map(uintptr_t start, size_t size) {
38+
const void* const res = mmap((void*)start, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
39+
if (res == MAP_FAILED) {
40+
// Failed to reserve memory
41+
return false;
42+
}
43+
44+
if ((uintptr_t)res != start) {
45+
// Failed to reserve memory at the requested address
46+
unmap(start, size);
47+
return false;
48+
}
49+
50+
// Success
51+
return true;
52+
}
53+
54+
bool ZVirtualMemoryManager::reserve_platform(uintptr_t start, size_t size) {
55+
// Reserve address views
56+
const uintptr_t marked0 = ZAddress::marked0(start);
57+
const uintptr_t marked1 = ZAddress::marked1(start);
58+
const uintptr_t remapped = ZAddress::remapped(start);
59+
60+
if (!map(marked0, size)) {
61+
return false;
62+
}
63+
64+
if (!map(marked1, size)) {
65+
unmap(marked0, size);
66+
return false;
67+
}
68+
69+
if (!map(remapped, size)) {
70+
unmap(marked0, size);
71+
unmap(marked1, size);
72+
return false;
73+
}
74+
75+
// Register address views with native memory tracker
76+
nmt_reserve(marked0, size);
77+
nmt_reserve(marked1, size);
78+
nmt_reserve(remapped, size);
79+
80+
return true;
81+
}

src/hotspot/share/gc/z/zPageAllocator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ ZPageAllocator::ZPageAllocator(size_t min_capacity,
9494
size_t max_capacity,
9595
size_t max_reserve) :
9696
_lock(),
97-
_virtual(),
97+
_virtual(max_capacity),
9898
_physical(),
9999
_cache(),
100100
_min_capacity(min_capacity),

src/hotspot/share/gc/z/zVirtualMemory.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,39 @@
2727
#include "logging/log.hpp"
2828
#include "services/memTracker.hpp"
2929

30-
ZVirtualMemoryManager::ZVirtualMemoryManager() :
30+
ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity) :
3131
_manager(),
3232
_initialized(false) {
3333

34-
log_info(gc, init)("Address Space: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "T)",
35-
ZAddressSpaceStart, ZAddressSpaceEnd, ZAddressSpaceSize / K / G);
34+
log_info(gc, init)("Address Space: " SIZE_FORMAT "T", ZAddressOffsetMax / K / G);
3635

3736
// Reserve address space
38-
if (!reserve(ZAddressSpaceStart, ZAddressSpaceSize)) {
37+
if (reserve(0, ZAddressOffsetMax) < max_capacity) {
38+
log_error(gc)("Failed to reserve address space for Java heap");
3939
return;
4040
}
4141

42-
// Make the complete address view free
43-
_manager.free(0, ZAddressOffsetMax);
44-
45-
// Register address space with native memory tracker
46-
nmt_reserve(ZAddressSpaceStart, ZAddressSpaceSize);
47-
4842
// Successfully initialized
4943
_initialized = true;
5044
}
5145

46+
size_t ZVirtualMemoryManager::reserve(uintptr_t start, size_t size) {
47+
if (size < ZGranuleSize) {
48+
// Too small
49+
return 0;
50+
}
51+
52+
if (!reserve_platform(start, size)) {
53+
const size_t half = size / 2;
54+
return reserve(start, half) + reserve(start + half, half);
55+
}
56+
57+
// Make the address range free
58+
_manager.free(start, size);
59+
60+
return size;
61+
}
62+
5263
void ZVirtualMemoryManager::nmt_reserve(uintptr_t start, size_t size) {
5364
MemTracker::record_virtual_memory_reserve((void*)start, size, CALLER_PC);
5465
MemTracker::record_virtual_memory_type((void*)start, mtJavaHeap);

src/hotspot/share/gc/z/zVirtualMemory.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@ class ZVirtualMemoryManager {
5050
ZMemoryManager _manager;
5151
bool _initialized;
5252

53-
bool reserve(uintptr_t start, size_t size);
53+
bool reserve_platform(uintptr_t start, size_t size);
54+
size_t reserve(uintptr_t start, size_t size);
5455
void nmt_reserve(uintptr_t start, size_t size);
5556

5657
public:
57-
ZVirtualMemoryManager();
58+
ZVirtualMemoryManager(size_t max_capacity);
5859

5960
bool is_initialized() const;
6061

0 commit comments

Comments
 (0)