src/os/windows/vm/os_windows.cpp
Print this page
*** 2516,2526 ****
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
os::commit_memory((char *)addr, thread->stack_base() - addr,
! false );
return EXCEPTION_CONTINUE_EXECUTION;
}
else
#endif
{
--- 2516,2526 ----
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
os::commit_memory((char *)addr, thread->stack_base() - addr,
! !ExecMem);
return EXCEPTION_CONTINUE_EXECUTION;
}
else
#endif
{
*** 3164,3173 ****
--- 3164,3182 ----
}
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.
return true;
}
*** 3178,3193 ****
// unless we have NUMAInterleaving enabled, the range of a commit
// 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 (exec) {
DWORD oldprot;
// Windows doc says to use VirtualProtect to get execute permissions
! if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
}
return true;
} else {
// when NUMAInterleaving is enabled, the commit might cover a range that
// came from multiple VirtualAlloc reserves (using allocate_pages_individually).
--- 3187,3208 ----
// unless we have NUMAInterleaving enabled, the range of a commit
// 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) {
! 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)) {
! NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
! return false;
}
+ }
return true;
} else {
// when NUMAInterleaving is enabled, the commit might cover a range that
// came from multiple VirtualAlloc reserves (using allocate_pages_individually).
*** 3197,3213 ****
char * next_alloc_addr = addr;
while (bytes_remaining > 0) {
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)
return false;
if (exec) {
DWORD oldprot;
! if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
return false;
}
bytes_remaining -= bytes_to_rq;
next_alloc_addr += bytes_to_rq;
}
}
// if we made it this far, return true
--- 3212,3236 ----
char * next_alloc_addr = addr;
while (bytes_remaining > 0) {
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) {
! 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)) {
! 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;
}
}
// if we made it this far, return true
*** 3214,3226 ****
return true;
}
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
bool exec) {
! return commit_memory(addr, size, exec);
}
bool os::pd_uncommit_memory(char* addr, size_t bytes) {
if (bytes == 0) {
// Don't bother the OS with noops.
return true;
}
--- 3237,3266 ----
return true;
}
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
bool 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) {
if (bytes == 0) {
// Don't bother the OS with noops.
return true;
}
*** 3232,3242 ****
bool os::pd_release_memory(char* addr, size_t bytes) {
return VirtualFree(addr, 0, MEM_RELEASE) != 0;
}
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
! return os::commit_memory(addr, size);
}
bool os::remove_stack_guard_pages(char* addr, size_t size) {
return os::uncommit_memory(addr, size);
}
--- 3272,3282 ----
bool os::pd_release_memory(char* addr, size_t bytes) {
return VirtualFree(addr, 0, MEM_RELEASE) != 0;
}
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
! return os::commit_memory(addr, size, !ExecMem);
}
bool os::remove_stack_guard_pages(char* addr, size_t size) {
return os::uncommit_memory(addr, size);
}
*** 3256,3267 ****
DWORD old_status;
// 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");
}
// One cannot use os::guard_memory() here, as on Win32 guard page
// have different (one-shot) semantics, from MSDN on PAGE_GUARD:
//
// Pages in the region become guard pages. Any attempt to access a guard page
--- 3296,3308 ----
DWORD old_status;
// 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_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:
//
// Pages in the region become guard pages. Any attempt to access a guard page