8234930: Use MAP_JIT when allocating pages for code cache on macOS

Reviewed-by: stuefe, iklam, burban
This commit is contained in:
Anton Kozlov 2020-12-15 18:43:49 +00:00 committed by Thomas Stuefe
parent da2415fed5
commit 2273f9555a
11 changed files with 85 additions and 59 deletions

View file

@ -1678,12 +1678,25 @@ static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
// problem.
bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
#ifdef __OpenBSD__
#if defined(__OpenBSD__)
// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
if (::mprotect(addr, size, prot) == 0) {
return true;
}
#elif defined(__APPLE__)
if (exec) {
// Do not replace MAP_JIT mappings, see JDK-8234930
if (::mprotect(addr, size, prot) == 0) {
return true;
}
} else {
uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
if (res != (uintptr_t) MAP_FAILED) {
return true;
}
}
#else
uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
@ -1766,11 +1779,22 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
}
bool os::pd_uncommit_memory(char* addr, size_t size) {
#ifdef __OpenBSD__
bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {
#if defined(__OpenBSD__)
// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size));
return ::mprotect(addr, size, PROT_NONE) == 0;
#elif defined(__APPLE__)
if (exec) {
if (::madvise(addr, size, MADV_FREE) != 0) {
return false;
}
return ::mprotect(addr, size, PROT_NONE) == 0;
} else {
uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
return res != (uintptr_t) MAP_FAILED;
}
#else
uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
@ -1791,9 +1815,10 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) {
// 'requested_addr' is only treated as a hint, the return value may or
// may not start from the requested address. Unlike Bsd mmap(), this
// function returns NULL to indicate failure.
static char* anon_mmap(char* requested_addr, size_t bytes) {
static char* anon_mmap(char* requested_addr, size_t bytes, bool exec) {
// MAP_FIXED is intentionally left out, to leave existing mappings intact.
const int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
const int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS
MACOS_ONLY(| (exec ? MAP_JIT : 0));
// Map reserved/uncommitted pages PROT_NONE so we fail early if we
// touch an uncommitted page. Otherwise, the read/write might
@ -1807,8 +1832,8 @@ static int anon_munmap(char * addr, size_t size) {
return ::munmap(addr, size) == 0;
}
char* os::pd_reserve_memory(size_t bytes) {
return anon_mmap(NULL /* addr */, bytes);
char* os::pd_reserve_memory(size_t bytes, bool exec) {
return anon_mmap(NULL /* addr */, bytes, exec);
}
bool os::pd_release_memory(char* addr, size_t size) {
@ -1893,7 +1918,7 @@ bool os::can_execute_large_page_memory() {
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
assert(file_desc >= 0, "file_desc is not valid");
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes);
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);
if (result != NULL) {
if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
@ -1905,7 +1930,7 @@ char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, i
// Reserve memory at an arbitrary address, only if that area is
// available (and not reserved for something else).
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes) {
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {
// Assert only that the size is a multiple of the page size, since
// that's all that mmap requires, and since that's all we really know
// about at this low abstraction level. If we need higher alignment,
@ -1918,7 +1943,7 @@ char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes) {
// Bsd mmap allows caller to pass an address as hint; give it a try first,
// if kernel honors the hint then we can return immediately.
char * addr = anon_mmap(requested_addr, bytes);
char * addr = anon_mmap(requested_addr, bytes, exec);
if (addr == requested_addr) {
return requested_addr;
}