Skip to content

Commit acd0e25

Browse files
AntonKozlovVladimir Kempik
authored andcommitted
8255254: Split os::reserve_memory and os::map_memory_to_file interfaces
Reviewed-by: stefank, stuefe
1 parent dc85a3f commit acd0e25

File tree

9 files changed

+116
-83
lines changed

9 files changed

+116
-83
lines changed

src/hotspot/os/aix/os_aix.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2236,7 +2236,7 @@ bool os::can_execute_large_page_memory() {
22362236
return false;
22372237
}
22382238

2239-
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, int file_desc) {
2239+
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
22402240
assert(file_desc >= 0, "file_desc is not valid");
22412241
char* result = NULL;
22422242

src/hotspot/os/bsd/os_bsd.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ bool os::can_execute_large_page_memory() {
19051905
return false;
19061906
}
19071907

1908-
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, int file_desc) {
1908+
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
19091909
assert(file_desc >= 0, "file_desc is not valid");
19101910
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes);
19111911
if (result != NULL) {

src/hotspot/os/linux/os_linux.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4214,7 +4214,7 @@ bool os::can_execute_large_page_memory() {
42144214
return UseTransparentHugePages || UseHugeTLBFS;
42154215
}
42164216

4217-
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, int file_desc) {
4217+
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
42184218
assert(file_desc >= 0, "file_desc is not valid");
42194219
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes);
42204220
if (result != NULL) {

src/hotspot/os/posix/os_posix.cpp

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -297,37 +297,18 @@ char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, in
297297
return map_memory_to_file(base, size, fd);
298298
}
299299

300-
// Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
301-
// so on posix, unmap the section at the start and at the end of the chunk that we mapped
302-
// rather than unmapping and remapping the whole chunk to get requested alignment.
303-
char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
300+
static size_t calculate_aligned_extra_size(size_t size, size_t alignment) {
304301
assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
305302
"Alignment must be a multiple of allocation granularity (page size)");
306303
assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
307304

308305
size_t extra_size = size + alignment;
309306
assert(extra_size >= size, "overflow, size is too large to allow alignment");
307+
return extra_size;
308+
}
310309

311-
char* extra_base;
312-
if (file_desc != -1) {
313-
// For file mapping, we do not call os:reserve_memory_with_fd since:
314-
// - we later chop away parts of the mapping using os::release_memory and that could fail if the
315-
// original mmap call had been tied to an fd.
316-
// - The memory API os::reserve_memory uses is an implementation detail. It may (and usually is)
317-
// mmap but it also may System V shared memory which cannot be uncommitted as a whole, so
318-
// chopping off and unmapping excess bits back and front (see below) would not work.
319-
extra_base = reserve_mmapped_memory(extra_size, NULL);
320-
if (extra_base != NULL) {
321-
MemTracker::record_virtual_memory_reserve((address)extra_base, extra_size, CALLER_PC);
322-
}
323-
} else {
324-
extra_base = os::reserve_memory(extra_size);
325-
}
326-
327-
if (extra_base == NULL) {
328-
return NULL;
329-
}
330-
310+
// After a bigger chunk was mapped, unmaps start and end parts to get the requested alignment.
311+
static char* chop_extra_memory(size_t size, size_t alignment, char* extra_base, size_t extra_size) {
331312
// Do manual alignment
332313
char* aligned_base = align_up(extra_base, alignment);
333314

@@ -349,13 +330,39 @@ char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
349330
os::release_memory(extra_base + begin_offset + size, end_offset);
350331
}
351332

352-
if (file_desc != -1) {
353-
// After we have an aligned address, we can replace anonymous mapping with file mapping
354-
if (replace_existing_mapping_with_file_mapping(aligned_base, size, file_desc) == NULL) {
355-
vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
356-
}
357-
MemTracker::record_virtual_memory_commit((address)aligned_base, size, CALLER_PC);
333+
return aligned_base;
334+
}
335+
336+
// Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
337+
// so on posix, unmap the section at the start and at the end of the chunk that we mapped
338+
// rather than unmapping and remapping the whole chunk to get requested alignment.
339+
char* os::reserve_memory_aligned(size_t size, size_t alignment) {
340+
size_t extra_size = calculate_aligned_extra_size(size, alignment);
341+
char* extra_base = os::reserve_memory(extra_size);
342+
if (extra_base == NULL) {
343+
return NULL;
344+
}
345+
return chop_extra_memory(size, alignment, extra_base, extra_size);
346+
}
347+
348+
char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int file_desc) {
349+
size_t extra_size = calculate_aligned_extra_size(size, alignment);
350+
// For file mapping, we do not call os:map_memory_to_file(size,fd) since:
351+
// - we later chop away parts of the mapping using os::release_memory and that could fail if the
352+
// original mmap call had been tied to an fd.
353+
// - The memory API os::reserve_memory uses is an implementation detail. It may (and usually is)
354+
// mmap but it also may System V shared memory which cannot be uncommitted as a whole, so
355+
// chopping off and unmapping excess bits back and front (see below) would not work.
356+
char* extra_base = reserve_mmapped_memory(extra_size, NULL);
357+
if (extra_base == NULL) {
358+
return NULL;
359+
}
360+
char* aligned_base = chop_extra_memory(size, alignment, extra_base, extra_size);
361+
// After we have an aligned address, we can replace anonymous mapping with file mapping
362+
if (replace_existing_mapping_with_file_mapping(aligned_base, size, file_desc) == NULL) {
363+
vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
358364
}
365+
MemTracker::record_virtual_memory_commit((address)aligned_base, size, CALLER_PC);
359366
return aligned_base;
360367
}
361368

src/hotspot/os/windows/os_windows.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,7 +3137,7 @@ void os::split_reserved_memory(char *base, size_t size, size_t split) {
31373137
// Multiple threads can race in this code but it's not possible to unmap small sections of
31383138
// virtual space to get requested alignment, like posix-like os's.
31393139
// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
3140-
char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
3140+
static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
31413141
assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
31423142
"Alignment must be a multiple of allocation granularity (page size)");
31433143
assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
@@ -3148,7 +3148,9 @@ char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
31483148
char* aligned_base = NULL;
31493149

31503150
do {
3151-
char* extra_base = os::reserve_memory_with_fd(extra_size, file_desc);
3151+
char* extra_base = file_desc != -1 ?
3152+
os::map_memory_to_file(extra_size, file_desc) :
3153+
os::reserve_memory(extra_size);
31523154
if (extra_base == NULL) {
31533155
return NULL;
31543156
}
@@ -3161,13 +3163,23 @@ char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
31613163
os::release_memory(extra_base, extra_size);
31623164
}
31633165

3164-
aligned_base = os::attempt_reserve_memory_at(aligned_base, size, file_desc);
3166+
aligned_base = file_desc != -1 ?
3167+
os::attempt_map_memory_to_file_at(aligned_base, size, file_desc) :
3168+
os::attempt_reserve_memory_at(aligned_base, size);
31653169

31663170
} while (aligned_base == NULL);
31673171

31683172
return aligned_base;
31693173
}
31703174

3175+
char* os::reserve_memory_aligned(size_t size, size_t alignment) {
3176+
return map_or_reserve_memory_aligned(size, alignment, -1 /* file_desc */);
3177+
}
3178+
3179+
char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int fd) {
3180+
return map_or_reserve_memory_aligned(size, alignment, fd);
3181+
}
3182+
31713183
char* os::pd_reserve_memory(size_t bytes) {
31723184
return pd_attempt_reserve_memory_at(NULL /* addr */, bytes);
31733185
}
@@ -3205,7 +3217,7 @@ char* os::pd_attempt_reserve_memory_at(char* addr, size_t bytes) {
32053217
return res;
32063218
}
32073219

3208-
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, int file_desc) {
3220+
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
32093221
assert(file_desc >= 0, "file_desc is not valid");
32103222
return map_memory_to_file(requested_addr, bytes, file_desc);
32113223
}

src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ static bool map_nvdimm_space(ReservedSpace rs) {
220220
return false;
221221
}
222222
// commit this memory in nv-dimm
223-
char* ret = os::attempt_reserve_memory_at(rs.base(), rs.size(), _backing_fd);
223+
char* ret = os::attempt_map_memory_to_file_at(rs.base(), rs.size(), _backing_fd);
224224

225225
if (ret != rs.base()) {
226226
if (ret != NULL) {

src/hotspot/share/memory/virtualspace.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,30 @@ ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
8080
_executable = executable;
8181
}
8282

83+
// Helper method
84+
static char* attempt_map_or_reserve_memory_at(char* base, size_t size, int fd) {
85+
if (fd != -1) {
86+
return os::attempt_map_memory_to_file_at(base, size, fd);
87+
}
88+
return os::attempt_reserve_memory_at(base, size);
89+
}
90+
91+
// Helper method
92+
static char* map_or_reserve_memory(size_t size, int fd) {
93+
if (fd != -1) {
94+
return os::map_memory_to_file(size, fd);
95+
}
96+
return os::reserve_memory(size);
97+
}
98+
99+
// Helper method
100+
static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fd) {
101+
if (fd != -1) {
102+
return os::map_memory_to_file_aligned(size, alignment, fd);
103+
}
104+
return os::reserve_memory_aligned(size, alignment);
105+
}
106+
83107
// Helper method
84108
static void unmap_or_release_memory(char* base, size_t size, bool is_file_mapped) {
85109
if (is_file_mapped) {
@@ -188,13 +212,13 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
188212
// important. If available space is not detected, return NULL.
189213

190214
if (requested_address != 0) {
191-
base = os::attempt_reserve_memory_at(requested_address, size, _fd_for_heap);
215+
base = attempt_map_or_reserve_memory_at(requested_address, size, _fd_for_heap);
192216
if (failed_to_reserve_as_requested(base, requested_address, size, false, _fd_for_heap != -1)) {
193217
// OS ignored requested address. Try different address.
194218
base = NULL;
195219
}
196220
} else {
197-
base = os::reserve_memory_with_fd(size, _fd_for_heap);
221+
base = map_or_reserve_memory(size, _fd_for_heap);
198222
}
199223

200224
if (base == NULL) return;
@@ -206,7 +230,7 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
206230

207231
// Make sure that size is aligned
208232
size = align_up(size, alignment);
209-
base = os::reserve_memory_aligned(size, alignment, _fd_for_heap);
233+
base = map_or_reserve_memory_aligned(size, alignment, _fd_for_heap);
210234

211235
if (requested_address != 0 &&
212236
failed_to_reserve_as_requested(base, requested_address, size, false, _fd_for_heap != -1)) {
@@ -372,13 +396,13 @@ void ReservedHeapSpace::try_reserve_heap(size_t size,
372396
}
373397

374398
if (requested_address != 0) {
375-
base = os::attempt_reserve_memory_at(requested_address, size, _fd_for_heap);
399+
base = attempt_map_or_reserve_memory_at(requested_address, size, _fd_for_heap);
376400
} else {
377401
// Optimistically assume that the OSes returns an aligned base pointer.
378402
// When reserving a large address range, most OSes seem to align to at
379403
// least 64K.
380404
// If the returned memory is not aligned we will release and retry.
381-
base = os::reserve_memory_with_fd(size, _fd_for_heap);
405+
base = map_or_reserve_memory(size, _fd_for_heap);
382406
}
383407
}
384408
if (base == NULL) { return; }

src/hotspot/share/runtime/os.cpp

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,38 +1658,10 @@ char* os::reserve_memory(size_t bytes, MEMFLAGS flags) {
16581658
return result;
16591659
}
16601660

1661-
char* os::reserve_memory_with_fd(size_t bytes, int file_desc) {
1662-
char* result;
1663-
1664-
if (file_desc != -1) {
1665-
// Could have called pd_reserve_memory() followed by replace_existing_mapping_with_file_mapping(),
1666-
// but AIX may use SHM in which case its more trouble to detach the segment and remap memory to the file.
1667-
result = os::map_memory_to_file(NULL /* addr */, bytes, file_desc);
1668-
if (result != NULL) {
1669-
MemTracker::record_virtual_memory_reserve_and_commit(result, bytes, CALLER_PC);
1670-
}
1671-
} else {
1672-
result = pd_reserve_memory(bytes);
1673-
if (result != NULL) {
1674-
MemTracker::record_virtual_memory_reserve(result, bytes, CALLER_PC);
1675-
}
1676-
}
1677-
1678-
return result;
1679-
}
1680-
1681-
char* os::attempt_reserve_memory_at(char* addr, size_t bytes, int file_desc) {
1682-
char* result = NULL;
1683-
if (file_desc != -1) {
1684-
result = pd_attempt_reserve_memory_at(addr, bytes, file_desc);
1685-
if (result != NULL) {
1686-
MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
1687-
}
1688-
} else {
1689-
result = pd_attempt_reserve_memory_at(addr, bytes);
1690-
if (result != NULL) {
1691-
MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
1692-
}
1661+
char* os::attempt_reserve_memory_at(char* addr, size_t bytes) {
1662+
char* result = pd_attempt_reserve_memory_at(addr, bytes);
1663+
if (result != NULL) {
1664+
MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
16931665
}
16941666
return result;
16951667
}
@@ -1758,6 +1730,25 @@ void os::pretouch_memory(void* start, void* end, size_t page_size) {
17581730
}
17591731
}
17601732

1733+
char* os::map_memory_to_file(size_t bytes, int file_desc) {
1734+
// Could have called pd_reserve_memory() followed by replace_existing_mapping_with_file_mapping(),
1735+
// but AIX may use SHM in which case its more trouble to detach the segment and remap memory to the file.
1736+
// On all current implementations NULL is interpreted as any available address.
1737+
char* result = os::map_memory_to_file(NULL /* addr */, bytes, file_desc);
1738+
if (result != NULL) {
1739+
MemTracker::record_virtual_memory_reserve_and_commit(result, bytes, CALLER_PC);
1740+
}
1741+
return result;
1742+
}
1743+
1744+
char* os::attempt_map_memory_to_file_at(char* addr, size_t bytes, int file_desc) {
1745+
char* result = pd_attempt_map_memory_to_file_at(addr, bytes, file_desc);
1746+
if (result != NULL) {
1747+
MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
1748+
}
1749+
return result;
1750+
}
1751+
17611752
char* os::map_memory(int fd, const char* file_name, size_t file_offset,
17621753
char *addr, size_t bytes, bool read_only,
17631754
bool allow_exec, MEMFLAGS flags) {

src/hotspot/share/runtime/os.hpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ class os: AllStatic {
116116
static char* pd_reserve_memory(size_t bytes);
117117

118118
static char* pd_attempt_reserve_memory_at(char* addr, size_t bytes);
119-
static char* pd_attempt_reserve_memory_at(char* addr, size_t bytes, int file_desc);
120119

121120
static bool pd_commit_memory(char* addr, size_t bytes, bool executable);
122121
static bool pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
@@ -131,6 +130,8 @@ class os: AllStatic {
131130
static bool pd_uncommit_memory(char* addr, size_t bytes);
132131
static bool pd_release_memory(char* addr, size_t bytes);
133132

133+
static char* pd_attempt_map_memory_to_file_at(char* addr, size_t bytes, int file_desc);
134+
134135
static char* pd_map_memory(int fd, const char* file_name, size_t file_offset,
135136
char *addr, size_t bytes, bool read_only = false,
136137
bool allow_exec = false);
@@ -313,19 +314,14 @@ class os: AllStatic {
313314
static int vm_allocation_granularity();
314315

315316
// Reserves virtual memory.
316-
// alignment_hint - currently only used by AIX
317317
static char* reserve_memory(size_t bytes, MEMFLAGS flags = mtOther);
318318

319-
// Reserves virtual memory.
320-
// if file_desc != -1, also attaches the memory to the file.
321-
static char* reserve_memory_with_fd(size_t bytes, int file_desc);
322-
323319
// Reserves virtual memory that starts at an address that is aligned to 'alignment'.
324-
static char* reserve_memory_aligned(size_t size, size_t alignment, int file_desc = -1);
320+
static char* reserve_memory_aligned(size_t size, size_t alignment);
325321

326322
// Attempts to reserve the virtual memory at [addr, addr + bytes).
327323
// Does not overwrite existing mappings.
328-
static char* attempt_reserve_memory_at(char* addr, size_t bytes, int file_desc = -1);
324+
static char* attempt_reserve_memory_at(char* addr, size_t bytes);
329325

330326
// Split a reserved memory region [base, base+size) into two regions [base, base+split) and
331327
// [base+split, base+size).
@@ -370,7 +366,10 @@ class os: AllStatic {
370366
static int create_file_for_heap(const char* dir);
371367
// Map memory to the file referred by fd. This function is slightly different from map_memory()
372368
// and is added to be used for implementation of -XX:AllocateHeapAt
369+
static char* map_memory_to_file(size_t size, int fd);
370+
static char* map_memory_to_file_aligned(size_t size, size_t alignment, int fd);
373371
static char* map_memory_to_file(char* base, size_t size, int fd);
372+
static char* attempt_map_memory_to_file_at(char* base, size_t size, int fd);
374373
// Replace existing reserved memory with file mapping
375374
static char* replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd);
376375

0 commit comments

Comments
 (0)