Wed, 27 Mar 2013 19:21:18 +0100
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
Summary: Ergonomics now also takes available virtual memory into account when deciding for a heap size. The helper method to determine the maximum allocatable memory block now uses the appropriate OS specific calls to retrieve available virtual memory for the java process. In 32 bit environments this method now also searches for the maximum actually reservable amount of memory. Merge previously separate implementations for Linux/BSD/Solaris into a single method.
Reviewed-by: jmasa, tamao
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
26 #define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
28 #include "runtime/atomic.inline.hpp"
29 #include "runtime/os.hpp"
31 #ifdef TARGET_OS_ARCH_solaris_x86
32 # include "orderAccess_solaris_x86.inline.hpp"
33 #endif
34 #ifdef TARGET_OS_ARCH_solaris_sparc
35 # include "orderAccess_solaris_sparc.inline.hpp"
36 #endif
38 // System includes
39 #include <sys/param.h>
40 #include <dlfcn.h>
41 #include <sys/socket.h>
42 #include <sys/poll.h>
43 #include <sys/filio.h>
44 #include <unistd.h>
45 #include <netdb.h>
46 #include <setjmp.h>
48 inline const char* os::file_separator() { return "/"; }
49 inline const char* os::line_separator() { return "\n"; }
50 inline const char* os::path_separator() { return ":"; }
52 // File names are case-sensitive on windows only
53 inline int os::file_name_strcmp(const char* s1, const char* s2) {
54 return strcmp(s1, s2);
55 }
57 inline bool os::uses_stack_guard_pages() {
58 return true;
59 }
61 inline bool os::allocate_stack_guard_pages() {
62 assert(uses_stack_guard_pages(), "sanity check");
63 int r = thr_main() ;
64 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
65 return r;
66 }
69 // On Solaris, reservations are made on a page by page basis, nothing to do.
70 inline void os::pd_split_reserved_memory(char *base, size_t size,
71 size_t split, bool realloc) {
72 }
75 // Bang the shadow pages if they need to be touched to be mapped.
76 inline void os::bang_stack_shadow_pages() {
77 }
78 inline void os::dll_unload(void *lib) { ::dlclose(lib); }
80 inline DIR* os::opendir(const char* dirname) {
81 assert(dirname != NULL, "just checking");
82 return ::opendir(dirname);
83 }
85 inline int os::readdir_buf_size(const char *path) {
86 int size = pathconf(path, _PC_NAME_MAX);
87 return (size < 0 ? MAXPATHLEN : size) + sizeof(dirent) + 1;
88 }
90 inline struct dirent* os::readdir(DIR* dirp, dirent* dbuf) {
91 assert(dirp != NULL, "just checking");
92 #if defined(_LP64) || defined(_GNU_SOURCE)
93 dirent* p;
94 int status;
96 if((status = ::readdir_r(dirp, dbuf, &p)) != 0) {
97 errno = status;
98 return NULL;
99 } else
100 return p;
101 #else // defined(_LP64) || defined(_GNU_SOURCE)
102 return ::readdir_r(dirp, dbuf);
103 #endif // defined(_LP64) || defined(_GNU_SOURCE)
104 }
106 inline int os::closedir(DIR *dirp) {
107 assert(dirp != NULL, "argument is NULL");
108 return ::closedir(dirp);
109 }
111 //////////////////////////////////////////////////////////////////////////////
112 ////////////////////////////////////////////////////////////////////////////////
114 // macros for interruptible io and system calls and system call restarting
116 #define _INTERRUPTIBLE(_setup, _cmd, _result, _thread, _clear, _before, _after, _int_enable) \
117 do { \
118 _setup; \
119 _before; \
120 OSThread* _osthread = _thread->osthread(); \
121 if (_int_enable && _thread->has_last_Java_frame()) { \
122 /* this is java interruptible io stuff */ \
123 if (os::is_interrupted(_thread, _clear)) { \
124 os::Solaris::bump_interrupted_before_count(); \
125 _result = OS_INTRPT; \
126 } else { \
127 /* _cmd always expands to an assignment to _result */ \
128 if ((_cmd) < 0 && errno == EINTR \
129 && os::is_interrupted(_thread, _clear)) { \
130 os::Solaris::bump_interrupted_during_count(); \
131 _result = OS_INTRPT; \
132 } \
133 } \
134 } else { \
135 /* this is normal blocking io stuff */ \
136 _cmd; \
137 } \
138 _after; \
139 } while(false)
141 // Interruptible io support + restarting of interrupted system calls
143 #ifndef ASSERT
145 #define INTERRUPTIBLE(_cmd, _result, _clear) do { \
146 _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO); \
147 } while((_result == OS_ERR) && (errno == EINTR))
149 #else
151 // This adds an assertion that it is only called from thread_in_native
152 // The call overhead is skipped for performance in product mode
153 #define INTERRUPTIBLE(_cmd, _result, _clear) do { \
154 _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO ); \
155 } while((_result == OS_ERR) && (errno == EINTR))
157 #endif
159 // Used for calls from _thread_in_vm, not from _thread_in_native
160 #define INTERRUPTIBLE_VM(_cmd, _result, _clear) do { \
161 _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible(_thread), UseVMInterruptibleIO ); \
162 } while((_result == OS_ERR) && (errno == EINTR))
164 /* Use NORESTART when the system call cannot return EINTR, when something other
165 than a system call is being invoked, or when the caller must do EINTR
166 handling. */
168 #ifndef ASSERT
170 #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
171 _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO)
173 #else
175 // This adds an assertion that it is only called from thread_in_native
176 // The call overhead is skipped for performance in product mode
177 #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
178 _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO )
180 #endif
182 // Don't attend to UseVMInterruptibleIO. Always allow interruption.
183 // Also assumes that it is called from the _thread_blocked state.
184 // Used by os_sleep().
186 #define INTERRUPTIBLE_NORESTART_VM_ALWAYS(_cmd, _result, _thread, _clear) \
187 _INTERRUPTIBLE(os::Solaris::setup_interruptible_already_blocked(_thread), _result = _cmd, _result, _thread, _clear, , , true )
189 #define INTERRUPTIBLE_RETURN_INT(_cmd, _clear) do { \
190 int _result; \
191 do { \
192 INTERRUPTIBLE(_cmd, _result, _clear); \
193 } while((_result == OS_ERR) && (errno == EINTR)); \
194 return _result; \
195 } while(false)
197 #define INTERRUPTIBLE_RETURN_INT_VM(_cmd, _clear) do { \
198 int _result; \
199 do { \
200 INTERRUPTIBLE_VM(_cmd, _result, _clear); \
201 } while((_result == OS_ERR) && (errno == EINTR)); \
202 return _result; \
203 } while(false)
205 #define INTERRUPTIBLE_RETURN_INT_NORESTART(_cmd, _clear) do { \
206 int _result; \
207 INTERRUPTIBLE_NORESTART(_cmd, _result, _clear); \
208 return _result; \
209 } while(false)
211 /* Use the RESTARTABLE macros when interruptible io is not needed */
213 #define RESTARTABLE(_cmd, _result) do { \
214 do { \
215 _result = _cmd; \
216 } while((_result == OS_ERR) && (errno == EINTR)); \
217 } while(false)
219 #define RESTARTABLE_RETURN_INT(_cmd) do { \
220 int _result; \
221 RESTARTABLE(_cmd, _result); \
222 return _result; \
223 } while(false)
225 inline bool os::numa_has_static_binding() { return false; }
226 inline bool os::numa_has_group_homing() { return true; }
228 inline int os::socket(int domain, int type, int protocol) {
229 return ::socket(domain, type, protocol);
230 }
232 inline int os::listen(int fd, int count) {
233 if (fd < 0) return OS_ERR;
235 return ::listen(fd, count);
236 }
238 inline int os::socket_shutdown(int fd, int howto){
239 return ::shutdown(fd, howto);
240 }
242 inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){
243 return ::getsockname(fd, him, len);
244 }
246 inline int os::get_host_name(char* name, int namelen){
247 return ::gethostname(name, namelen);
248 }
250 inline struct hostent* os::get_host_by_name(char* name) {
251 return ::gethostbyname(name);
252 }
254 inline int os::get_sock_opt(int fd, int level, int optname,
255 char* optval, socklen_t* optlen) {
256 return ::getsockopt(fd, level, optname, optval, optlen);
257 }
259 inline int os::set_sock_opt(int fd, int level, int optname,
260 const char *optval, socklen_t optlen) {
261 return ::setsockopt(fd, level, optname, optval, optlen);
262 }
263 #endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP