Skip to content

Commit 250b45a

Browse files
committed
8266222: [aix] In mmap-mode, partial releases with os::release_memory may trash internal bookkeeping
Reviewed-by: mdoerr
1 parent 65ce4d2 commit 250b45a

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

src/hotspot/os/aix/os_aix.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,7 @@ bool os::pd_release_memory(char* addr, size_t size) {
19891989
// Dynamically do different things for mmap/shmat.
19901990
vmembk_t* const vmi = vmembk_find(addr);
19911991
guarantee0(vmi);
1992+
vmi->assert_is_valid_subrange(addr, size);
19921993

19931994
// Always round to os::vm_page_size(), which may be larger than 4K.
19941995
size = align_up(size, os::vm_page_size());
@@ -2002,20 +2003,37 @@ bool os::pd_release_memory(char* addr, size_t size) {
20022003
// - If user only wants to release a partial range, uncommit (disclaim) that
20032004
// range. That way, at least, we do not use memory anymore (bust still page
20042005
// table space).
2005-
vmi->assert_is_valid_subrange(addr, size);
20062006
if (addr == vmi->addr && size == vmi->size) {
20072007
rc = release_shmated_memory(addr, size);
20082008
remove_bookkeeping = true;
20092009
} else {
20102010
rc = uncommit_shmated_memory(addr, size);
20112011
}
20122012
} else {
2013-
// User may unmap partial regions but region has to be fully contained.
2014-
#ifdef ASSERT
2015-
vmi->assert_is_valid_subrange(addr, size);
2016-
#endif
2013+
// In mmap-mode:
2014+
// - If the user wants to release the full range, we do that and remove the mapping.
2015+
// - If the user wants to release part of the range, we release that part, but need
2016+
// to adjust bookkeeping.
2017+
assert(is_aligned(size, 4 * K), "Sanity");
20172018
rc = release_mmaped_memory(addr, size);
2018-
remove_bookkeeping = true;
2019+
if (addr == vmi->addr && size == vmi->size) {
2020+
remove_bookkeeping = true;
2021+
} else {
2022+
if (addr == vmi->addr && size < vmi->size) {
2023+
// Chopped from head
2024+
vmi->addr += size;
2025+
vmi->size -= size;
2026+
} else if (addr + size == vmi->addr + vmi->size) {
2027+
// Chopped from tail
2028+
vmi->size -= size;
2029+
} else {
2030+
// releasing a mapping in the middle of the original mapping:
2031+
// For now we forbid this, since this is an invalid scenario
2032+
// (the bookkeeping is easy enough to fix if needed but there
2033+
// is no use case for it; any occurrence is likely an error.
2034+
ShouldNotReachHere();
2035+
}
2036+
}
20192037
}
20202038

20212039
// update bookkeeping

0 commit comments

Comments
 (0)