mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +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
|
@ -2524,7 +2524,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
|||
addr = (address)((uintptr_t)addr &
|
||||
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
|
||||
os::commit_memory((char *)addr, thread->stack_base() - addr,
|
||||
false );
|
||||
!ExecMem);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
else
|
||||
|
@ -3172,6 +3172,15 @@ bool os::release_memory_special(char* base, size_t bytes) {
|
|||
void os::print_statistics() {
|
||||
}
|
||||
|
||||
static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {
|
||||
int err = os::get_last_error();
|
||||
char buf[256];
|
||||
size_t buf_len = os::lasterror(buf, sizeof(buf));
|
||||
warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
|
||||
", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,
|
||||
exec, buf_len != 0 ? buf : "<no_error_string>", err);
|
||||
}
|
||||
|
||||
bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
|
||||
if (bytes == 0) {
|
||||
// Don't bother the OS with noops.
|
||||
|
@ -3186,11 +3195,17 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
|
|||
// is always within a reserve covered by a single VirtualAlloc
|
||||
// in that case we can just do a single commit for the requested size
|
||||
if (!UseNUMAInterleaving) {
|
||||
if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false;
|
||||
if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {
|
||||
NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
|
||||
return false;
|
||||
}
|
||||
if (exec) {
|
||||
DWORD oldprot;
|
||||
// Windows doc says to use VirtualProtect to get execute permissions
|
||||
if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
|
||||
if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {
|
||||
NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
@ -3205,12 +3220,20 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
|
|||
MEMORY_BASIC_INFORMATION alloc_info;
|
||||
VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
|
||||
size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
|
||||
if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL)
|
||||
if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,
|
||||
PAGE_READWRITE) == NULL) {
|
||||
NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
|
||||
exec);)
|
||||
return false;
|
||||
}
|
||||
if (exec) {
|
||||
DWORD oldprot;
|
||||
if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
|
||||
if (!VirtualProtect(next_alloc_addr, bytes_to_rq,
|
||||
PAGE_EXECUTE_READWRITE, &oldprot)) {
|
||||
NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
|
||||
exec);)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bytes_remaining -= bytes_to_rq;
|
||||
next_alloc_addr += bytes_to_rq;
|
||||
|
@ -3222,7 +3245,24 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
|
|||
|
||||
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)) {
|
||||
warn_fail_commit_memory(addr, size, exec);
|
||||
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);
|
||||
}
|
||||
|
||||
bool os::pd_uncommit_memory(char* addr, size_t bytes) {
|
||||
|
@ -3240,7 +3280,7 @@ bool os::pd_release_memory(char* addr, size_t bytes) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool os::remove_stack_guard_pages(char* addr, size_t size) {
|
||||
|
@ -3264,8 +3304,9 @@ bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
|
|||
|
||||
// Strange enough, but on Win32 one can change protection only for committed
|
||||
// memory, not a big deal anyway, as bytes less or equal than 64K
|
||||
if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
|
||||
fatal("cannot commit protection page");
|
||||
if (!is_committed) {
|
||||
commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
|
||||
"cannot commit protection page");
|
||||
}
|
||||
// One cannot use os::guard_memory() here, as on Win32 guard page
|
||||
// have different (one-shot) semantics, from MSDN on PAGE_GUARD:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue