Mercurial > hg > graal-jvmci-8
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); |