< prev index next >

src/share/vm/runtime/os.cpp

Print this page
rev 7280 : 8064457: Introduce compressed oops mode "disjoint base" and improve compressed heap handling.

*** 1531,1540 **** --- 1531,1649 ---- MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); } return result; } + // A convenience function which attempts to reserve memory at a number + // of given addresses. An address array is given and first the first, + // then the second is tried and so on. + // Function returns NULL if memory could not be obtained at any of the + // given addresses. + // + // parameters + // bytes - size of block + // addr - array of addresses, NULL terminated + // + char* os::attempt_reserve_memory_at_multiple(size_t bytes, char* addr[]) { + for (int i = 0; addr[i]; i ++) { + char* const attach_point = addr[i]; + assert(attach_point >= (char *)HeapBaseMinAddress, "Flag support broken"); + char* const addr = os::attempt_reserve_memory_at(bytes, attach_point); + if (addr) { + // Note: depending on platform and OS, it is not guaranteed that + // os::attempt_reserve_memory_at only returns requested addr or nothing :/ + if (addr != attach_point) { + os::release_memory(addr, bytes); + } else { + return addr; + } + } + } + + return NULL; + } + + // A convenience function which attempts to reserve memory + // in a given memory range. + char* os::attempt_reserve_memory_in_range(size_t size, size_t alignment, + char* range_from, char* range_to, int num_attempts) { + // sanity checks + if (range_from == 0) { + range_from = (char*) 1; + } + + if (size == 0) { + return NULL; + } + + if (range_to <= range_from) { + return NULL; + } else { + size_t d = range_to - range_from; + if (d < size) { + return NULL; + } + } + + // The necessary attach point alignment (for mmap or shmat to have a + // chance of attaching). + const size_t os_attach_point_alignment = + AIX_ONLY(SIZE_256M) // Known shm boundary alignment. + NOT_AIX(os::vm_allocation_granularity()); + + const size_t attach_point_alignment = + alignment > 0 ? + lcm(alignment, os_attach_point_alignment) : os_attach_point_alignment; + + // Calc address range within we try to attach (range of possible start addresses). + char* const highest_start = (char *)align_ptr_down(range_to - size, attach_point_alignment); + char* const lowest_start = (char *)align_ptr_up(range_from, attach_point_alignment); + const size_t attach_range = highest_start - lowest_start; + + // Default is 20 ... + if (num_attempts <= 0) { + num_attempts = 20; + } + + // ... but cap at possible + const uint64_t num_attempts_possible = + (attach_range / attach_point_alignment) + 1; // at least one is possible even for 0 sized attach range + + if (num_attempts_possible < (uint64_t)num_attempts) { + num_attempts = num_attempts_possible; + } + + const size_t stepsize = + align_size_up(attach_range / num_attempts, attach_point_alignment); + + // Build up attach point array. + char** attach_points = (char**) os::malloc((num_attempts + 1) * sizeof(char*), mtInternal); + assert(attach_points, "OOM"); + + // Fill attach points array. + char* attach_point = highest_start; + int i = 0; + while (i < num_attempts && attach_point >= lowest_start) { + attach_points[i] = attach_point; + i++; + // Handle overflow correctly! + if ((uintptr_t)attach_point > stepsize) { + attach_point -= stepsize; + } else { + attach_point = 0; + } + } + + attach_points[i] = NULL; + + char* addr = os::attempt_reserve_memory_at_multiple(size, attach_points); + + os::free(attach_points); + + return addr; + } + void os::split_reserved_memory(char *base, size_t size, size_t split, bool realloc) { pd_split_reserved_memory(base, size, split, realloc); }
< prev index next >