mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 06:14:49 +02:00
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory(). Add os::commit_memory_or_exit(). Also tidy up some NMT accounting and some mmap() return value checking. Reviewed-by: zgu, stefank, dholmes, dsamersoff
This commit is contained in:
parent
718f3252f6
commit
72a51a0c44
18 changed files with 357 additions and 80 deletions
|
@ -2074,6 +2074,13 @@ void bsd_wrap_code(char* base, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
|
||||
int err) {
|
||||
warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
|
||||
", %d) failed; error='%s' (errno=%d)", addr, size, exec,
|
||||
strerror(err), err);
|
||||
}
|
||||
|
||||
// NOTE: Bsd kernel does not really reserve the pages for us.
|
||||
// All it does is to check if there are enough free pages
|
||||
// left at the time of mmap(). This could be a potential
|
||||
|
@ -2082,18 +2089,45 @@ 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__
|
||||
// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
|
||||
return ::mprotect(addr, size, prot) == 0;
|
||||
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);
|
||||
return res != (uintptr_t) MAP_FAILED;
|
||||
if (res != (uintptr_t) MAP_FAILED) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Warn about any commit errors we see in non-product builds just
|
||||
// in case mmap() doesn't work as described on the man page.
|
||||
NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
|
||||
bool exec) {
|
||||
return commit_memory(addr, size, exec);
|
||||
// alignment_hint is ignored on this OS
|
||||
return pd_commit_memory(addr, size, exec);
|
||||
}
|
||||
|
||||
void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
|
||||
const char* mesg) {
|
||||
assert(mesg != NULL, "mesg must be specified");
|
||||
if (!pd_commit_memory(addr, size, exec)) {
|
||||
// add extra info in product mode for vm_exit_out_of_memory():
|
||||
PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
|
||||
vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
|
||||
}
|
||||
}
|
||||
|
||||
void os::pd_commit_memory_or_exit(char* addr, size_t size,
|
||||
size_t alignment_hint, bool exec,
|
||||
const char* mesg) {
|
||||
// alignment_hint is ignored on this OS
|
||||
pd_commit_memory_or_exit(addr, size, exec, mesg);
|
||||
}
|
||||
|
||||
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
|
||||
|
@ -2148,7 +2182,7 @@ bool os::pd_uncommit_memory(char* addr, size_t size) {
|
|||
}
|
||||
|
||||
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
|
||||
return os::commit_memory(addr, size);
|
||||
return os::commit_memory(addr, size, !ExecMem);
|
||||
}
|
||||
|
||||
// If this is a growable mapping, remove the guard pages entirely by
|
||||
|
@ -3512,7 +3546,7 @@ jint os::init_2(void)
|
|||
|
||||
if (!UseMembar) {
|
||||
address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
|
||||
guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
|
||||
os::set_memory_serialize_page( mem_serialize_page );
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue