@@ -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