comparison src/os/bsd/vm/os_bsd.cpp @ 10969:a837fa3d3f86

8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint Summary: 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
author dcubed
date Thu, 13 Jun 2013 11:16:38 -0700
parents f2110083203d
children 1f4355cee9a2
comparison
equal deleted inserted replaced
10405:f2110083203d 10969:a837fa3d3f86
2072 ::close(fd); 2072 ::close(fd);
2073 unlink(buf); 2073 unlink(buf);
2074 } 2074 }
2075 } 2075 }
2076 2076
2077 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
2078 int err) {
2079 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2080 ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
2081 strerror(err), err);
2082 }
2083
2077 // NOTE: Bsd kernel does not really reserve the pages for us. 2084 // NOTE: Bsd kernel does not really reserve the pages for us.
2078 // All it does is to check if there are enough free pages 2085 // All it does is to check if there are enough free pages
2079 // left at the time of mmap(). This could be a potential 2086 // left at the time of mmap(). This could be a potential
2080 // problem. 2087 // problem.
2081 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { 2088 bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
2082 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2089 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2083 #ifdef __OpenBSD__ 2090 #ifdef __OpenBSD__
2084 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD 2091 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
2085 return ::mprotect(addr, size, prot) == 0; 2092 if (::mprotect(addr, size, prot) == 0) {
2093 return true;
2094 }
2086 #else 2095 #else
2087 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, 2096 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
2088 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); 2097 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
2089 return res != (uintptr_t) MAP_FAILED; 2098 if (res != (uintptr_t) MAP_FAILED) {
2090 #endif 2099 return true;
2091 } 2100 }
2092 2101 #endif
2102
2103 // Warn about any commit errors we see in non-product builds just
2104 // in case mmap() doesn't work as described on the man page.
2105 NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)
2106
2107 return false;
2108 }
2093 2109
2094 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, 2110 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
2095 bool exec) { 2111 bool exec) {
2096 return commit_memory(addr, size, exec); 2112 // alignment_hint is ignored on this OS
2113 return pd_commit_memory(addr, size, exec);
2114 }
2115
2116 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
2117 const char* mesg) {
2118 assert(mesg != NULL, "mesg must be specified");
2119 if (!pd_commit_memory(addr, size, exec)) {
2120 // add extra info in product mode for vm_exit_out_of_memory():
2121 PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
2122 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
2123 }
2124 }
2125
2126 void os::pd_commit_memory_or_exit(char* addr, size_t size,
2127 size_t alignment_hint, bool exec,
2128 const char* mesg) {
2129 // alignment_hint is ignored on this OS
2130 pd_commit_memory_or_exit(addr, size, exec, mesg);
2097 } 2131 }
2098 2132
2099 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2133 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2100 } 2134 }
2101 2135
2146 return res != (uintptr_t) MAP_FAILED; 2180 return res != (uintptr_t) MAP_FAILED;
2147 #endif 2181 #endif
2148 } 2182 }
2149 2183
2150 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { 2184 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
2151 return os::commit_memory(addr, size); 2185 return os::commit_memory(addr, size, !ExecMem);
2152 } 2186 }
2153 2187
2154 // If this is a growable mapping, remove the guard pages entirely by 2188 // If this is a growable mapping, remove the guard pages entirely by
2155 // munmap()ping them. If not, just call uncommit_memory(). 2189 // munmap()ping them. If not, just call uncommit_memory().
2156 bool os::remove_stack_guard_pages(char* addr, size_t size) { 2190 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3510 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); 3544 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
3511 #endif 3545 #endif
3512 3546
3513 if (!UseMembar) { 3547 if (!UseMembar) {
3514 address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 3548 address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3515 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); 3549 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
3516 os::set_memory_serialize_page( mem_serialize_page ); 3550 os::set_memory_serialize_page( mem_serialize_page );
3517 3551
3518 #ifndef PRODUCT 3552 #ifndef PRODUCT
3519 if(Verbose && PrintMiscellaneous) 3553 if(Verbose && PrintMiscellaneous)
3520 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 3554 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);