Fri, 06 Sep 2013 20:16:09 +0200
8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
Reviewed-by: kvn
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os/aix/vm/attachListener_aix.cpp Fri Sep 06 20:16:09 2013 +0200 1.3 @@ -0,0 +1,574 @@ 1.4 +/* 1.5 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#include "precompiled.hpp" 1.30 +#include "runtime/interfaceSupport.hpp" 1.31 +#include "runtime/os.hpp" 1.32 +#include "services/attachListener.hpp" 1.33 +#include "services/dtraceAttacher.hpp" 1.34 + 1.35 +#include <unistd.h> 1.36 +#include <signal.h> 1.37 +#include <sys/types.h> 1.38 +#include <sys/socket.h> 1.39 +#include <sys/un.h> 1.40 +#include <sys/stat.h> 1.41 + 1.42 +#ifndef UNIX_PATH_MAX 1.43 +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) 1.44 +#endif 1.45 + 1.46 +// The attach mechanism on Linux uses a UNIX domain socket. An attach listener 1.47 +// thread is created at startup or is created on-demand via a signal from 1.48 +// the client tool. The attach listener creates a socket and binds it to a file 1.49 +// in the filesystem. The attach listener then acts as a simple (single- 1.50 +// threaded) server - it waits for a client to connect, reads the request, 1.51 +// executes it, and returns the response to the client via the socket 1.52 +// connection. 1.53 +// 1.54 +// As the socket is a UNIX domain socket it means that only clients on the 1.55 +// local machine can connect. In addition there are two other aspects to 1.56 +// the security: 1.57 +// 1. The well known file that the socket is bound to has permission 400 1.58 +// 2. When a client connect, the SO_PEERID socket option is used to 1.59 +// obtain the credentials of client. We check that the effective uid 1.60 +// of the client matches this process. 1.61 + 1.62 +// forward reference 1.63 +class AixAttachOperation; 1.64 + 1.65 +class AixAttachListener: AllStatic { 1.66 + private: 1.67 + // the path to which we bind the UNIX domain socket 1.68 + static char _path[UNIX_PATH_MAX]; 1.69 + static bool _has_path; 1.70 + // Shutdown marker to prevent accept blocking during clean-up. 1.71 + static bool _shutdown; 1.72 + 1.73 + // the file descriptor for the listening socket 1.74 + static int _listener; 1.75 + 1.76 + static void set_path(char* path) { 1.77 + if (path == NULL) { 1.78 + _has_path = false; 1.79 + } else { 1.80 + strncpy(_path, path, UNIX_PATH_MAX); 1.81 + _path[UNIX_PATH_MAX-1] = '\0'; 1.82 + _has_path = true; 1.83 + } 1.84 + } 1.85 + 1.86 + static void set_listener(int s) { _listener = s; } 1.87 + 1.88 + // reads a request from the given connected socket 1.89 + static AixAttachOperation* read_request(int s); 1.90 + 1.91 + public: 1.92 + enum { 1.93 + ATTACH_PROTOCOL_VER = 1 // protocol version 1.94 + }; 1.95 + enum { 1.96 + ATTACH_ERROR_BADVERSION = 101 // error codes 1.97 + }; 1.98 + 1.99 + // initialize the listener, returns 0 if okay 1.100 + static int init(); 1.101 + 1.102 + static char* path() { return _path; } 1.103 + static bool has_path() { return _has_path; } 1.104 + static int listener() { return _listener; } 1.105 + // Shutdown marker to prevent accept blocking during clean-up 1.106 + static void set_shutdown(bool shutdown) { _shutdown = shutdown; } 1.107 + static bool is_shutdown() { return _shutdown; } 1.108 + 1.109 + // write the given buffer to a socket 1.110 + static int write_fully(int s, char* buf, int len); 1.111 + 1.112 + static AixAttachOperation* dequeue(); 1.113 +}; 1.114 + 1.115 +class AixAttachOperation: public AttachOperation { 1.116 + private: 1.117 + // the connection to the client 1.118 + int _socket; 1.119 + 1.120 + public: 1.121 + void complete(jint res, bufferedStream* st); 1.122 + 1.123 + void set_socket(int s) { _socket = s; } 1.124 + int socket() const { return _socket; } 1.125 + 1.126 + AixAttachOperation(char* name) : AttachOperation(name) { 1.127 + set_socket(-1); 1.128 + } 1.129 +}; 1.130 + 1.131 +// statics 1.132 +char AixAttachListener::_path[UNIX_PATH_MAX]; 1.133 +bool AixAttachListener::_has_path; 1.134 +int AixAttachListener::_listener = -1; 1.135 +// Shutdown marker to prevent accept blocking during clean-up 1.136 +bool AixAttachListener::_shutdown = false; 1.137 + 1.138 +// Supporting class to help split a buffer into individual components 1.139 +class ArgumentIterator : public StackObj { 1.140 + private: 1.141 + char* _pos; 1.142 + char* _end; 1.143 + public: 1.144 + ArgumentIterator(char* arg_buffer, size_t arg_size) { 1.145 + _pos = arg_buffer; 1.146 + _end = _pos + arg_size - 1; 1.147 + } 1.148 + char* next() { 1.149 + if (*_pos == '\0') { 1.150 + return NULL; 1.151 + } 1.152 + char* res = _pos; 1.153 + char* next_pos = strchr(_pos, '\0'); 1.154 + if (next_pos < _end) { 1.155 + next_pos++; 1.156 + } 1.157 + _pos = next_pos; 1.158 + return res; 1.159 + } 1.160 +}; 1.161 + 1.162 +// On AIX if sockets block until all data has been transmitted 1.163 +// successfully in some communication domains a socket "close" may 1.164 +// never complete. We have to take care that after the socket shutdown 1.165 +// the listener never enters accept state. 1.166 + 1.167 +// atexit hook to stop listener and unlink the file that it is 1.168 +// bound too. 1.169 + 1.170 +// Some modifications to the listener logic to prevent deadlocks on exit. 1.171 +// 1. We Shutdown the socket here instead. AixAttachOperation::complete() is not the right place 1.172 +// since more than one agent in a sequence in JPLIS live tests wouldn't work (Listener thread 1.173 +// would be dead after the first operation completion). 1.174 +// 2. close(s) may never return if the listener thread is in socket accept(). Unlinking the file 1.175 +// should be sufficient for cleanup. 1.176 +extern "C" { 1.177 + static void listener_cleanup() { 1.178 + static int cleanup_done; 1.179 + if (!cleanup_done) { 1.180 + cleanup_done = 1; 1.181 + AixAttachListener::set_shutdown(true); 1.182 + int s = AixAttachListener::listener(); 1.183 + if (s != -1) { 1.184 + ::shutdown(s, 2); 1.185 + } 1.186 + if (AixAttachListener::has_path()) { 1.187 + ::unlink(AixAttachListener::path()); 1.188 + } 1.189 + } 1.190 + } 1.191 +} 1.192 + 1.193 +// Initialization - create a listener socket and bind it to a file 1.194 + 1.195 +int AixAttachListener::init() { 1.196 + char path[UNIX_PATH_MAX]; // socket file 1.197 + char initial_path[UNIX_PATH_MAX]; // socket file during setup 1.198 + int listener; // listener socket (file descriptor) 1.199 + 1.200 + // register function to cleanup 1.201 + ::atexit(listener_cleanup); 1.202 + 1.203 + int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d", 1.204 + os::get_temp_directory(), os::current_process_id()); 1.205 + if (n < (int)UNIX_PATH_MAX) { 1.206 + n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path); 1.207 + } 1.208 + if (n >= (int)UNIX_PATH_MAX) { 1.209 + return -1; 1.210 + } 1.211 + 1.212 + // create the listener socket 1.213 + listener = ::socket(PF_UNIX, SOCK_STREAM, 0); 1.214 + if (listener == -1) { 1.215 + return -1; 1.216 + } 1.217 + 1.218 + // bind socket 1.219 + struct sockaddr_un addr; 1.220 + addr.sun_family = AF_UNIX; 1.221 + strcpy(addr.sun_path, initial_path); 1.222 + ::unlink(initial_path); 1.223 + // We must call bind with the actual socketaddr length. This is obligatory for AS400. 1.224 + int res = ::bind(listener, (struct sockaddr*)&addr, SUN_LEN(&addr)); 1.225 + if (res == -1) { 1.226 + RESTARTABLE(::close(listener), res); 1.227 + return -1; 1.228 + } 1.229 + 1.230 + // put in listen mode, set permissions, and rename into place 1.231 + res = ::listen(listener, 5); 1.232 + if (res == 0) { 1.233 + RESTARTABLE(::chmod(initial_path, (S_IREAD|S_IWRITE) & ~(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)), res); 1.234 + if (res == 0) { 1.235 + res = ::rename(initial_path, path); 1.236 + } 1.237 + } 1.238 + if (res == -1) { 1.239 + RESTARTABLE(::close(listener), res); 1.240 + ::unlink(initial_path); 1.241 + return -1; 1.242 + } 1.243 + set_path(path); 1.244 + set_listener(listener); 1.245 + set_shutdown(false); 1.246 + 1.247 + return 0; 1.248 +} 1.249 + 1.250 +// Given a socket that is connected to a peer we read the request and 1.251 +// create an AttachOperation. As the socket is blocking there is potential 1.252 +// for a denial-of-service if the peer does not response. However this happens 1.253 +// after the peer credentials have been checked and in the worst case it just 1.254 +// means that the attach listener thread is blocked. 1.255 +// 1.256 +AixAttachOperation* AixAttachListener::read_request(int s) { 1.257 + char ver_str[8]; 1.258 + sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER); 1.259 + 1.260 + // The request is a sequence of strings so we first figure out the 1.261 + // expected count and the maximum possible length of the request. 1.262 + // The request is: 1.263 + // <ver>0<cmd>0<arg>0<arg>0<arg>0 1.264 + // where <ver> is the protocol version (1), <cmd> is the command 1.265 + // name ("load", "datadump", ...), and <arg> is an argument 1.266 + int expected_str_count = 2 + AttachOperation::arg_count_max; 1.267 + const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) + 1.268 + AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1); 1.269 + 1.270 + char buf[max_len]; 1.271 + int str_count = 0; 1.272 + 1.273 + // Read until all (expected) strings have been read, the buffer is 1.274 + // full, or EOF. 1.275 + 1.276 + int off = 0; 1.277 + int left = max_len; 1.278 + 1.279 + do { 1.280 + int n; 1.281 + // Don't block on interrupts because this will 1.282 + // hang in the clean-up when shutting down. 1.283 + n = read(s, buf+off, left); 1.284 + if (n == -1) { 1.285 + return NULL; // reset by peer or other error 1.286 + } 1.287 + if (n == 0) { // end of file reached 1.288 + break; 1.289 + } 1.290 + for (int i=0; i<n; i++) { 1.291 + if (buf[off+i] == 0) { 1.292 + // EOS found 1.293 + str_count++; 1.294 + 1.295 + // The first string is <ver> so check it now to 1.296 + // check for protocol mis-match 1.297 + if (str_count == 1) { 1.298 + if ((strlen(buf) != strlen(ver_str)) || 1.299 + (atoi(buf) != ATTACH_PROTOCOL_VER)) { 1.300 + char msg[32]; 1.301 + sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION); 1.302 + write_fully(s, msg, strlen(msg)); 1.303 + return NULL; 1.304 + } 1.305 + } 1.306 + } 1.307 + } 1.308 + off += n; 1.309 + left -= n; 1.310 + } while (left > 0 && str_count < expected_str_count); 1.311 + 1.312 + if (str_count != expected_str_count) { 1.313 + return NULL; // incomplete request 1.314 + } 1.315 + 1.316 + // parse request 1.317 + 1.318 + ArgumentIterator args(buf, (max_len)-left); 1.319 + 1.320 + // version already checked 1.321 + char* v = args.next(); 1.322 + 1.323 + char* name = args.next(); 1.324 + if (name == NULL || strlen(name) > AttachOperation::name_length_max) { 1.325 + return NULL; 1.326 + } 1.327 + 1.328 + AixAttachOperation* op = new AixAttachOperation(name); 1.329 + 1.330 + for (int i=0; i<AttachOperation::arg_count_max; i++) { 1.331 + char* arg = args.next(); 1.332 + if (arg == NULL) { 1.333 + op->set_arg(i, NULL); 1.334 + } else { 1.335 + if (strlen(arg) > AttachOperation::arg_length_max) { 1.336 + delete op; 1.337 + return NULL; 1.338 + } 1.339 + op->set_arg(i, arg); 1.340 + } 1.341 + } 1.342 + 1.343 + op->set_socket(s); 1.344 + return op; 1.345 +} 1.346 + 1.347 + 1.348 +// Dequeue an operation 1.349 +// 1.350 +// In the Linux implementation there is only a single operation and clients 1.351 +// cannot queue commands (except at the socket level). 1.352 +// 1.353 +AixAttachOperation* AixAttachListener::dequeue() { 1.354 + for (;;) { 1.355 + int s; 1.356 + 1.357 + // wait for client to connect 1.358 + struct sockaddr addr; 1.359 + socklen_t len = sizeof(addr); 1.360 + memset(&addr, 0, len); 1.361 + // We must prevent accept blocking on the socket if it has been shut down. 1.362 + // Therefore we allow interrups and check whether we have been shut down already. 1.363 + if (AixAttachListener::is_shutdown()) { 1.364 + return NULL; 1.365 + } 1.366 + s=::accept(listener(), &addr, &len); 1.367 + if (s == -1) { 1.368 + return NULL; // log a warning? 1.369 + } 1.370 + 1.371 + // Added timeouts for read and write. If we get no request within the 1.372 + // next AttachListenerTimeout milliseconds we just finish the connection. 1.373 + struct timeval tv; 1.374 + tv.tv_sec = 0; 1.375 + tv.tv_usec = AttachListenerTimeout * 1000; 1.376 + ::setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)); 1.377 + ::setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)); 1.378 + 1.379 + // get the credentials of the peer and check the effective uid/guid 1.380 + // - check with jeff on this. 1.381 + struct peercred_struct cred_info; 1.382 + socklen_t optlen = sizeof(cred_info); 1.383 + if (::getsockopt(s, SOL_SOCKET, SO_PEERID, (void*)&cred_info, &optlen) == -1) { 1.384 + int res; 1.385 + RESTARTABLE(::close(s), res); 1.386 + continue; 1.387 + } 1.388 + uid_t euid = geteuid(); 1.389 + gid_t egid = getegid(); 1.390 + 1.391 + if (cred_info.euid != euid || cred_info.egid != egid) { 1.392 + int res; 1.393 + RESTARTABLE(::close(s), res); 1.394 + continue; 1.395 + } 1.396 + 1.397 + // peer credential look okay so we read the request 1.398 + AixAttachOperation* op = read_request(s); 1.399 + if (op == NULL) { 1.400 + int res; 1.401 + RESTARTABLE(::close(s), res); 1.402 + continue; 1.403 + } else { 1.404 + return op; 1.405 + } 1.406 + } 1.407 +} 1.408 + 1.409 +// write the given buffer to the socket 1.410 +int AixAttachListener::write_fully(int s, char* buf, int len) { 1.411 + do { 1.412 + int n = ::write(s, buf, len); 1.413 + if (n == -1) { 1.414 + if (errno != EINTR) return -1; 1.415 + } else { 1.416 + buf += n; 1.417 + len -= n; 1.418 + } 1.419 + } 1.420 + while (len > 0); 1.421 + return 0; 1.422 +} 1.423 + 1.424 +// Complete an operation by sending the operation result and any result 1.425 +// output to the client. At this time the socket is in blocking mode so 1.426 +// potentially we can block if there is a lot of data and the client is 1.427 +// non-responsive. For most operations this is a non-issue because the 1.428 +// default send buffer is sufficient to buffer everything. In the future 1.429 +// if there are operations that involves a very big reply then it the 1.430 +// socket could be made non-blocking and a timeout could be used. 1.431 + 1.432 +void AixAttachOperation::complete(jint result, bufferedStream* st) { 1.433 + JavaThread* thread = JavaThread::current(); 1.434 + ThreadBlockInVM tbivm(thread); 1.435 + 1.436 + thread->set_suspend_equivalent(); 1.437 + // cleared by handle_special_suspend_equivalent_condition() or 1.438 + // java_suspend_self() via check_and_wait_while_suspended() 1.439 + 1.440 + // write operation result 1.441 + char msg[32]; 1.442 + sprintf(msg, "%d\n", result); 1.443 + int rc = AixAttachListener::write_fully(this->socket(), msg, strlen(msg)); 1.444 + 1.445 + // write any result data 1.446 + if (rc == 0) { 1.447 + // Shutdown the socket in the cleanup function to enable more than 1.448 + // one agent attach in a sequence (see comments to listener_cleanup()). 1.449 + AixAttachListener::write_fully(this->socket(), (char*) st->base(), st->size()); 1.450 + } 1.451 + 1.452 + // done 1.453 + RESTARTABLE(::close(this->socket()), rc); 1.454 + 1.455 + // were we externally suspended while we were waiting? 1.456 + thread->check_and_wait_while_suspended(); 1.457 + 1.458 + delete this; 1.459 +} 1.460 + 1.461 + 1.462 +// AttachListener functions 1.463 + 1.464 +AttachOperation* AttachListener::dequeue() { 1.465 + JavaThread* thread = JavaThread::current(); 1.466 + ThreadBlockInVM tbivm(thread); 1.467 + 1.468 + thread->set_suspend_equivalent(); 1.469 + // cleared by handle_special_suspend_equivalent_condition() or 1.470 + // java_suspend_self() via check_and_wait_while_suspended() 1.471 + 1.472 + AttachOperation* op = AixAttachListener::dequeue(); 1.473 + 1.474 + // were we externally suspended while we were waiting? 1.475 + thread->check_and_wait_while_suspended(); 1.476 + 1.477 + return op; 1.478 +} 1.479 + 1.480 +// Performs initialization at vm startup 1.481 +// For AIX we remove any stale .java_pid file which could cause 1.482 +// an attaching process to think we are ready to receive on the 1.483 +// domain socket before we are properly initialized 1.484 + 1.485 +void AttachListener::vm_start() { 1.486 + char fn[UNIX_PATH_MAX]; 1.487 + struct stat64 st; 1.488 + int ret; 1.489 + 1.490 + int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", 1.491 + os::get_temp_directory(), os::current_process_id()); 1.492 + assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); 1.493 + 1.494 + RESTARTABLE(::stat64(fn, &st), ret); 1.495 + if (ret == 0) { 1.496 + ret = ::unlink(fn); 1.497 + if (ret == -1) { 1.498 + debug_only(warning("failed to remove stale attach pid file at %s", fn)); 1.499 + } 1.500 + } 1.501 +} 1.502 + 1.503 +int AttachListener::pd_init() { 1.504 + JavaThread* thread = JavaThread::current(); 1.505 + ThreadBlockInVM tbivm(thread); 1.506 + 1.507 + thread->set_suspend_equivalent(); 1.508 + // cleared by handle_special_suspend_equivalent_condition() or 1.509 + // java_suspend_self() via check_and_wait_while_suspended() 1.510 + 1.511 + int ret_code = AixAttachListener::init(); 1.512 + 1.513 + // were we externally suspended while we were waiting? 1.514 + thread->check_and_wait_while_suspended(); 1.515 + 1.516 + return ret_code; 1.517 +} 1.518 + 1.519 +// Attach Listener is started lazily except in the case when 1.520 +// +ReduseSignalUsage is used 1.521 +bool AttachListener::init_at_startup() { 1.522 + if (ReduceSignalUsage) { 1.523 + return true; 1.524 + } else { 1.525 + return false; 1.526 + } 1.527 +} 1.528 + 1.529 +// If the file .attach_pid<pid> exists in the working directory 1.530 +// or /tmp then this is the trigger to start the attach mechanism 1.531 +bool AttachListener::is_init_trigger() { 1.532 + if (init_at_startup() || is_initialized()) { 1.533 + return false; // initialized at startup or already initialized 1.534 + } 1.535 + char fn[PATH_MAX+1]; 1.536 + sprintf(fn, ".attach_pid%d", os::current_process_id()); 1.537 + int ret; 1.538 + struct stat64 st; 1.539 + RESTARTABLE(::stat64(fn, &st), ret); 1.540 + if (ret == -1) { 1.541 + snprintf(fn, sizeof(fn), "%s/.attach_pid%d", 1.542 + os::get_temp_directory(), os::current_process_id()); 1.543 + RESTARTABLE(::stat64(fn, &st), ret); 1.544 + } 1.545 + if (ret == 0) { 1.546 + // simple check to avoid starting the attach mechanism when 1.547 + // a bogus user creates the file 1.548 + if (st.st_uid == geteuid()) { 1.549 + init(); 1.550 + return true; 1.551 + } 1.552 + } 1.553 + return false; 1.554 +} 1.555 + 1.556 +// if VM aborts then remove listener 1.557 +void AttachListener::abort() { 1.558 + listener_cleanup(); 1.559 +} 1.560 + 1.561 +void AttachListener::pd_data_dump() { 1.562 + os::signal_notify(SIGQUIT); 1.563 +} 1.564 + 1.565 +AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) { 1.566 + return NULL; 1.567 +} 1.568 + 1.569 +jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) { 1.570 + out->print_cr("flag '%s' cannot be changed", op->arg(0)); 1.571 + return JNI_ERR; 1.572 +} 1.573 + 1.574 +void AttachListener::pd_detachall() { 1.575 + // Cleanup server socket to detach clients. 1.576 + listener_cleanup(); 1.577 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/os/aix/vm/c2_globals_aix.hpp Fri Sep 06 20:16:09 2013 +0200 2.3 @@ -0,0 +1,37 @@ 2.4 +/* 2.5 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 2.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 + * 2.9 + * This code is free software; you can redistribute it and/or modify it 2.10 + * under the terms of the GNU General Public License version 2 only, as 2.11 + * published by the Free Software Foundation. 2.12 + * 2.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.16 + * version 2 for more details (a copy is included in the LICENSE file that 2.17 + * accompanied this code). 2.18 + * 2.19 + * You should have received a copy of the GNU General Public License version 2.20 + * 2 along with this work; if not, write to the Free Software Foundation, 2.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.22 + * 2.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.24 + * or visit www.oracle.com if you need additional information or have any 2.25 + * questions. 2.26 + * 2.27 + */ 2.28 + 2.29 +#ifndef OS_AIX_VM_C2_GLOBALS_AIX_HPP 2.30 +#define OS_AIX_VM_C2_GLOBALS_AIX_HPP 2.31 + 2.32 +#include "utilities/globalDefinitions.hpp" 2.33 +#include "utilities/macros.hpp" 2.34 + 2.35 +// 2.36 +// Sets the default values for operating system dependent flags used by the 2.37 +// server compiler. (see c2_globals.hpp) 2.38 +// 2.39 + 2.40 +#endif // OS_AIX_VM_C2_GLOBALS_AIX_HPP
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/os/aix/vm/decoder_aix.hpp Fri Sep 06 20:16:09 2013 +0200 3.3 @@ -0,0 +1,48 @@ 3.4 +/* 3.5 + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright 2013 SAP AG. All rights reserved. 3.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 + * 3.9 + * This code is free software; you can redistribute it and/or modify it 3.10 + * under the terms of the GNU General Public License version 2 only, as 3.11 + * published by the Free Software Foundation. 3.12 + * 3.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.16 + * version 2 for more details (a copy is included in the LICENSE file that 3.17 + * accompanied this code). 3.18 + * 3.19 + * You should have received a copy of the GNU General Public License version 3.20 + * 2 along with this work; if not, write to the Free Software Foundation, 3.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.22 + * 3.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.24 + * or visit www.oracle.com if you need additional information or have any 3.25 + * questions. 3.26 + * 3.27 + */ 3.28 + 3.29 +#include "utilities/decoder.hpp" 3.30 +#include "porting_aix.hpp" 3.31 + 3.32 +// Provide simple AIXDecoder which enables decoding of C frames in VM. 3.33 +class AIXDecoder: public AbstractDecoder { 3.34 + public: 3.35 + AIXDecoder() { 3.36 + _decoder_status = no_error; 3.37 + } 3.38 + ~AIXDecoder() {} 3.39 + 3.40 + virtual bool can_decode_C_frame_in_vm() const { return true; } 3.41 + 3.42 + virtual bool demangle(const char* symbol, char* buf, int buflen) { return false; } // demangled by getFuncName 3.43 + 3.44 + virtual bool decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { 3.45 + return (::getFuncName((codeptr_t)addr, buf, buflen, offset, 0, 0, 0) == 0); 3.46 + } 3.47 + virtual bool decode(address addr, char *buf, int buflen, int* offset, const void *base) { 3.48 + ShouldNotReachHere(); 3.49 + return false; 3.50 + } 3.51 +};
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/os/aix/vm/globals_aix.hpp Fri Sep 06 20:16:09 2013 +0200 4.3 @@ -0,0 +1,63 @@ 4.4 +/* 4.5 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 4.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 + * 4.9 + * This code is free software; you can redistribute it and/or modify it 4.10 + * under the terms of the GNU General Public License version 2 only, as 4.11 + * published by the Free Software Foundation. 4.12 + * 4.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.16 + * version 2 for more details (a copy is included in the LICENSE file that 4.17 + * accompanied this code). 4.18 + * 4.19 + * You should have received a copy of the GNU General Public License version 4.20 + * 2 along with this work; if not, write to the Free Software Foundation, 4.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.22 + * 4.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.24 + * or visit www.oracle.com if you need additional information or have any 4.25 + * questions. 4.26 + * 4.27 + */ 4.28 + 4.29 +#ifndef OS_AIX_VM_GLOBALS_AIX_HPP 4.30 +#define OS_AIX_VM_GLOBALS_AIX_HPP 4.31 + 4.32 +// 4.33 +// Defines Aix specific flags. They are not available on other platforms. 4.34 +// 4.35 +#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ 4.36 + \ 4.37 + /* If UseLargePages == true allow or deny usage of 16M pages. 16M pages are */ \ 4.38 + /* a scarce resource and there may be situations where we do not want the VM */ \ 4.39 + /* to run with 16M pages. (Will fall back to 64K pages). */ \ 4.40 + product_pd(bool, Use16MPages, \ 4.41 + "Use 16M pages if available.") \ 4.42 + \ 4.43 + /* use optimized addresses for the polling page, */ \ 4.44 + /* e.g. map it to a special 32-bit address. */ \ 4.45 + product_pd(bool, OptimizePollingPageLocation, \ 4.46 + "Optimize the location of the polling page used for Safepoints") \ 4.47 + \ 4.48 + product_pd(intx, AttachListenerTimeout, \ 4.49 + "Timeout in ms the attach listener waits for a request") \ 4.50 + \ 4.51 + 4.52 +// Per default, do not allow 16M pages. 16M pages have to be switched on specifically. 4.53 +define_pd_global(bool, Use16MPages, false); 4.54 +define_pd_global(bool, OptimizePollingPageLocation, true); 4.55 +define_pd_global(intx, AttachListenerTimeout, 1000); 4.56 + 4.57 +// 4.58 +// Defines Aix-specific default values. The flags are available on all 4.59 +// platforms, but they may have different default values on other platforms. 4.60 +// 4.61 +define_pd_global(bool, UseLargePages, true); 4.62 +define_pd_global(bool, UseLargePagesIndividualAllocation, false); 4.63 +define_pd_global(bool, UseOSErrorReporting, false); 4.64 +define_pd_global(bool, UseThreadPriorities, true) ; 4.65 + 4.66 +#endif // OS_AIX_VM_GLOBALS_AIX_HPP
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/os/aix/vm/interfaceSupport_aix.hpp Fri Sep 06 20:16:09 2013 +0200 5.3 @@ -0,0 +1,35 @@ 5.4 +/* 5.5 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 5.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 + * 5.9 + * This code is free software; you can redistribute it and/or modify it 5.10 + * under the terms of the GNU General Public License version 2 only, as 5.11 + * published by the Free Software Foundation. 5.12 + * 5.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.16 + * version 2 for more details (a copy is included in the LICENSE file that 5.17 + * accompanied this code). 5.18 + * 5.19 + * You should have received a copy of the GNU General Public License version 5.20 + * 2 along with this work; if not, write to the Free Software Foundation, 5.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.22 + * 5.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.24 + * or visit www.oracle.com if you need additional information or have any 5.25 + * questions. 5.26 + * 5.27 + */ 5.28 + 5.29 +#ifndef OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP 5.30 +#define OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP 5.31 + 5.32 +// Contains inlined functions for class InterfaceSupport 5.33 + 5.34 +static inline void serialize_memory(JavaThread *thread) { 5.35 + os::write_memory_serialize_page(thread); 5.36 +} 5.37 + 5.38 +#endif // OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/os/aix/vm/jsig.c Fri Sep 06 20:16:09 2013 +0200 6.3 @@ -0,0 +1,233 @@ 6.4 +/* 6.5 + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 6.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 + * 6.9 + * This code is free software; you can redistribute it and/or modify it 6.10 + * under the terms of the GNU General Public License version 2 only, as 6.11 + * published by the Free Software Foundation. 6.12 + * 6.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.16 + * version 2 for more details (a copy is included in the LICENSE file that 6.17 + * accompanied this code). 6.18 + * 6.19 + * You should have received a copy of the GNU General Public License version 6.20 + * 2 along with this work; if not, write to the Free Software Foundation, 6.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.22 + * 6.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.24 + * or visit www.oracle.com if you need additional information or have any 6.25 + * questions. 6.26 + * 6.27 + */ 6.28 + 6.29 +/* CopyrightVersion 1.2 */ 6.30 + 6.31 +/* This is a special library that should be loaded before libc & 6.32 + * libthread to interpose the signal handler installation functions: 6.33 + * sigaction(), signal(), sigset(). 6.34 + * Used for signal-chaining. See RFE 4381843. 6.35 + */ 6.36 + 6.37 +#include <signal.h> 6.38 +#include <dlfcn.h> 6.39 +#include <pthread.h> 6.40 +#include <stdio.h> 6.41 +#include <stdlib.h> 6.42 + 6.43 +#define bool int 6.44 +#define true 1 6.45 +#define false 0 6.46 + 6.47 +// Highest so far on AIX 5.2 is SIGSAK (63) 6.48 +#define MAXSIGNUM 63 6.49 +#define MASK(sig) ((unsigned int)1 << sig) 6.50 + 6.51 +static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ 6.52 +static unsigned int jvmsigs = 0; /* signals used by jvm */ 6.53 + 6.54 +/* used to synchronize the installation of signal handlers */ 6.55 +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 6.56 +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 6.57 +static pthread_t tid = 0; 6.58 + 6.59 +typedef void (*sa_handler_t)(int); 6.60 +typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 6.61 +// signal_t is already defined on AIX 6.62 +typedef sa_handler_t (*signal_like_function_t)(int, sa_handler_t); 6.63 +typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *); 6.64 + 6.65 +static signal_like_function_t os_signal = 0; /* os's version of signal()/sigset() */ 6.66 +static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ 6.67 + 6.68 +static bool jvm_signal_installing = false; 6.69 +static bool jvm_signal_installed = false; 6.70 + 6.71 +static void signal_lock() { 6.72 + pthread_mutex_lock(&mutex); 6.73 + /* When the jvm is installing its set of signal handlers, threads 6.74 + * other than the jvm thread should wait */ 6.75 + if (jvm_signal_installing) { 6.76 + if (tid != pthread_self()) { 6.77 + pthread_cond_wait(&cond, &mutex); 6.78 + } 6.79 + } 6.80 +} 6.81 + 6.82 +static void signal_unlock() { 6.83 + pthread_mutex_unlock(&mutex); 6.84 +} 6.85 + 6.86 +static sa_handler_t call_os_signal(int sig, sa_handler_t disp, 6.87 + bool is_sigset) { 6.88 + if (os_signal == NULL) { 6.89 + if (!is_sigset) { 6.90 + // Aix: call functions directly instead of dlsym'ing them 6.91 + os_signal = signal; 6.92 + } else { 6.93 + // Aix: call functions directly instead of dlsym'ing them 6.94 + os_signal = sigset; 6.95 + } 6.96 + if (os_signal == NULL) { 6.97 + printf("%s\n", dlerror()); 6.98 + exit(0); 6.99 + } 6.100 + } 6.101 + return (*os_signal)(sig, disp); 6.102 +} 6.103 + 6.104 +static void save_signal_handler(int sig, sa_handler_t disp) { 6.105 + sigset_t set; 6.106 + sact[sig].sa_handler = disp; 6.107 + sigemptyset(&set); 6.108 + sact[sig].sa_mask = set; 6.109 + sact[sig].sa_flags = 0; 6.110 +} 6.111 + 6.112 +static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { 6.113 + sa_handler_t oldhandler; 6.114 + bool sigused; 6.115 + 6.116 + signal_lock(); 6.117 + 6.118 + sigused = (MASK(sig) & jvmsigs) != 0; 6.119 + if (jvm_signal_installed && sigused) { 6.120 + /* jvm has installed its signal handler for this signal. */ 6.121 + /* Save the handler. Don't really install it. */ 6.122 + oldhandler = sact[sig].sa_handler; 6.123 + save_signal_handler(sig, disp); 6.124 + 6.125 + signal_unlock(); 6.126 + return oldhandler; 6.127 + } else if (jvm_signal_installing) { 6.128 + /* jvm is installing its signal handlers. Install the new 6.129 + * handlers and save the old ones. jvm uses sigaction(). 6.130 + * Leave the piece here just in case. */ 6.131 + oldhandler = call_os_signal(sig, disp, is_sigset); 6.132 + save_signal_handler(sig, oldhandler); 6.133 + 6.134 + /* Record the signals used by jvm */ 6.135 + jvmsigs |= MASK(sig); 6.136 + 6.137 + signal_unlock(); 6.138 + return oldhandler; 6.139 + } else { 6.140 + /* jvm has no relation with this signal (yet). Install the 6.141 + * the handler. */ 6.142 + oldhandler = call_os_signal(sig, disp, is_sigset); 6.143 + 6.144 + signal_unlock(); 6.145 + return oldhandler; 6.146 + } 6.147 +} 6.148 + 6.149 +sa_handler_t signal(int sig, sa_handler_t disp) { 6.150 + return set_signal(sig, disp, false); 6.151 +} 6.152 + 6.153 +sa_handler_t sigset(int sig, sa_handler_t disp) { 6.154 + return set_signal(sig, disp, true); 6.155 + } 6.156 + 6.157 +static int call_os_sigaction(int sig, const struct sigaction *act, 6.158 + struct sigaction *oact) { 6.159 + if (os_sigaction == NULL) { 6.160 + // Aix: call functions directly instead of dlsym'ing them 6.161 + os_sigaction = sigaction; 6.162 + if (os_sigaction == NULL) { 6.163 + printf("%s\n", dlerror()); 6.164 + exit(0); 6.165 + } 6.166 + } 6.167 + return (*os_sigaction)(sig, act, oact); 6.168 +} 6.169 + 6.170 +int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { 6.171 + int res; 6.172 + bool sigused; 6.173 + struct sigaction oldAct; 6.174 + 6.175 + signal_lock(); 6.176 + 6.177 + sigused = (MASK(sig) & jvmsigs) != 0; 6.178 + if (jvm_signal_installed && sigused) { 6.179 + /* jvm has installed its signal handler for this signal. */ 6.180 + /* Save the handler. Don't really install it. */ 6.181 + if (oact != NULL) { 6.182 + *oact = sact[sig]; 6.183 + } 6.184 + if (act != NULL) { 6.185 + sact[sig] = *act; 6.186 + } 6.187 + 6.188 + signal_unlock(); 6.189 + return 0; 6.190 + } else if (jvm_signal_installing) { 6.191 + /* jvm is installing its signal handlers. Install the new 6.192 + * handlers and save the old ones. */ 6.193 + res = call_os_sigaction(sig, act, &oldAct); 6.194 + sact[sig] = oldAct; 6.195 + if (oact != NULL) { 6.196 + *oact = oldAct; 6.197 + } 6.198 + 6.199 + /* Record the signals used by jvm */ 6.200 + jvmsigs |= MASK(sig); 6.201 + 6.202 + signal_unlock(); 6.203 + return res; 6.204 + } else { 6.205 + /* jvm has no relation with this signal (yet). Install the 6.206 + * the handler. */ 6.207 + res = call_os_sigaction(sig, act, oact); 6.208 + 6.209 + signal_unlock(); 6.210 + return res; 6.211 + } 6.212 +} 6.213 + 6.214 +/* The three functions for the jvm to call into */ 6.215 +void JVM_begin_signal_setting() { 6.216 + signal_lock(); 6.217 + jvm_signal_installing = true; 6.218 + tid = pthread_self(); 6.219 + signal_unlock(); 6.220 +} 6.221 + 6.222 +void JVM_end_signal_setting() { 6.223 + signal_lock(); 6.224 + jvm_signal_installed = true; 6.225 + jvm_signal_installing = false; 6.226 + pthread_cond_broadcast(&cond); 6.227 + signal_unlock(); 6.228 +} 6.229 + 6.230 +struct sigaction *JVM_get_signal_action(int sig) { 6.231 + /* Does race condition make sense here? */ 6.232 + if ((MASK(sig) & jvmsigs) != 0) { 6.233 + return &sact[sig]; 6.234 + } 6.235 + return NULL; 6.236 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/os/aix/vm/jvm_aix.cpp Fri Sep 06 20:16:09 2013 +0200 7.3 @@ -0,0 +1,201 @@ 7.4 +/* 7.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 7.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 + * 7.9 + * This code is free software; you can redistribute it and/or modify it 7.10 + * under the terms of the GNU General Public License version 2 only, as 7.11 + * published by the Free Software Foundation. 7.12 + * 7.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.16 + * version 2 for more details (a copy is included in the LICENSE file that 7.17 + * accompanied this code). 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License version 7.20 + * 2 along with this work; if not, write to the Free Software Foundation, 7.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.22 + * 7.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.24 + * or visit www.oracle.com if you need additional information or have any 7.25 + * questions. 7.26 + * 7.27 + */ 7.28 + 7.29 +#include "precompiled.hpp" 7.30 +#include "prims/jvm.h" 7.31 +#include "runtime/interfaceSupport.hpp" 7.32 +#include "runtime/osThread.hpp" 7.33 + 7.34 +#include <signal.h> 7.35 + 7.36 + 7.37 +// sun.misc.Signal /////////////////////////////////////////////////////////// 7.38 +// Signal code is mostly copied from classic vm, signals_md.c 1.4 98/08/23 7.39 +/* 7.40 + * This function is included primarily as a debugging aid. If Java is 7.41 + * running in a console window, then pressing <CTRL-\\> will cause 7.42 + * the current state of all active threads and monitors to be written 7.43 + * to the console window. 7.44 + */ 7.45 + 7.46 +JVM_ENTRY_NO_ENV(void*, JVM_RegisterSignal(jint sig, void* handler)) 7.47 + // Copied from classic vm 7.48 + // signals_md.c 1.4 98/08/23 7.49 + void* newHandler = handler == (void *)2 7.50 + ? os::user_handler() 7.51 + : handler; 7.52 + switch (sig) { 7.53 + /* The following are already used by the VM. */ 7.54 + case INTERRUPT_SIGNAL: 7.55 + case SIGFPE: 7.56 + case SIGILL: 7.57 + case SIGSEGV: 7.58 + 7.59 + /* The following signal is used by the VM to dump thread stacks unless 7.60 + ReduceSignalUsage is set, in which case the user is allowed to set 7.61 + his own _native_ handler for this signal; thus, in either case, 7.62 + we do not allow JVM_RegisterSignal to change the handler. */ 7.63 + case BREAK_SIGNAL: 7.64 + return (void *)-1; 7.65 + 7.66 + /* The following signals are used for Shutdown Hooks support. However, if 7.67 + ReduceSignalUsage (-Xrs) is set, Shutdown Hooks must be invoked via 7.68 + System.exit(), Java is not allowed to use these signals, and the the 7.69 + user is allowed to set his own _native_ handler for these signals and 7.70 + invoke System.exit() as needed. Terminator.setup() is avoiding 7.71 + registration of these signals when -Xrs is present. 7.72 + - If the HUP signal is ignored (from the nohup) command, then Java 7.73 + is not allowed to use this signal. 7.74 + */ 7.75 + 7.76 + case SHUTDOWN1_SIGNAL: 7.77 + case SHUTDOWN2_SIGNAL: 7.78 + case SHUTDOWN3_SIGNAL: 7.79 + if (ReduceSignalUsage) return (void*)-1; 7.80 + if (os::Aix::is_sig_ignored(sig)) return (void*)1; 7.81 + } 7.82 + 7.83 + void* oldHandler = os::signal(sig, newHandler); 7.84 + if (oldHandler == os::user_handler()) { 7.85 + return (void *)2; 7.86 + } else { 7.87 + return oldHandler; 7.88 + } 7.89 +JVM_END 7.90 + 7.91 + 7.92 +JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig)) 7.93 + if (ReduceSignalUsage) { 7.94 + // do not allow SHUTDOWN1_SIGNAL,SHUTDOWN2_SIGNAL,SHUTDOWN3_SIGNAL, 7.95 + // BREAK_SIGNAL to be raised when ReduceSignalUsage is set, since 7.96 + // no handler for them is actually registered in JVM or via 7.97 + // JVM_RegisterSignal. 7.98 + if (sig == SHUTDOWN1_SIGNAL || sig == SHUTDOWN2_SIGNAL || 7.99 + sig == SHUTDOWN3_SIGNAL || sig == BREAK_SIGNAL) { 7.100 + return JNI_FALSE; 7.101 + } 7.102 + } 7.103 + else if ((sig == SHUTDOWN1_SIGNAL || sig == SHUTDOWN2_SIGNAL || 7.104 + sig == SHUTDOWN3_SIGNAL) && os::Aix::is_sig_ignored(sig)) { 7.105 + // do not allow SHUTDOWN1_SIGNAL to be raised when SHUTDOWN1_SIGNAL 7.106 + // is ignored, since no handler for them is actually registered in JVM 7.107 + // or via JVM_RegisterSignal. 7.108 + // This also applies for SHUTDOWN2_SIGNAL and SHUTDOWN3_SIGNAL 7.109 + return JNI_FALSE; 7.110 + } 7.111 + 7.112 + os::signal_raise(sig); 7.113 + return JNI_TRUE; 7.114 +JVM_END 7.115 + 7.116 +/* 7.117 + All the defined signal names for Linux. 7.118 + 7.119 + NOTE that not all of these names are accepted by our Java implementation 7.120 + 7.121 + Via an existing claim by the VM, sigaction restrictions, or 7.122 + the "rules of Unix" some of these names will be rejected at runtime. 7.123 + For example the VM sets up to handle USR1, sigaction returns EINVAL for 7.124 + STOP, and Linux simply doesn't allow catching of KILL. 7.125 + 7.126 + Here are the names currently accepted by a user of sun.misc.Signal with 7.127 + 1.4.1 (ignoring potential interaction with use of chaining, etc): 7.128 + 7.129 + HUP, INT, TRAP, ABRT, IOT, BUS, USR2, PIPE, ALRM, TERM, STKFLT, 7.130 + CLD, CHLD, CONT, TSTP, TTIN, TTOU, URG, XCPU, XFSZ, VTALRM, PROF, 7.131 + WINCH, POLL, IO, PWR, SYS 7.132 + 7.133 +*/ 7.134 + 7.135 +struct siglabel { 7.136 + const char *name; 7.137 + int number; 7.138 +}; 7.139 + 7.140 +struct siglabel siglabels[] = { 7.141 + /* derived from /usr/include/bits/signum.h on RH7.2 */ 7.142 + "HUP", SIGHUP, /* Hangup (POSIX). */ 7.143 + "INT", SIGINT, /* Interrupt (ANSI). */ 7.144 + "QUIT", SIGQUIT, /* Quit (POSIX). */ 7.145 + "ILL", SIGILL, /* Illegal instruction (ANSI). */ 7.146 + "TRAP", SIGTRAP, /* Trace trap (POSIX). */ 7.147 + "ABRT", SIGABRT, /* Abort (ANSI). */ 7.148 + "IOT", SIGIOT, /* IOT trap (4.2 BSD). */ 7.149 + "BUS", SIGBUS, /* BUS error (4.2 BSD). */ 7.150 + "FPE", SIGFPE, /* Floating-point exception (ANSI). */ 7.151 + "KILL", SIGKILL, /* Kill, unblockable (POSIX). */ 7.152 + "USR1", SIGUSR1, /* User-defined signal 1 (POSIX). */ 7.153 + "SEGV", SIGSEGV, /* Segmentation violation (ANSI). */ 7.154 + "USR2", SIGUSR2, /* User-defined signal 2 (POSIX). */ 7.155 + "PIPE", SIGPIPE, /* Broken pipe (POSIX). */ 7.156 + "ALRM", SIGALRM, /* Alarm clock (POSIX). */ 7.157 + "TERM", SIGTERM, /* Termination (ANSI). */ 7.158 +#ifdef SIGSTKFLT 7.159 + "STKFLT", SIGSTKFLT, /* Stack fault. */ 7.160 +#endif 7.161 + "CLD", SIGCLD, /* Same as SIGCHLD (System V). */ 7.162 + "CHLD", SIGCHLD, /* Child status has changed (POSIX). */ 7.163 + "CONT", SIGCONT, /* Continue (POSIX). */ 7.164 + "STOP", SIGSTOP, /* Stop, unblockable (POSIX). */ 7.165 + "TSTP", SIGTSTP, /* Keyboard stop (POSIX). */ 7.166 + "TTIN", SIGTTIN, /* Background read from tty (POSIX). */ 7.167 + "TTOU", SIGTTOU, /* Background write to tty (POSIX). */ 7.168 + "URG", SIGURG, /* Urgent condition on socket (4.2 BSD). */ 7.169 + "XCPU", SIGXCPU, /* CPU limit exceeded (4.2 BSD). */ 7.170 + "XFSZ", SIGXFSZ, /* File size limit exceeded (4.2 BSD). */ 7.171 + "DANGER", SIGDANGER, /* System crash imminent; free up some page space (AIX). */ 7.172 + "VTALRM", SIGVTALRM, /* Virtual alarm clock (4.2 BSD). */ 7.173 + "PROF", SIGPROF, /* Profiling alarm clock (4.2 BSD). */ 7.174 + "WINCH", SIGWINCH, /* Window size change (4.3 BSD, Sun). */ 7.175 + "POLL", SIGPOLL, /* Pollable event occurred (System V). */ 7.176 + "IO", SIGIO, /* I/O now possible (4.2 BSD). */ 7.177 + "PWR", SIGPWR, /* Power failure restart (System V). */ 7.178 +#ifdef SIGSYS 7.179 + "SYS", SIGSYS /* Bad system call. Only on some Linuxen! */ 7.180 +#endif 7.181 + }; 7.182 + 7.183 +JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name)) 7.184 + 7.185 + /* find and return the named signal's number */ 7.186 + 7.187 + for(uint i=0; i<ARRAY_SIZE(siglabels); i++) 7.188 + if(!strcmp(name, siglabels[i].name)) 7.189 + return siglabels[i].number; 7.190 + 7.191 + return -1; 7.192 + 7.193 +JVM_END 7.194 + 7.195 +// used by os::exception_name() 7.196 +extern bool signal_name(int signo, char* buf, size_t len) { 7.197 + for(uint i = 0; i < ARRAY_SIZE(siglabels); i++) { 7.198 + if (signo == siglabels[i].number) { 7.199 + jio_snprintf(buf, len, "SIG%s", siglabels[i].name); 7.200 + return true; 7.201 + } 7.202 + } 7.203 + return false; 7.204 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/os/aix/vm/jvm_aix.h Fri Sep 06 20:16:09 2013 +0200 8.3 @@ -0,0 +1,123 @@ 8.4 +/* 8.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 8.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 + * 8.9 + * This code is free software; you can redistribute it and/or modify it 8.10 + * under the terms of the GNU General Public License version 2 only, as 8.11 + * published by the Free Software Foundation. 8.12 + * 8.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.16 + * version 2 for more details (a copy is included in the LICENSE file that 8.17 + * accompanied this code). 8.18 + * 8.19 + * You should have received a copy of the GNU General Public License version 8.20 + * 2 along with this work; if not, write to the Free Software Foundation, 8.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.22 + * 8.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.24 + * or visit www.oracle.com if you need additional information or have any 8.25 + * questions. 8.26 + * 8.27 + */ 8.28 + 8.29 +#ifndef OS_AIX_VM_JVM_AIX_H 8.30 +#define OS_AIX_VM_JVM_AIX_H 8.31 + 8.32 +// HotSpot integration note: 8.33 +// 8.34 +// This is derived from the JDK classic file: 8.35 +// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22) 8.36 +// All local includes have been commented out. 8.37 + 8.38 +#ifndef JVM_MD_H 8.39 +#define JVM_MD_H 8.40 + 8.41 +/* 8.42 + * This file is currently collecting system-specific dregs for the 8.43 + * JNI conversion, which should be sorted out later. 8.44 + */ 8.45 + 8.46 +// Since we are compiling with c++, we need the following to make c macros 8.47 +// visible. 8.48 +#if !defined(__STDC_LIMIT_MACROS) 8.49 +# define __STDC_LIMIT_MACROS 1 8.50 +#endif 8.51 +#if !defined(__STDC_CONSTANT_MACROS) 8.52 +# define __STDC_CONSTANT_MACROS 1 8.53 +#endif 8.54 +#if !defined(__STDC_FORMAT_MACROS) 8.55 +# define __STDC_FORMAT_MACROS 1 8.56 +#endif 8.57 + 8.58 +#include <dirent.h> /* For DIR */ 8.59 + 8.60 +// Must redefine NULL because the macro gets redefined to int 0 8.61 +// by dirent.h. This redefinition is included later then the standard definition in 8.62 +// globalDefinitions_<compiler>.hpp and leads to assertions in the VM initialization. 8.63 +// We definitely need NULL to have the same lengh as an address pointer. 8.64 +#ifdef _LP64 8.65 +#undef NULL 8.66 +#define NULL 0L 8.67 +#else 8.68 +#ifndef NULL 8.69 +#define NULL 0 8.70 +#endif 8.71 +#endif 8.72 + 8.73 +#include <sys/param.h> /* For MAXPATHLEN */ 8.74 +#include <sys/socket.h> /* For socklen_t */ 8.75 +#include <unistd.h> /* For F_OK, R_OK, W_OK */ 8.76 + 8.77 +#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} 8.78 +#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} 8.79 +#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} 8.80 +#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} 8.81 +#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} 8.82 +#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} 8.83 + 8.84 +#define JNI_LIB_PREFIX "lib" 8.85 +#define JNI_LIB_SUFFIX ".so" 8.86 + 8.87 +// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may 8.88 +// cause problems if JVM and the rest of JDK are built on different 8.89 +// Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1, 8.90 +// so buffers declared in VM are always >= 4096. 8.91 +#define JVM_MAXPATHLEN MAXPATHLEN + 1 8.92 + 8.93 +#define JVM_R_OK R_OK 8.94 +#define JVM_W_OK W_OK 8.95 +#define JVM_X_OK X_OK 8.96 +#define JVM_F_OK F_OK 8.97 + 8.98 +/* 8.99 + * File I/O 8.100 + */ 8.101 + 8.102 +#include <sys/types.h> 8.103 +#include <sys/stat.h> 8.104 +#include <fcntl.h> 8.105 +#include <errno.h> 8.106 + 8.107 +/* O Flags */ 8.108 + 8.109 +#define JVM_O_RDONLY O_RDONLY 8.110 +#define JVM_O_WRONLY O_WRONLY 8.111 +#define JVM_O_RDWR O_RDWR 8.112 +#define JVM_O_O_APPEND O_APPEND 8.113 +#define JVM_O_EXCL O_EXCL 8.114 +#define JVM_O_CREAT O_CREAT 8.115 + 8.116 +/* Signal definitions */ 8.117 + 8.118 +#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ 8.119 +#define INTERRUPT_SIGNAL SIGUSR1 /* Interruptible I/O support. */ 8.120 +#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ 8.121 +#define SHUTDOWN2_SIGNAL SIGINT 8.122 +#define SHUTDOWN3_SIGNAL SIGTERM 8.123 + 8.124 +#endif /* JVM_MD_H */ 8.125 + 8.126 +#endif // OS_AIX_VM_JVM_AIX_H
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/os/aix/vm/libperfstat_aix.cpp Fri Sep 06 20:16:09 2013 +0200 9.3 @@ -0,0 +1,124 @@ 9.4 +/* 9.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + * 9.26 + */ 9.27 + 9.28 +#include "runtime/arguments.hpp" 9.29 +#include "libperfstat_aix.hpp" 9.30 + 9.31 +// For dlopen and friends 9.32 +#include <fcntl.h> 9.33 + 9.34 +// handle to the libperfstat 9.35 +static void* g_libhandle = NULL; 9.36 + 9.37 +// whether initialization worked 9.38 +static bool g_initialized = false; 9.39 + 9.40 + 9.41 +typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, perfstat_cpu_total_t* userbuff, 9.42 + int sizeof_userbuff, int desired_number); 9.43 + 9.44 +typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff, 9.45 + int sizeof_userbuff, int desired_number); 9.46 + 9.47 +typedef void (*fun_perfstat_reset_t) (); 9.48 + 9.49 +static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL; 9.50 +static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL; 9.51 +static fun_perfstat_reset_t g_fun_perfstat_reset = NULL; 9.52 + 9.53 +bool libperfstat::init() { 9.54 + 9.55 + if (g_initialized) { 9.56 + return true; 9.57 + } 9.58 + 9.59 + g_initialized = false; 9.60 + 9.61 + // dynamically load the libperfstat porting library. 9.62 + g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW); 9.63 + if (!g_libhandle) { 9.64 + if (Verbose) { 9.65 + fprintf(stderr, "Cannot load libperfstat.a (dlerror: %s)", dlerror()); 9.66 + } 9.67 + return false; 9.68 + } 9.69 + 9.70 + // resolve function pointers 9.71 + 9.72 +#define RESOLVE_FUN_NO_ERROR(name) \ 9.73 + g_fun_##name = (fun_##name##_t) dlsym(g_libhandle, #name); 9.74 + 9.75 +#define RESOLVE_FUN(name) \ 9.76 + RESOLVE_FUN_NO_ERROR(name) \ 9.77 + if (!g_fun_##name) { \ 9.78 + if (Verbose) { \ 9.79 + fprintf(stderr, "Cannot resolve " #name "() from libperfstat.a\n" \ 9.80 + " (dlerror: %s)", dlerror()); \ 9.81 + } \ 9.82 + return false; \ 9.83 + } 9.84 + 9.85 + RESOLVE_FUN(perfstat_cpu_total); 9.86 + RESOLVE_FUN(perfstat_memory_total); 9.87 + RESOLVE_FUN(perfstat_reset); 9.88 + 9.89 + g_initialized = true; 9.90 + 9.91 + return true; 9.92 +} 9.93 + 9.94 +void libperfstat::cleanup() { 9.95 + 9.96 + g_initialized = false; 9.97 + 9.98 + if (g_libhandle) { 9.99 + dlclose(g_libhandle); 9.100 + g_libhandle = NULL; 9.101 + } 9.102 + 9.103 + g_fun_perfstat_cpu_total = NULL; 9.104 + g_fun_perfstat_memory_total = NULL; 9.105 + g_fun_perfstat_reset = NULL; 9.106 +} 9.107 + 9.108 +int libperfstat::perfstat_memory_total(perfstat_id_t *name, 9.109 + perfstat_memory_total_t* userbuff, 9.110 + int sizeof_userbuff, int desired_number) { 9.111 + assert(g_initialized, "libperfstat not initialized"); 9.112 + assert(g_fun_perfstat_memory_total, ""); 9.113 + return g_fun_perfstat_memory_total(name, userbuff, sizeof_userbuff, desired_number); 9.114 +} 9.115 + 9.116 +int libperfstat::perfstat_cpu_total(perfstat_id_t *name, perfstat_cpu_total_t* userbuff, 9.117 + int sizeof_userbuff, int desired_number) { 9.118 + assert(g_initialized, "libperfstat not initialized"); 9.119 + assert(g_fun_perfstat_cpu_total, ""); 9.120 + return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number); 9.121 +} 9.122 + 9.123 +void libperfstat::perfstat_reset() { 9.124 + assert(g_initialized, "libperfstat not initialized"); 9.125 + assert(g_fun_perfstat_reset, ""); 9.126 + g_fun_perfstat_reset(); 9.127 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/os/aix/vm/libperfstat_aix.hpp Fri Sep 06 20:16:09 2013 +0200 10.3 @@ -0,0 +1,59 @@ 10.4 +/* 10.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. 10.11 + * 10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.15 + * version 2 for more details (a copy is included in the LICENSE file that 10.16 + * accompanied this code). 10.17 + * 10.18 + * You should have received a copy of the GNU General Public License version 10.19 + * 2 along with this work; if not, write to the Free Software Foundation, 10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.21 + * 10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 10.23 + * or visit www.oracle.com if you need additional information or have any 10.24 + * questions. 10.25 + * 10.26 + */ 10.27 + 10.28 +// encapsulates the libperfstat library. 10.29 +// 10.30 +// The purpose of this code is to dynamically load the libperfstat library 10.31 +// instead of statically linking against it. The libperfstat library is an 10.32 +// AIX-specific library which only exists on AIX, not on PASE. If I want to 10.33 +// share binaries between AIX and PASE, I cannot directly link against libperfstat.so. 10.34 + 10.35 +#ifndef OS_AIX_VM_LIBPERFSTAT_AIX_HPP 10.36 +#define OS_AIX_VM_LIBPERFSTAT_AIX_HPP 10.37 + 10.38 +#include <libperfstat.h> 10.39 + 10.40 +class libperfstat { 10.41 + 10.42 +public: 10.43 + 10.44 + // Load the libperfstat library (must be in LIBPATH). 10.45 + // Returns true if succeeded, false if error. 10.46 + static bool init(); 10.47 + 10.48 + // cleanup of the libo4 porting library. 10.49 + static void cleanup(); 10.50 + 10.51 + // direct wrappers for the libperfstat functionality. All they do is 10.52 + // to call the functions with the same name via function pointers. 10.53 + static int perfstat_cpu_total(perfstat_id_t *name, perfstat_cpu_total_t* userbuff, 10.54 + int sizeof_userbuff, int desired_number); 10.55 + 10.56 + static int perfstat_memory_total(perfstat_id_t *name, perfstat_memory_total_t* userbuff, 10.57 + int sizeof_userbuff, int desired_number); 10.58 + 10.59 + static void perfstat_reset(); 10.60 +}; 10.61 + 10.62 +#endif // OS_AIX_VM_LIBPERFSTAT_AIX_HPP
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/os/aix/vm/loadlib_aix.cpp Fri Sep 06 20:16:09 2013 +0200 11.3 @@ -0,0 +1,185 @@ 11.4 +/* 11.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + * 11.26 + */ 11.27 + 11.28 + 11.29 +// Implementation of LoadedLibraries and friends 11.30 + 11.31 +// Ultimately this just uses loadquery() 11.32 +// See: 11.33 +// http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp 11.34 +// ?topic=/com.ibm.aix.basetechref/doc/basetrf1/loadquery.htm 11.35 + 11.36 +#ifndef __STDC_FORMAT_MACROS 11.37 +#define __STDC_FORMAT_MACROS 11.38 +#endif 11.39 +// 'allocation.inline.hpp' triggers the inclusion of 'inttypes.h' which defines macros 11.40 +// required by the definitions in 'globalDefinitions.hpp'. But these macros in 'inttypes.h' 11.41 +// are only defined if '__STDC_FORMAT_MACROS' is defined! 11.42 +#include "memory/allocation.inline.hpp" 11.43 +#include "oops/oop.inline.hpp" 11.44 +#include "runtime/threadCritical.hpp" 11.45 +#include "utilities/debug.hpp" 11.46 +#include "utilities/ostream.hpp" 11.47 +#include "loadlib_aix.hpp" 11.48 +#include "porting_aix.hpp" 11.49 + 11.50 +// For loadquery() 11.51 +#include <sys/ldr.h> 11.52 + 11.53 +/////////////////////////////////////////////////////////////////////////////// 11.54 +// Implementation for LoadedLibraryModule 11.55 + 11.56 +// output debug info 11.57 +void LoadedLibraryModule::print(outputStream* os) const { 11.58 + os->print("%15.15s: text: " INTPTR_FORMAT " - " INTPTR_FORMAT 11.59 + ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " ", 11.60 + shortname, text_from, text_to, data_from, data_to); 11.61 + os->print(" %s", fullpath); 11.62 + if (strlen(membername) > 0) { 11.63 + os->print("(%s)", membername); 11.64 + } 11.65 + os->cr(); 11.66 +} 11.67 + 11.68 + 11.69 +/////////////////////////////////////////////////////////////////////////////// 11.70 +// Implementation for LoadedLibraries 11.71 + 11.72 +// class variables 11.73 +LoadedLibraryModule LoadedLibraries::tab[MAX_MODULES]; 11.74 +int LoadedLibraries::num_loaded = 0; 11.75 + 11.76 +// Checks whether the address p points to any of the loaded code segments. 11.77 +// If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 11.78 +// static 11.79 +const LoadedLibraryModule* LoadedLibraries::find_for_text_address(const unsigned char* p) { 11.80 + 11.81 + if (num_loaded == 0) { 11.82 + reload(); 11.83 + } 11.84 + for (int i = 0; i < num_loaded; i++) { 11.85 + if (tab[i].is_in_text(p)) { 11.86 + return &tab[i]; 11.87 + } 11.88 + } 11.89 + return NULL; 11.90 +} 11.91 + 11.92 +// Checks whether the address p points to any of the loaded data segments. 11.93 +// If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 11.94 +// static 11.95 +const LoadedLibraryModule* LoadedLibraries::find_for_data_address(const unsigned char* p) { 11.96 + if (num_loaded == 0) { 11.97 + reload(); 11.98 + } 11.99 + for (int i = 0; i < num_loaded; i++) { 11.100 + if (tab[i].is_in_data(p)) { 11.101 + return &tab[i]; 11.102 + } 11.103 + } 11.104 + return NULL; 11.105 +} 11.106 + 11.107 +// Rebuild the internal table of LoadedLibraryModule objects 11.108 +// static 11.109 +void LoadedLibraries::reload() { 11.110 + 11.111 + ThreadCritical cs; 11.112 + 11.113 + // discard old content 11.114 + num_loaded = 0; 11.115 + 11.116 + // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. 11.117 + size_t buf_size = 4096; 11.118 + char* loadquery_buf = AllocateHeap(buf_size, mtInternal); 11.119 + 11.120 + while(loadquery(L_GETINFO, loadquery_buf, buf_size) == -1) { 11.121 + if (errno == ENOMEM) { 11.122 + buf_size *= 2; 11.123 + loadquery_buf = ReallocateHeap(loadquery_buf, buf_size, mtInternal); 11.124 + } else { 11.125 + FreeHeap(loadquery_buf); 11.126 + // Ensure that the uintptr_t pointer is valid 11.127 + assert(errno != EFAULT, "loadquery: Invalid uintptr_t in info buffer."); 11.128 + fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno)); 11.129 + return; 11.130 + } 11.131 + } 11.132 + 11.133 + // Iterate over the loadquery result. For details see sys/ldr.h on AIX. 11.134 + const struct ld_info* p = (struct ld_info*) loadquery_buf; 11.135 + 11.136 + // Ensure we have all loaded libs. 11.137 + bool all_loaded = false; 11.138 + while(num_loaded < MAX_MODULES) { 11.139 + LoadedLibraryModule& mod = tab[num_loaded]; 11.140 + mod.text_from = (const unsigned char*) p->ldinfo_textorg; 11.141 + mod.text_to = (const unsigned char*) (((char*)p->ldinfo_textorg) + p->ldinfo_textsize); 11.142 + mod.data_from = (const unsigned char*) p->ldinfo_dataorg; 11.143 + mod.data_to = (const unsigned char*) (((char*)p->ldinfo_dataorg) + p->ldinfo_datasize); 11.144 + sprintf(mod.fullpath, "%.*s", sizeof(mod.fullpath), p->ldinfo_filename); 11.145 + // do we have a member name as well (see ldr.h)? 11.146 + const char* p_mbr_name = p->ldinfo_filename + strlen(p->ldinfo_filename) + 1; 11.147 + if (*p_mbr_name) { 11.148 + sprintf(mod.membername, "%.*s", sizeof(mod.membername), p_mbr_name); 11.149 + } else { 11.150 + mod.membername[0] = '\0'; 11.151 + } 11.152 + 11.153 + // fill in the short name 11.154 + const char* p_slash = strrchr(mod.fullpath, '/'); 11.155 + if (p_slash) { 11.156 + sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), p_slash + 1); 11.157 + } else { 11.158 + sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), mod.fullpath); 11.159 + } 11.160 + num_loaded ++; 11.161 + 11.162 + // next entry... 11.163 + if (p->ldinfo_next) { 11.164 + p = (struct ld_info*)(((char*)p) + p->ldinfo_next); 11.165 + } else { 11.166 + all_loaded = true; 11.167 + break; 11.168 + } 11.169 + } 11.170 + 11.171 + FreeHeap(loadquery_buf); 11.172 + 11.173 + // Ensure we have all loaded libs 11.174 + assert(all_loaded, "loadquery returned more entries then expected. Please increase MAX_MODULES"); 11.175 + 11.176 +} // end LoadedLibraries::reload() 11.177 + 11.178 + 11.179 +// output loaded libraries table 11.180 +//static 11.181 +void LoadedLibraries::print(outputStream* os) { 11.182 + 11.183 + for (int i = 0; i < num_loaded; i++) { 11.184 + tab[i].print(os); 11.185 + } 11.186 + 11.187 +} 11.188 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/os/aix/vm/loadlib_aix.hpp Fri Sep 06 20:16:09 2013 +0200 12.3 @@ -0,0 +1,128 @@ 12.4 +/* 12.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 + * 12.8 + * This code is free software; you can redistribute it and/or modify it 12.9 + * under the terms of the GNU General Public License version 2 only, as 12.10 + * published by the Free Software Foundation. 12.11 + * 12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.15 + * version 2 for more details (a copy is included in the LICENSE file that 12.16 + * accompanied this code). 12.17 + * 12.18 + * You should have received a copy of the GNU General Public License version 12.19 + * 2 along with this work; if not, write to the Free Software Foundation, 12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.21 + * 12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 12.23 + * or visit www.oracle.com if you need additional information or have any 12.24 + * questions. 12.25 + * 12.26 + */ 12.27 + 12.28 + 12.29 +// Loadlib_aix.cpp contains support code for analysing the memory 12.30 +// layout of loaded binaries in ones own process space. 12.31 +// 12.32 +// It is needed, among other things, to provide a dladdr() emulation, because 12.33 +// that one is not provided by AIX 12.34 + 12.35 +#ifndef OS_AIX_VM_LOADLIB_AIX_HPP 12.36 +#define OS_AIX_VM_LOADLIB_AIX_HPP 12.37 + 12.38 +class outputStream; 12.39 + 12.40 +// This class holds information about a single loaded library module. 12.41 +// Note that on AIX, a single library can be spread over multiple 12.42 +// uintptr_t range on a module base, eg. 12.43 +// libC.a(shr3_64.o) or libC.a(shrcore_64.o). 12.44 +class LoadedLibraryModule { 12.45 + 12.46 + friend class LoadedLibraries; 12.47 + 12.48 + char fullpath[512]; // eg /usr/lib/libC.a 12.49 + char shortname[30]; // eg libC.a 12.50 + char membername[30]; // eg shrcore_64.o 12.51 + const unsigned char* text_from; 12.52 + const unsigned char* text_to; 12.53 + const unsigned char* data_from; 12.54 + const unsigned char* data_to; 12.55 + 12.56 + public: 12.57 + 12.58 + const char* get_fullpath() const { 12.59 + return fullpath; 12.60 + } 12.61 + const char* get_shortname() const { 12.62 + return shortname; 12.63 + } 12.64 + const char* get_membername() const { 12.65 + return membername; 12.66 + } 12.67 + 12.68 + // text_from, text_to: returns the range of the text (code) 12.69 + // segment for that module 12.70 + const unsigned char* get_text_from() const { 12.71 + return text_from; 12.72 + } 12.73 + const unsigned char* get_text_to() const { 12.74 + return text_to; 12.75 + } 12.76 + 12.77 + // data_from/data_to: returns the range of the data 12.78 + // segment for that module 12.79 + const unsigned char* get_data_from() const { 12.80 + return data_from; 12.81 + } 12.82 + const unsigned char* get_data_to() const { 12.83 + return data_to; 12.84 + } 12.85 + 12.86 + // returns true if the 12.87 + bool is_in_text(const unsigned char* p) const { 12.88 + return p >= text_from && p < text_to ? true : false; 12.89 + } 12.90 + 12.91 + bool is_in_data(const unsigned char* p) const { 12.92 + return p >= data_from && p < data_to ? true : false; 12.93 + } 12.94 + 12.95 + // output debug info 12.96 + void print(outputStream* os) const; 12.97 + 12.98 +}; // end LoadedLibraryModule 12.99 + 12.100 +// This class is a singleton holding a map of all loaded binaries 12.101 +// in the AIX process space. 12.102 +class LoadedLibraries 12.103 +// : AllStatic (including allocation.hpp just for AllStatic is overkill.) 12.104 +{ 12.105 + 12.106 + private: 12.107 + 12.108 + enum {MAX_MODULES = 100}; 12.109 + static LoadedLibraryModule tab[MAX_MODULES]; 12.110 + static int num_loaded; 12.111 + 12.112 + public: 12.113 + 12.114 + // rebuild the internal table of LoadedLibraryModule objects 12.115 + static void reload(); 12.116 + 12.117 + // checks whether the address p points to any of the loaded code segments. 12.118 + // If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 12.119 + static const LoadedLibraryModule* find_for_text_address(const unsigned char* p); 12.120 + 12.121 + // checks whether the address p points to any of the loaded data segments. 12.122 + // If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 12.123 + static const LoadedLibraryModule* find_for_data_address(const unsigned char* p); 12.124 + 12.125 + // output debug info 12.126 + static void print(outputStream* os); 12.127 + 12.128 +}; // end LoadedLibraries 12.129 + 12.130 + 12.131 +#endif // OS_AIX_VM_LOADLIB_AIX_HPP
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/os/aix/vm/mutex_aix.inline.hpp Fri Sep 06 20:16:09 2013 +0200 13.3 @@ -0,0 +1,33 @@ 13.4 +/* 13.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 13.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 + * 13.9 + * This code is free software; you can redistribute it and/or modify it 13.10 + * under the terms of the GNU General Public License version 2 only, as 13.11 + * published by the Free Software Foundation. 13.12 + * 13.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.16 + * version 2 for more details (a copy is included in the LICENSE file that 13.17 + * accompanied this code). 13.18 + * 13.19 + * You should have received a copy of the GNU General Public License version 13.20 + * 2 along with this work; if not, write to the Free Software Foundation, 13.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.22 + * 13.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.24 + * or visit www.oracle.com if you need additional information or have any 13.25 + * questions. 13.26 + * 13.27 + */ 13.28 + 13.29 +#ifndef OS_AIX_VM_MUTEX_AIX_INLINE_HPP 13.30 +#define OS_AIX_VM_MUTEX_AIX_INLINE_HPP 13.31 + 13.32 +#include "os_aix.inline.hpp" 13.33 +#include "runtime/interfaceSupport.hpp" 13.34 +#include "thread_aix.inline.hpp" 13.35 + 13.36 +#endif // OS_AIX_VM_MUTEX_AIX_INLINE_HPP
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/os/aix/vm/osThread_aix.cpp Fri Sep 06 20:16:09 2013 +0200 14.3 @@ -0,0 +1,58 @@ 14.4 +/* 14.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 14.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 + * 14.9 + * This code is free software; you can redistribute it and/or modify it 14.10 + * under the terms of the GNU General Public License version 2 only, as 14.11 + * published by the Free Software Foundation. 14.12 + * 14.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.16 + * version 2 for more details (a copy is included in the LICENSE file that 14.17 + * accompanied this code). 14.18 + * 14.19 + * You should have received a copy of the GNU General Public License version 14.20 + * 2 along with this work; if not, write to the Free Software Foundation, 14.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.22 + * 14.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 14.24 + * or visit www.oracle.com if you need additional information or have any 14.25 + * questions. 14.26 + * 14.27 + */ 14.28 + 14.29 +// no precompiled headers 14.30 +#include "runtime/atomic.hpp" 14.31 +#include "runtime/handles.inline.hpp" 14.32 +#include "runtime/mutexLocker.hpp" 14.33 +#include "runtime/os.hpp" 14.34 +#include "runtime/osThread.hpp" 14.35 +#include "runtime/safepoint.hpp" 14.36 +#include "runtime/vmThread.hpp" 14.37 +#ifdef TARGET_ARCH_ppc 14.38 +# include "assembler_ppc.inline.hpp" 14.39 +#endif 14.40 + 14.41 + 14.42 +void OSThread::pd_initialize() { 14.43 + assert(this != NULL, "check"); 14.44 + _thread_id = 0; 14.45 + _pthread_id = 0; 14.46 + _siginfo = NULL; 14.47 + _ucontext = NULL; 14.48 + _expanding_stack = 0; 14.49 + _alt_sig_stack = NULL; 14.50 + 14.51 + _last_cpu_times.sys = _last_cpu_times.user = 0L; 14.52 + 14.53 + sigemptyset(&_caller_sigmask); 14.54 + 14.55 + _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true); 14.56 + assert(_startThread_lock !=NULL, "check"); 14.57 +} 14.58 + 14.59 +void OSThread::pd_destroy() { 14.60 + delete _startThread_lock; 14.61 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/os/aix/vm/osThread_aix.hpp Fri Sep 06 20:16:09 2013 +0200 15.3 @@ -0,0 +1,144 @@ 15.4 +/* 15.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 15.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 + * 15.9 + * This code is free software; you can redistribute it and/or modify it 15.10 + * under the terms of the GNU General Public License version 2 only, as 15.11 + * published by the Free Software Foundation. 15.12 + * 15.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.16 + * version 2 for more details (a copy is included in the LICENSE file that 15.17 + * accompanied this code). 15.18 + * 15.19 + * You should have received a copy of the GNU General Public License version 15.20 + * 2 along with this work; if not, write to the Free Software Foundation, 15.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.22 + * 15.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 15.24 + * or visit www.oracle.com if you need additional information or have any 15.25 + * questions. 15.26 + * 15.27 + */ 15.28 + 15.29 +#ifndef OS_AIX_VM_OSTHREAD_AIX_HPP 15.30 +#define OS_AIX_VM_OSTHREAD_AIX_HPP 15.31 + 15.32 + public: 15.33 + typedef pid_t thread_id_t; 15.34 + 15.35 + private: 15.36 + int _thread_type; 15.37 + 15.38 + public: 15.39 + 15.40 + int thread_type() const { 15.41 + return _thread_type; 15.42 + } 15.43 + void set_thread_type(int type) { 15.44 + _thread_type = type; 15.45 + } 15.46 + 15.47 + private: 15.48 + 15.49 + // _pthread_id is the pthread id, which is used by library calls 15.50 + // (e.g. pthread_kill). 15.51 + pthread_t _pthread_id; 15.52 + 15.53 + sigset_t _caller_sigmask; // Caller's signal mask 15.54 + 15.55 + public: 15.56 + 15.57 + // Methods to save/restore caller's signal mask 15.58 + sigset_t caller_sigmask() const { return _caller_sigmask; } 15.59 + void set_caller_sigmask(sigset_t sigmask) { _caller_sigmask = sigmask; } 15.60 + 15.61 +#ifndef PRODUCT 15.62 + // Used for debugging, return a unique integer for each thread. 15.63 + int thread_identifier() const { return _thread_id; } 15.64 +#endif 15.65 +#ifdef ASSERT 15.66 + // We expect no reposition failures so kill vm if we get one. 15.67 + // 15.68 + bool valid_reposition_failure() { 15.69 + return false; 15.70 + } 15.71 +#endif // ASSERT 15.72 + pthread_t pthread_id() const { 15.73 + return _pthread_id; 15.74 + } 15.75 + void set_pthread_id(pthread_t tid) { 15.76 + _pthread_id = tid; 15.77 + } 15.78 + 15.79 + // *************************************************************** 15.80 + // suspension support. 15.81 + // *************************************************************** 15.82 + 15.83 + public: 15.84 + // flags that support signal based suspend/resume on Linux are in a 15.85 + // separate class to avoid confusion with many flags in OSThread that 15.86 + // are used by VM level suspend/resume. 15.87 + os::SuspendResume sr; 15.88 + 15.89 + // _ucontext and _siginfo are used by SR_handler() to save thread context, 15.90 + // and they will later be used to walk the stack or reposition thread PC. 15.91 + // If the thread is not suspended in SR_handler() (e.g. self suspend), 15.92 + // the value in _ucontext is meaningless, so we must use the last Java 15.93 + // frame information as the frame. This will mean that for threads 15.94 + // that are parked on a mutex the profiler (and safepoint mechanism) 15.95 + // will see the thread as if it were still in the Java frame. This 15.96 + // not a problem for the profiler since the Java frame is a close 15.97 + // enough result. For the safepoint mechanism when the give it the 15.98 + // Java frame we are not at a point where the safepoint needs the 15.99 + // frame to that accurate (like for a compiled safepoint) since we 15.100 + // should be in a place where we are native and will block ourselves 15.101 + // if we transition. 15.102 + private: 15.103 + void* _siginfo; 15.104 + ucontext_t* _ucontext; 15.105 + int _expanding_stack; // non zero if manually expanding stack 15.106 + address _alt_sig_stack; // address of base of alternate signal stack 15.107 + 15.108 + public: 15.109 + void* siginfo() const { return _siginfo; } 15.110 + void set_siginfo(void* ptr) { _siginfo = ptr; } 15.111 + ucontext_t* ucontext() const { return _ucontext; } 15.112 + void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; } 15.113 + void set_expanding_stack(void) { _expanding_stack = 1; } 15.114 + void clear_expanding_stack(void) { _expanding_stack = 0; } 15.115 + int expanding_stack(void) { return _expanding_stack; } 15.116 + 15.117 + void set_alt_sig_stack(address val) { _alt_sig_stack = val; } 15.118 + address alt_sig_stack(void) { return _alt_sig_stack; } 15.119 + 15.120 + private: 15.121 + Monitor* _startThread_lock; // sync parent and child in thread creation 15.122 + 15.123 + public: 15.124 + 15.125 + Monitor* startThread_lock() const { 15.126 + return _startThread_lock; 15.127 + } 15.128 + 15.129 + // *************************************************************** 15.130 + // Platform dependent initialization and cleanup 15.131 + // *************************************************************** 15.132 + 15.133 + private: 15.134 + 15.135 + void pd_initialize(); 15.136 + void pd_destroy(); 15.137 + 15.138 + public: 15.139 + 15.140 + // The last measured values of cpu timing to prevent the "stale 15.141 + // value return" bug in thread_cpu_time. 15.142 + volatile struct { 15.143 + jlong sys; 15.144 + jlong user; 15.145 + } _last_cpu_times; 15.146 + 15.147 +#endif // OS_AIX_VM_OSTHREAD_AIX_HPP
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/os/aix/vm/os_aix.cpp Fri Sep 06 20:16:09 2013 +0200 16.3 @@ -0,0 +1,5126 @@ 16.4 +/* 16.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 16.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 + * 16.9 + * This code is free software; you can redistribute it and/or modify it 16.10 + * under the terms of the GNU General Public License version 2 only, as 16.11 + * published by the Free Software Foundation. 16.12 + * 16.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 16.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.16 + * version 2 for more details (a copy is included in the LICENSE file that 16.17 + * accompanied this code). 16.18 + * 16.19 + * You should have received a copy of the GNU General Public License version 16.20 + * 2 along with this work; if not, write to the Free Software Foundation, 16.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.22 + * 16.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 16.24 + * or visit www.oracle.com if you need additional information or have any 16.25 + * questions. 16.26 + * 16.27 + */ 16.28 + 16.29 +// According to the AIX OS doc #pragma alloca must be used 16.30 +// with C++ compiler before referencing the function alloca() 16.31 +#pragma alloca 16.32 + 16.33 +// no precompiled headers 16.34 +#include "classfile/classLoader.hpp" 16.35 +#include "classfile/systemDictionary.hpp" 16.36 +#include "classfile/vmSymbols.hpp" 16.37 +#include "code/icBuffer.hpp" 16.38 +#include "code/vtableStubs.hpp" 16.39 +#include "compiler/compileBroker.hpp" 16.40 +#include "interpreter/interpreter.hpp" 16.41 +#include "jvm_aix.h" 16.42 +#include "libperfstat_aix.hpp" 16.43 +#include "loadlib_aix.hpp" 16.44 +#include "memory/allocation.inline.hpp" 16.45 +#include "memory/filemap.hpp" 16.46 +#include "mutex_aix.inline.hpp" 16.47 +#include "oops/oop.inline.hpp" 16.48 +#include "os_share_aix.hpp" 16.49 +#include "porting_aix.hpp" 16.50 +#include "prims/jniFastGetField.hpp" 16.51 +#include "prims/jvm.h" 16.52 +#include "prims/jvm_misc.hpp" 16.53 +#include "runtime/arguments.hpp" 16.54 +#include "runtime/extendedPC.hpp" 16.55 +#include "runtime/globals.hpp" 16.56 +#include "runtime/interfaceSupport.hpp" 16.57 +#include "runtime/java.hpp" 16.58 +#include "runtime/javaCalls.hpp" 16.59 +#include "runtime/mutexLocker.hpp" 16.60 +#include "runtime/objectMonitor.hpp" 16.61 +#include "runtime/osThread.hpp" 16.62 +#include "runtime/perfMemory.hpp" 16.63 +#include "runtime/sharedRuntime.hpp" 16.64 +#include "runtime/statSampler.hpp" 16.65 +#include "runtime/stubRoutines.hpp" 16.66 +#include "runtime/threadCritical.hpp" 16.67 +#include "runtime/timer.hpp" 16.68 +#include "services/attachListener.hpp" 16.69 +#include "services/runtimeService.hpp" 16.70 +#include "thread_aix.inline.hpp" 16.71 +#include "utilities/decoder.hpp" 16.72 +#include "utilities/defaultStream.hpp" 16.73 +#include "utilities/events.hpp" 16.74 +#include "utilities/growableArray.hpp" 16.75 +#include "utilities/vmError.hpp" 16.76 +#ifdef TARGET_ARCH_ppc 16.77 +# include "assembler_ppc.inline.hpp" 16.78 +# include "nativeInst_ppc.hpp" 16.79 +#endif 16.80 +#ifdef COMPILER1 16.81 +#include "c1/c1_Runtime1.hpp" 16.82 +#endif 16.83 +#ifdef COMPILER2 16.84 +#include "opto/runtime.hpp" 16.85 +#endif 16.86 + 16.87 +// put OS-includes here (sorted alphabetically) 16.88 +#include <errno.h> 16.89 +#include <fcntl.h> 16.90 +#include <inttypes.h> 16.91 +#include <poll.h> 16.92 +#include <procinfo.h> 16.93 +#include <pthread.h> 16.94 +#include <pwd.h> 16.95 +#include <semaphore.h> 16.96 +#include <signal.h> 16.97 +#include <stdint.h> 16.98 +#include <stdio.h> 16.99 +#include <string.h> 16.100 +#include <unistd.h> 16.101 +#include <sys/ioctl.h> 16.102 +#include <sys/ipc.h> 16.103 +#include <sys/mman.h> 16.104 +#include <sys/resource.h> 16.105 +#include <sys/select.h> 16.106 +#include <sys/shm.h> 16.107 +#include <sys/socket.h> 16.108 +#include <sys/stat.h> 16.109 +#include <sys/sysinfo.h> 16.110 +#include <sys/systemcfg.h> 16.111 +#include <sys/time.h> 16.112 +#include <sys/times.h> 16.113 +#include <sys/types.h> 16.114 +#include <sys/utsname.h> 16.115 +#include <sys/vminfo.h> 16.116 +#include <sys/wait.h> 16.117 + 16.118 +// Add missing declarations (should be in procinfo.h but isn't until AIX 6.1). 16.119 +#if !defined(_AIXVERSION_610) 16.120 +extern "C" { 16.121 + int getthrds64(pid_t ProcessIdentifier, 16.122 + struct thrdentry64* ThreadBuffer, 16.123 + int ThreadSize, 16.124 + tid64_t* IndexPointer, 16.125 + int Count); 16.126 +} 16.127 +#endif 16.128 + 16.129 +// Excerpts from systemcfg.h definitions newer than AIX 5.3 16.130 +#ifndef PV_7 16.131 +# define PV_7 0x200000 // Power PC 7 16.132 +# define PV_7_Compat 0x208000 // Power PC 7 16.133 +#endif 16.134 + 16.135 +#define MAX_PATH (2 * K) 16.136 + 16.137 +// for timer info max values which include all bits 16.138 +#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) 16.139 +// for multipage initialization error analysis (in 'g_multipage_error') 16.140 +#define ERROR_MP_OS_TOO_OLD 100 16.141 +#define ERROR_MP_EXTSHM_ACTIVE 101 16.142 +#define ERROR_MP_VMGETINFO_FAILED 102 16.143 +#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 16.144 + 16.145 +// the semantics in this file are thus that codeptr_t is a *real code ptr* 16.146 +// This means that any function taking codeptr_t as arguments will assume 16.147 +// a real codeptr and won't handle function descriptors (eg getFuncName), 16.148 +// whereas functions taking address as args will deal with function 16.149 +// descriptors (eg os::dll_address_to_library_name) 16.150 +typedef unsigned int* codeptr_t; 16.151 + 16.152 +// typedefs for stackslots, stack pointers, pointers to op codes 16.153 +typedef unsigned long stackslot_t; 16.154 +typedef stackslot_t* stackptr_t; 16.155 + 16.156 +// query dimensions of the stack of the calling thread 16.157 +static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); 16.158 + 16.159 +// function to check a given stack pointer against given stack limits 16.160 +inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) { 16.161 + if (((uintptr_t)sp) & 0x7) { 16.162 + return false; 16.163 + } 16.164 + if (sp > stack_base) { 16.165 + return false; 16.166 + } 16.167 + if (sp < (stackptr_t) ((address)stack_base - stack_size)) { 16.168 + return false; 16.169 + } 16.170 + return true; 16.171 +} 16.172 + 16.173 +// returns true if function is a valid codepointer 16.174 +inline bool is_valid_codepointer(codeptr_t p) { 16.175 + if (!p) { 16.176 + return false; 16.177 + } 16.178 + if (((uintptr_t)p) & 0x3) { 16.179 + return false; 16.180 + } 16.181 + if (LoadedLibraries::find_for_text_address((address)p) == NULL) { 16.182 + return false; 16.183 + } 16.184 + return true; 16.185 +} 16.186 + 16.187 +// macro to check a given stack pointer against given stack limits and to die if test fails 16.188 +#define CHECK_STACK_PTR(sp, stack_base, stack_size) { \ 16.189 + guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \ 16.190 +} 16.191 + 16.192 +// macro to check the current stack pointer against given stacklimits 16.193 +#define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \ 16.194 + address sp; \ 16.195 + sp = os::current_stack_pointer(); \ 16.196 + CHECK_STACK_PTR(sp, stack_base, stack_size); \ 16.197 +} 16.198 + 16.199 +//////////////////////////////////////////////////////////////////////////////// 16.200 +// global variables (for a description see os_aix.hpp) 16.201 + 16.202 +julong os::Aix::_physical_memory = 0; 16.203 +pthread_t os::Aix::_main_thread = ((pthread_t)0); 16.204 +int os::Aix::_page_size = -1; 16.205 +int os::Aix::_on_pase = -1; 16.206 +int os::Aix::_os_version = -1; 16.207 +int os::Aix::_stack_page_size = -1; 16.208 +size_t os::Aix::_shm_default_page_size = -1; 16.209 +int os::Aix::_can_use_64K_pages = -1; 16.210 +int os::Aix::_can_use_16M_pages = -1; 16.211 +int os::Aix::_xpg_sus_mode = -1; 16.212 +int os::Aix::_extshm = -1; 16.213 +int os::Aix::_logical_cpus = -1; 16.214 + 16.215 +//////////////////////////////////////////////////////////////////////////////// 16.216 +// local variables 16.217 + 16.218 +static int g_multipage_error = -1; // error analysis for multipage initialization 16.219 +static jlong initial_time_count = 0; 16.220 +static int clock_tics_per_sec = 100; 16.221 +static sigset_t check_signal_done; // For diagnostics to print a message once (see run_periodic_checks) 16.222 +static bool check_signals = true; 16.223 +static pid_t _initial_pid = 0; 16.224 +static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) 16.225 +static sigset_t SR_sigset; 16.226 +static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls */ 16.227 + 16.228 +julong os::available_memory() { 16.229 + return Aix::available_memory(); 16.230 +} 16.231 + 16.232 +julong os::Aix::available_memory() { 16.233 + Unimplemented(); 16.234 + return 0; 16.235 +} 16.236 + 16.237 +julong os::physical_memory() { 16.238 + return Aix::physical_memory(); 16.239 +} 16.240 + 16.241 +//////////////////////////////////////////////////////////////////////////////// 16.242 +// environment support 16.243 + 16.244 +bool os::getenv(const char* name, char* buf, int len) { 16.245 + const char* val = ::getenv(name); 16.246 + if (val != NULL && strlen(val) < (size_t)len) { 16.247 + strcpy(buf, val); 16.248 + return true; 16.249 + } 16.250 + if (len > 0) buf[0] = 0; // return a null string 16.251 + return false; 16.252 +} 16.253 + 16.254 + 16.255 +// Return true if user is running as root. 16.256 + 16.257 +bool os::have_special_privileges() { 16.258 + static bool init = false; 16.259 + static bool privileges = false; 16.260 + if (!init) { 16.261 + privileges = (getuid() != geteuid()) || (getgid() != getegid()); 16.262 + init = true; 16.263 + } 16.264 + return privileges; 16.265 +} 16.266 + 16.267 +// Helper function, emulates disclaim64 using multiple 32bit disclaims 16.268 +// because we cannot use disclaim64() on AS/400 and old AIX releases. 16.269 +static bool my_disclaim64(char* addr, size_t size) { 16.270 + 16.271 + if (size == 0) { 16.272 + return true; 16.273 + } 16.274 + 16.275 + // Maximum size 32bit disclaim() accepts. (Theoretically 4GB, but I just do not trust that.) 16.276 + const unsigned int maxDisclaimSize = 0x80000000; 16.277 + 16.278 + const unsigned int numFullDisclaimsNeeded = (size / maxDisclaimSize); 16.279 + const unsigned int lastDisclaimSize = (size % maxDisclaimSize); 16.280 + 16.281 + char* p = addr; 16.282 + 16.283 + for (int i = 0; i < numFullDisclaimsNeeded; i ++) { 16.284 + if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { 16.285 + //if (Verbose) 16.286 + fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); 16.287 + return false; 16.288 + } 16.289 + p += maxDisclaimSize; 16.290 + } 16.291 + 16.292 + if (lastDisclaimSize > 0) { 16.293 + if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { 16.294 + //if (Verbose) 16.295 + fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); 16.296 + return false; 16.297 + } 16.298 + } 16.299 + 16.300 + return true; 16.301 +} 16.302 + 16.303 +// Cpu architecture string 16.304 +#if defined(PPC32) 16.305 +static char cpu_arch[] = "ppc"; 16.306 +#elif defined(PPC64) 16.307 +static char cpu_arch[] = "ppc64"; 16.308 +#else 16.309 +#error Add appropriate cpu_arch setting 16.310 +#endif 16.311 + 16.312 + 16.313 +// Given an address, returns the size of the page backing that address. 16.314 +size_t os::Aix::query_pagesize(void* addr) { 16.315 + 16.316 + vm_page_info pi; 16.317 + pi.addr = (uint64_t)addr; 16.318 + if (::vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) { 16.319 + return pi.pagesize; 16.320 + } else { 16.321 + fprintf(stderr, "vmgetinfo failed to retrieve page size for address %p (errno %d).\n", addr, errno); 16.322 + assert(false, "vmgetinfo failed to retrieve page size"); 16.323 + return SIZE_4K; 16.324 + } 16.325 + 16.326 +} 16.327 + 16.328 +// Returns the kernel thread id of the currently running thread. 16.329 +pid_t os::Aix::gettid() { 16.330 + return (pid_t) thread_self(); 16.331 +} 16.332 + 16.333 +void os::Aix::initialize_system_info() { 16.334 + 16.335 + // get the number of online(logical) cpus instead of configured 16.336 + os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN); 16.337 + assert(_processor_count > 0, "_processor_count must be > 0"); 16.338 + 16.339 + // retrieve total physical storage 16.340 + os::Aix::meminfo_t mi; 16.341 + if (!os::Aix::get_meminfo(&mi)) { 16.342 + fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); 16.343 + assert(false, "os::Aix::get_meminfo failed."); 16.344 + } 16.345 + _physical_memory = (julong) mi.real_total; 16.346 +} 16.347 + 16.348 +// Helper function for tracing page sizes. 16.349 +static const char* describe_pagesize(size_t pagesize) { 16.350 + switch (pagesize) { 16.351 + case SIZE_4K : return "4K"; 16.352 + case SIZE_64K: return "64K"; 16.353 + case SIZE_16M: return "16M"; 16.354 + case SIZE_16G: return "16G"; 16.355 + default: 16.356 + assert(false, "surprise"); 16.357 + return "??"; 16.358 + } 16.359 +} 16.360 + 16.361 +// Retrieve information about multipage size support. Will initialize 16.362 +// Aix::_page_size, Aix::_stack_page_size, Aix::_can_use_64K_pages, 16.363 +// Aix::_can_use_16M_pages. 16.364 +// Must be called before calling os::large_page_init(). 16.365 +void os::Aix::query_multipage_support() { 16.366 + 16.367 + guarantee(_page_size == -1 && 16.368 + _stack_page_size == -1 && 16.369 + _can_use_64K_pages == -1 && 16.370 + _can_use_16M_pages == -1 && 16.371 + g_multipage_error == -1, 16.372 + "do not call twice"); 16.373 + 16.374 + _page_size = ::sysconf(_SC_PAGESIZE); 16.375 + 16.376 + // This really would surprise me. 16.377 + assert(_page_size == SIZE_4K, "surprise!"); 16.378 + 16.379 + 16.380 + // query default data page size (default page size for C-Heap, pthread stacks and .bss). 16.381 + // Default data page size is influenced either by linker options (-bdatapsize) 16.382 + // or by environment variable LDR_CNTRL (suboption DATAPSIZE). If none is given, 16.383 + // default should be 4K. 16.384 + size_t data_page_size = SIZE_4K; 16.385 + { 16.386 + void* p = ::malloc(SIZE_16M); 16.387 + data_page_size = os::Aix::query_pagesize(p); 16.388 + ::free(p); 16.389 + } 16.390 + 16.391 + // query default shm page size (LDR_CNTRL SHMPSIZE) 16.392 + { 16.393 + const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR); 16.394 + guarantee(shmid != -1, "shmget failed"); 16.395 + void* p = ::shmat(shmid, NULL, 0); 16.396 + ::shmctl(shmid, IPC_RMID, NULL); 16.397 + guarantee(p != (void*) -1, "shmat failed"); 16.398 + _shm_default_page_size = os::Aix::query_pagesize(p); 16.399 + ::shmdt(p); 16.400 + } 16.401 + 16.402 + // before querying the stack page size, make sure we are not running as primordial 16.403 + // thread (because primordial thread's stack may have different page size than 16.404 + // pthread thread stacks). Running a VM on the primordial thread won't work for a 16.405 + // number of reasons so we may just as well guarantee it here 16.406 + guarantee(!os::Aix::is_primordial_thread(), "Must not be called for primordial thread"); 16.407 + 16.408 + // query stack page size 16.409 + { 16.410 + int dummy = 0; 16.411 + _stack_page_size = os::Aix::query_pagesize(&dummy); 16.412 + // everything else would surprise me and should be looked into 16.413 + guarantee(_stack_page_size == SIZE_4K || _stack_page_size == SIZE_64K, "Wrong page size"); 16.414 + // also, just for completeness: pthread stacks are allocated from C heap, so 16.415 + // stack page size should be the same as data page size 16.416 + guarantee(_stack_page_size == data_page_size, "stack page size should be the same as data page size"); 16.417 + } 16.418 + 16.419 + // EXTSHM is bad: among other things, it prevents setting pagesize dynamically 16.420 + // for system V shm. 16.421 + if (Aix::extshm()) { 16.422 + if (Verbose) { 16.423 + fprintf(stderr, "EXTSHM is active - will disable large page support.\n" 16.424 + "Please make sure EXTSHM is OFF for large page support.\n"); 16.425 + } 16.426 + g_multipage_error = ERROR_MP_EXTSHM_ACTIVE; 16.427 + _can_use_64K_pages = _can_use_16M_pages = 0; 16.428 + goto query_multipage_support_end; 16.429 + } 16.430 + 16.431 + // now check which page sizes the OS claims it supports, and of those, which actually can be used. 16.432 + { 16.433 + const int MAX_PAGE_SIZES = 4; 16.434 + psize_t sizes[MAX_PAGE_SIZES]; 16.435 + const int num_psizes = ::vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES); 16.436 + if (num_psizes == -1) { 16.437 + if (Verbose) { 16.438 + fprintf(stderr, "vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)\n", errno); 16.439 + fprintf(stderr, "disabling multipage support.\n"); 16.440 + } 16.441 + g_multipage_error = ERROR_MP_VMGETINFO_FAILED; 16.442 + _can_use_64K_pages = _can_use_16M_pages = 0; 16.443 + goto query_multipage_support_end; 16.444 + } 16.445 + guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed."); 16.446 + assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?"); 16.447 + if (Verbose) { 16.448 + fprintf(stderr, "vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes); 16.449 + for (int i = 0; i < num_psizes; i ++) { 16.450 + fprintf(stderr, " %s ", describe_pagesize(sizes[i])); 16.451 + } 16.452 + fprintf(stderr, " .\n"); 16.453 + } 16.454 + 16.455 + // Can we use 64K, 16M pages? 16.456 + _can_use_64K_pages = 0; 16.457 + _can_use_16M_pages = 0; 16.458 + for (int i = 0; i < num_psizes; i ++) { 16.459 + if (sizes[i] == SIZE_64K) { 16.460 + _can_use_64K_pages = 1; 16.461 + } else if (sizes[i] == SIZE_16M) { 16.462 + _can_use_16M_pages = 1; 16.463 + } 16.464 + } 16.465 + 16.466 + if (!_can_use_64K_pages) { 16.467 + g_multipage_error = ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K; 16.468 + } 16.469 + 16.470 + // Double-check for 16M pages: Even if AIX claims to be able to use 16M pages, 16.471 + // there must be an actual 16M page pool, and we must run with enough rights. 16.472 + if (_can_use_16M_pages) { 16.473 + const int shmid = ::shmget(IPC_PRIVATE, SIZE_16M, IPC_CREAT | S_IRUSR | S_IWUSR); 16.474 + guarantee(shmid != -1, "shmget failed"); 16.475 + struct shmid_ds shm_buf = { 0 }; 16.476 + shm_buf.shm_pagesize = SIZE_16M; 16.477 + const bool can_set_pagesize = ::shmctl(shmid, SHM_PAGESIZE, &shm_buf) == 0 ? true : false; 16.478 + const int en = errno; 16.479 + ::shmctl(shmid, IPC_RMID, NULL); 16.480 + if (!can_set_pagesize) { 16.481 + if (Verbose) { 16.482 + fprintf(stderr, "Failed to allocate even one misely 16M page. shmctl failed with %d (%s).\n" 16.483 + "Will deactivate 16M support.\n", en, strerror(en)); 16.484 + } 16.485 + _can_use_16M_pages = 0; 16.486 + } 16.487 + } 16.488 + 16.489 + } // end: check which pages can be used for shared memory 16.490 + 16.491 +query_multipage_support_end: 16.492 + 16.493 + guarantee(_page_size != -1 && 16.494 + _stack_page_size != -1 && 16.495 + _can_use_64K_pages != -1 && 16.496 + _can_use_16M_pages != -1, "Page sizes not properly initialized"); 16.497 + 16.498 + if (_can_use_64K_pages) { 16.499 + g_multipage_error = 0; 16.500 + } 16.501 + 16.502 + if (Verbose) { 16.503 + fprintf(stderr, "Data page size (C-Heap, bss, etc): %s\n", describe_pagesize(data_page_size)); 16.504 + fprintf(stderr, "Thread stack page size (pthread): %s\n", describe_pagesize(_stack_page_size)); 16.505 + fprintf(stderr, "Default shared memory page size: %s\n", describe_pagesize(_shm_default_page_size)); 16.506 + fprintf(stderr, "Can use 64K pages dynamically with shared meory: %s\n", (_can_use_64K_pages ? "yes" :"no")); 16.507 + fprintf(stderr, "Can use 16M pages dynamically with shared memory: %s\n", (_can_use_16M_pages ? "yes" :"no")); 16.508 + fprintf(stderr, "Multipage error details: %d\n", g_multipage_error); 16.509 + } 16.510 + 16.511 +} // end os::Aix::query_multipage_support() 16.512 + 16.513 + 16.514 +// The code for this method was initially derived from the version in os_linux.cpp 16.515 +void os::init_system_properties_values() { 16.516 + // The next few definitions allow the code to be verbatim: 16.517 +#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal) 16.518 +#define DEFAULT_LIBPATH "/usr/lib:/lib" 16.519 +#define EXTENSIONS_DIR "/lib/ext" 16.520 +#define ENDORSED_DIR "/lib/endorsed" 16.521 + 16.522 + // sysclasspath, java_home, dll_dir 16.523 + char *home_path; 16.524 + char *dll_path; 16.525 + char *pslash; 16.526 + char buf[MAXPATHLEN]; 16.527 + os::jvm_path(buf, sizeof(buf)); 16.528 + 16.529 + // Found the full path to libjvm.so. 16.530 + // Now cut the path to <java_home>/jre if we can. 16.531 + *(strrchr(buf, '/')) = '\0'; // get rid of /libjvm.so 16.532 + pslash = strrchr(buf, '/'); 16.533 + if (pslash != NULL) { 16.534 + *pslash = '\0'; // get rid of /{client|server|hotspot} 16.535 + } 16.536 + 16.537 + dll_path = malloc(strlen(buf) + 1); 16.538 + strcpy(dll_path, buf); 16.539 + Arguments::set_dll_dir(dll_path); 16.540 + 16.541 + if (pslash != NULL) { 16.542 + pslash = strrchr(buf, '/'); 16.543 + if (pslash != NULL) { 16.544 + *pslash = '\0'; // get rid of /<arch> 16.545 + pslash = strrchr(buf, '/'); 16.546 + if (pslash != NULL) { 16.547 + *pslash = '\0'; // get rid of /lib 16.548 + } 16.549 + } 16.550 + } 16.551 + 16.552 + home_path = malloc(strlen(buf) + 1); 16.553 + strcpy(home_path, buf); 16.554 + Arguments::set_java_home(home_path); 16.555 + 16.556 + if (!set_boot_path('/', ':')) return; 16.557 + 16.558 + // Where to look for native libraries 16.559 + 16.560 + // On Aix we get the user setting of LIBPATH 16.561 + // Eventually, all the library path setting will be done here. 16.562 + char *ld_library_path; 16.563 + 16.564 + // Construct the invariant part of ld_library_path. 16.565 + ld_library_path = (char *) malloc(sizeof(DEFAULT_LIBPATH)); 16.566 + sprintf(ld_library_path, DEFAULT_LIBPATH); 16.567 + 16.568 + // Get the user setting of LIBPATH, and prepended it. 16.569 + char *v = ::getenv("LIBPATH"); 16.570 + if (v == NULL) { 16.571 + v = ""; 16.572 + } 16.573 + 16.574 + char *t = ld_library_path; 16.575 + // That's +1 for the colon and +1 for the trailing '\0' 16.576 + ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1); 16.577 + sprintf(ld_library_path, "%s:%s", v, t); 16.578 + 16.579 + Arguments::set_library_path(ld_library_path); 16.580 + 16.581 + // Extensions directories 16.582 + char* cbuf = malloc(strlen(Arguments::get_java_home()) + sizeof(EXTENSIONS_DIR)); 16.583 + sprintf(cbuf, "%s" EXTENSIONS_DIR, Arguments::get_java_home()); 16.584 + Arguments::set_ext_dirs(cbuf); 16.585 + 16.586 + // Endorsed standards default directory. 16.587 + cbuf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR)); 16.588 + sprintf(cbuf, "%s" ENDORSED_DIR, Arguments::get_java_home()); 16.589 + Arguments::set_endorsed_dirs(cbuf); 16.590 + 16.591 +#undef malloc 16.592 +#undef DEFAULT_LIBPATH 16.593 +#undef EXTENSIONS_DIR 16.594 +#undef ENDORSED_DIR 16.595 +} 16.596 + 16.597 +//////////////////////////////////////////////////////////////////////////////// 16.598 +// breakpoint support 16.599 + 16.600 +void os::breakpoint() { 16.601 + BREAKPOINT; 16.602 +} 16.603 + 16.604 +extern "C" void breakpoint() { 16.605 + // use debugger to set breakpoint here 16.606 +} 16.607 + 16.608 +//////////////////////////////////////////////////////////////////////////////// 16.609 +// signal support 16.610 + 16.611 +debug_only(static bool signal_sets_initialized = false); 16.612 +static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; 16.613 + 16.614 +bool os::Aix::is_sig_ignored(int sig) { 16.615 + struct sigaction oact; 16.616 + sigaction(sig, (struct sigaction*)NULL, &oact); 16.617 + void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) 16.618 + : CAST_FROM_FN_PTR(void*, oact.sa_handler); 16.619 + if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) 16.620 + return true; 16.621 + else 16.622 + return false; 16.623 +} 16.624 + 16.625 +void os::Aix::signal_sets_init() { 16.626 + // Should also have an assertion stating we are still single-threaded. 16.627 + assert(!signal_sets_initialized, "Already initialized"); 16.628 + // Fill in signals that are necessarily unblocked for all threads in 16.629 + // the VM. Currently, we unblock the following signals: 16.630 + // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden 16.631 + // by -Xrs (=ReduceSignalUsage)); 16.632 + // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all 16.633 + // other threads. The "ReduceSignalUsage" boolean tells us not to alter 16.634 + // the dispositions or masks wrt these signals. 16.635 + // Programs embedding the VM that want to use the above signals for their 16.636 + // own purposes must, at this time, use the "-Xrs" option to prevent 16.637 + // interference with shutdown hooks and BREAK_SIGNAL thread dumping. 16.638 + // (See bug 4345157, and other related bugs). 16.639 + // In reality, though, unblocking these signals is really a nop, since 16.640 + // these signals are not blocked by default. 16.641 + sigemptyset(&unblocked_sigs); 16.642 + sigemptyset(&allowdebug_blocked_sigs); 16.643 + sigaddset(&unblocked_sigs, SIGILL); 16.644 + sigaddset(&unblocked_sigs, SIGSEGV); 16.645 + sigaddset(&unblocked_sigs, SIGBUS); 16.646 + sigaddset(&unblocked_sigs, SIGFPE); 16.647 + sigaddset(&unblocked_sigs, SIGTRAP); 16.648 + sigaddset(&unblocked_sigs, SIGDANGER); 16.649 + sigaddset(&unblocked_sigs, SR_signum); 16.650 + 16.651 + if (!ReduceSignalUsage) { 16.652 + if (!os::Aix::is_sig_ignored(SHUTDOWN1_SIGNAL)) { 16.653 + sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); 16.654 + sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); 16.655 + } 16.656 + if (!os::Aix::is_sig_ignored(SHUTDOWN2_SIGNAL)) { 16.657 + sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); 16.658 + sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); 16.659 + } 16.660 + if (!os::Aix::is_sig_ignored(SHUTDOWN3_SIGNAL)) { 16.661 + sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); 16.662 + sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); 16.663 + } 16.664 + } 16.665 + // Fill in signals that are blocked by all but the VM thread. 16.666 + sigemptyset(&vm_sigs); 16.667 + if (!ReduceSignalUsage) 16.668 + sigaddset(&vm_sigs, BREAK_SIGNAL); 16.669 + debug_only(signal_sets_initialized = true); 16.670 +} 16.671 + 16.672 +// These are signals that are unblocked while a thread is running Java. 16.673 +// (For some reason, they get blocked by default.) 16.674 +sigset_t* os::Aix::unblocked_signals() { 16.675 + assert(signal_sets_initialized, "Not initialized"); 16.676 + return &unblocked_sigs; 16.677 +} 16.678 + 16.679 +// These are the signals that are blocked while a (non-VM) thread is 16.680 +// running Java. Only the VM thread handles these signals. 16.681 +sigset_t* os::Aix::vm_signals() { 16.682 + assert(signal_sets_initialized, "Not initialized"); 16.683 + return &vm_sigs; 16.684 +} 16.685 + 16.686 +// These are signals that are blocked during cond_wait to allow debugger in 16.687 +sigset_t* os::Aix::allowdebug_blocked_signals() { 16.688 + assert(signal_sets_initialized, "Not initialized"); 16.689 + return &allowdebug_blocked_sigs; 16.690 +} 16.691 + 16.692 +void os::Aix::hotspot_sigmask(Thread* thread) { 16.693 + 16.694 + //Save caller's signal mask before setting VM signal mask 16.695 + sigset_t caller_sigmask; 16.696 + pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask); 16.697 + 16.698 + OSThread* osthread = thread->osthread(); 16.699 + osthread->set_caller_sigmask(caller_sigmask); 16.700 + 16.701 + pthread_sigmask(SIG_UNBLOCK, os::Aix::unblocked_signals(), NULL); 16.702 + 16.703 + if (!ReduceSignalUsage) { 16.704 + if (thread->is_VM_thread()) { 16.705 + // Only the VM thread handles BREAK_SIGNAL ... 16.706 + pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL); 16.707 + } else { 16.708 + // ... all other threads block BREAK_SIGNAL 16.709 + pthread_sigmask(SIG_BLOCK, vm_signals(), NULL); 16.710 + } 16.711 + } 16.712 +} 16.713 + 16.714 +// retrieve memory information. 16.715 +// Returns false if something went wrong; 16.716 +// content of pmi undefined in this case. 16.717 +bool os::Aix::get_meminfo(meminfo_t* pmi) { 16.718 + 16.719 + assert(pmi, "get_meminfo: invalid parameter"); 16.720 + 16.721 + memset(pmi, 0, sizeof(meminfo_t)); 16.722 + 16.723 + if (os::Aix::on_pase()) { 16.724 + 16.725 + Unimplemented(); 16.726 + return false; 16.727 + 16.728 + } else { 16.729 + 16.730 + // On AIX, I use the (dynamically loaded) perfstat library to retrieve memory statistics 16.731 + // See: 16.732 + // http://publib.boulder.ibm.com/infocenter/systems/index.jsp 16.733 + // ?topic=/com.ibm.aix.basetechref/doc/basetrf1/perfstat_memtot.htm 16.734 + // http://publib.boulder.ibm.com/infocenter/systems/index.jsp 16.735 + // ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm 16.736 + 16.737 + perfstat_memory_total_t psmt; 16.738 + memset (&psmt, '\0', sizeof(psmt)); 16.739 + const int rc = libperfstat::perfstat_memory_total(NULL, &psmt, sizeof(psmt), 1); 16.740 + if (rc == -1) { 16.741 + fprintf(stderr, "perfstat_memory_total() failed (errno=%d)\n", errno); 16.742 + assert(0, "perfstat_memory_total() failed"); 16.743 + return false; 16.744 + } 16.745 + 16.746 + assert(rc == 1, "perfstat_memory_total() - weird return code"); 16.747 + 16.748 + // excerpt from 16.749 + // http://publib.boulder.ibm.com/infocenter/systems/index.jsp 16.750 + // ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm 16.751 + // The fields of perfstat_memory_total_t: 16.752 + // u_longlong_t virt_total Total virtual memory (in 4 KB pages). 16.753 + // u_longlong_t real_total Total real memory (in 4 KB pages). 16.754 + // u_longlong_t real_free Free real memory (in 4 KB pages). 16.755 + // u_longlong_t pgsp_total Total paging space (in 4 KB pages). 16.756 + // u_longlong_t pgsp_free Free paging space (in 4 KB pages). 16.757 + 16.758 + pmi->virt_total = psmt.virt_total * 4096; 16.759 + pmi->real_total = psmt.real_total * 4096; 16.760 + pmi->real_free = psmt.real_free * 4096; 16.761 + pmi->pgsp_total = psmt.pgsp_total * 4096; 16.762 + pmi->pgsp_free = psmt.pgsp_free * 4096; 16.763 + 16.764 + return true; 16.765 + 16.766 + } 16.767 +} // end os::Aix::get_meminfo 16.768 + 16.769 +// Retrieve global cpu information. 16.770 +// Returns false if something went wrong; 16.771 +// the content of pci is undefined in this case. 16.772 +bool os::Aix::get_cpuinfo(cpuinfo_t* pci) { 16.773 + assert(pci, "get_cpuinfo: invalid parameter"); 16.774 + memset(pci, 0, sizeof(cpuinfo_t)); 16.775 + 16.776 + perfstat_cpu_total_t psct; 16.777 + memset (&psct, '\0', sizeof(psct)); 16.778 + 16.779 + if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t), 1)) { 16.780 + fprintf(stderr, "perfstat_cpu_total() failed (errno=%d)\n", errno); 16.781 + assert(0, "perfstat_cpu_total() failed"); 16.782 + return false; 16.783 + } 16.784 + 16.785 + // global cpu information 16.786 + strcpy (pci->description, psct.description); 16.787 + pci->processorHZ = psct.processorHZ; 16.788 + pci->ncpus = psct.ncpus; 16.789 + os::Aix::_logical_cpus = psct.ncpus; 16.790 + for (int i = 0; i < 3; i++) { 16.791 + pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS); 16.792 + } 16.793 + 16.794 + // get the processor version from _system_configuration 16.795 + switch (_system_configuration.version) { 16.796 + case PV_7: 16.797 + strcpy(pci->version, "Power PC 7"); 16.798 + break; 16.799 + case PV_6_1: 16.800 + strcpy(pci->version, "Power PC 6 DD1.x"); 16.801 + break; 16.802 + case PV_6: 16.803 + strcpy(pci->version, "Power PC 6"); 16.804 + break; 16.805 + case PV_5: 16.806 + strcpy(pci->version, "Power PC 5"); 16.807 + break; 16.808 + case PV_5_2: 16.809 + strcpy(pci->version, "Power PC 5_2"); 16.810 + break; 16.811 + case PV_5_3: 16.812 + strcpy(pci->version, "Power PC 5_3"); 16.813 + break; 16.814 + case PV_5_Compat: 16.815 + strcpy(pci->version, "PV_5_Compat"); 16.816 + break; 16.817 + case PV_6_Compat: 16.818 + strcpy(pci->version, "PV_6_Compat"); 16.819 + break; 16.820 + case PV_7_Compat: 16.821 + strcpy(pci->version, "PV_7_Compat"); 16.822 + break; 16.823 + default: 16.824 + strcpy(pci->version, "unknown"); 16.825 + } 16.826 + 16.827 + return true; 16.828 + 16.829 +} //end os::Aix::get_cpuinfo 16.830 + 16.831 +////////////////////////////////////////////////////////////////////////////// 16.832 +// detecting pthread library 16.833 + 16.834 +void os::Aix::libpthread_init() { 16.835 + return; 16.836 +} 16.837 + 16.838 +////////////////////////////////////////////////////////////////////////////// 16.839 +// create new thread 16.840 + 16.841 +// Thread start routine for all newly created threads 16.842 +static void *java_start(Thread *thread) { 16.843 + 16.844 + // find out my own stack dimensions 16.845 + { 16.846 + // actually, this should do exactly the same as thread->record_stack_base_and_size... 16.847 + address base = 0; 16.848 + size_t size = 0; 16.849 + query_stack_dimensions(&base, &size); 16.850 + thread->set_stack_base(base); 16.851 + thread->set_stack_size(size); 16.852 + } 16.853 + 16.854 + // Do some sanity checks. 16.855 + CHECK_CURRENT_STACK_PTR(thread->stack_base(), thread->stack_size()); 16.856 + 16.857 + // Try to randomize the cache line index of hot stack frames. 16.858 + // This helps when threads of the same stack traces evict each other's 16.859 + // cache lines. The threads can be either from the same JVM instance, or 16.860 + // from different JVM instances. The benefit is especially true for 16.861 + // processors with hyperthreading technology. 16.862 + 16.863 + static int counter = 0; 16.864 + int pid = os::current_process_id(); 16.865 + alloca(((pid ^ counter++) & 7) * 128); 16.866 + 16.867 + ThreadLocalStorage::set_thread(thread); 16.868 + 16.869 + OSThread* osthread = thread->osthread(); 16.870 + 16.871 + // thread_id is kernel thread id (similar to Solaris LWP id) 16.872 + osthread->set_thread_id(os::Aix::gettid()); 16.873 + 16.874 + // initialize signal mask for this thread 16.875 + os::Aix::hotspot_sigmask(thread); 16.876 + 16.877 + // initialize floating point control register 16.878 + os::Aix::init_thread_fpu_state(); 16.879 + 16.880 + assert(osthread->get_state() == RUNNABLE, "invalid os thread state"); 16.881 + 16.882 + // call one more level start routine 16.883 + thread->run(); 16.884 + 16.885 + return 0; 16.886 +} 16.887 + 16.888 +bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { 16.889 + 16.890 + // We want the whole function to be synchronized. 16.891 + ThreadCritical cs; 16.892 + 16.893 + assert(thread->osthread() == NULL, "caller responsible"); 16.894 + 16.895 + // Allocate the OSThread object 16.896 + OSThread* osthread = new OSThread(NULL, NULL); 16.897 + if (osthread == NULL) { 16.898 + return false; 16.899 + } 16.900 + 16.901 + // set the correct thread state 16.902 + osthread->set_thread_type(thr_type); 16.903 + 16.904 + // Initial state is ALLOCATED but not INITIALIZED 16.905 + osthread->set_state(ALLOCATED); 16.906 + 16.907 + thread->set_osthread(osthread); 16.908 + 16.909 + // init thread attributes 16.910 + pthread_attr_t attr; 16.911 + pthread_attr_init(&attr); 16.912 + guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???"); 16.913 + 16.914 + // Make sure we run in 1:1 kernel-user-thread mode. 16.915 + if (os::Aix::on_aix()) { 16.916 + guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???"); 16.917 + guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???"); 16.918 + } // end: aix 16.919 + 16.920 + // Start in suspended state, and in os::thread_start, wake the thread up. 16.921 + guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???"); 16.922 + 16.923 + // calculate stack size if it's not specified by caller 16.924 + if (os::Aix::supports_variable_stack_size()) { 16.925 + if (stack_size == 0) { 16.926 + stack_size = os::Aix::default_stack_size(thr_type); 16.927 + 16.928 + switch (thr_type) { 16.929 + case os::java_thread: 16.930 + // Java threads use ThreadStackSize whose default value can be changed with the flag -Xss. 16.931 + assert(JavaThread::stack_size_at_create() > 0, "this should be set"); 16.932 + stack_size = JavaThread::stack_size_at_create(); 16.933 + break; 16.934 + case os::compiler_thread: 16.935 + if (CompilerThreadStackSize > 0) { 16.936 + stack_size = (size_t)(CompilerThreadStackSize * K); 16.937 + break; 16.938 + } // else fall through: 16.939 + // use VMThreadStackSize if CompilerThreadStackSize is not defined 16.940 + case os::vm_thread: 16.941 + case os::pgc_thread: 16.942 + case os::cgc_thread: 16.943 + case os::watcher_thread: 16.944 + if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); 16.945 + break; 16.946 + } 16.947 + } 16.948 + 16.949 + stack_size = MAX2(stack_size, os::Aix::min_stack_allowed); 16.950 + pthread_attr_setstacksize(&attr, stack_size); 16.951 + } //else let thread_create() pick the default value (96 K on AIX) 16.952 + 16.953 + pthread_t tid; 16.954 + int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); 16.955 + 16.956 + pthread_attr_destroy(&attr); 16.957 + 16.958 + if (ret != 0) { 16.959 + if (PrintMiscellaneous && (Verbose || WizardMode)) { 16.960 + perror("pthread_create()"); 16.961 + } 16.962 + // Need to clean up stuff we've allocated so far 16.963 + thread->set_osthread(NULL); 16.964 + delete osthread; 16.965 + return false; 16.966 + } 16.967 + 16.968 + // Store pthread info into the OSThread 16.969 + osthread->set_pthread_id(tid); 16.970 + 16.971 + return true; 16.972 +} 16.973 + 16.974 +///////////////////////////////////////////////////////////////////////////// 16.975 +// attach existing thread 16.976 + 16.977 +// bootstrap the main thread 16.978 +bool os::create_main_thread(JavaThread* thread) { 16.979 + assert(os::Aix::_main_thread == pthread_self(), "should be called inside main thread"); 16.980 + return create_attached_thread(thread); 16.981 +} 16.982 + 16.983 +bool os::create_attached_thread(JavaThread* thread) { 16.984 +#ifdef ASSERT 16.985 + thread->verify_not_published(); 16.986 +#endif 16.987 + 16.988 + // Allocate the OSThread object 16.989 + OSThread* osthread = new OSThread(NULL, NULL); 16.990 + 16.991 + if (osthread == NULL) { 16.992 + return false; 16.993 + } 16.994 + 16.995 + // Store pthread info into the OSThread 16.996 + osthread->set_thread_id(os::Aix::gettid()); 16.997 + osthread->set_pthread_id(::pthread_self()); 16.998 + 16.999 + // initialize floating point control register 16.1000 + os::Aix::init_thread_fpu_state(); 16.1001 + 16.1002 + // some sanity checks 16.1003 + CHECK_CURRENT_STACK_PTR(thread->stack_base(), thread->stack_size()); 16.1004 + 16.1005 + // Initial thread state is RUNNABLE 16.1006 + osthread->set_state(RUNNABLE); 16.1007 + 16.1008 + thread->set_osthread(osthread); 16.1009 + 16.1010 + if (UseNUMA) { 16.1011 + int lgrp_id = os::numa_get_group_id(); 16.1012 + if (lgrp_id != -1) { 16.1013 + thread->set_lgrp_id(lgrp_id); 16.1014 + } 16.1015 + } 16.1016 + 16.1017 + // initialize signal mask for this thread 16.1018 + // and save the caller's signal mask 16.1019 + os::Aix::hotspot_sigmask(thread); 16.1020 + 16.1021 + return true; 16.1022 +} 16.1023 + 16.1024 +void os::pd_start_thread(Thread* thread) { 16.1025 + int status = pthread_continue_np(thread->osthread()->pthread_id()); 16.1026 + assert(status == 0, "thr_continue failed"); 16.1027 +} 16.1028 + 16.1029 +// Free OS resources related to the OSThread 16.1030 +void os::free_thread(OSThread* osthread) { 16.1031 + assert(osthread != NULL, "osthread not set"); 16.1032 + 16.1033 + if (Thread::current()->osthread() == osthread) { 16.1034 + // Restore caller's signal mask 16.1035 + sigset_t sigmask = osthread->caller_sigmask(); 16.1036 + pthread_sigmask(SIG_SETMASK, &sigmask, NULL); 16.1037 + } 16.1038 + 16.1039 + delete osthread; 16.1040 +} 16.1041 + 16.1042 +////////////////////////////////////////////////////////////////////////////// 16.1043 +// thread local storage 16.1044 + 16.1045 +int os::allocate_thread_local_storage() { 16.1046 + pthread_key_t key; 16.1047 + int rslt = pthread_key_create(&key, NULL); 16.1048 + assert(rslt == 0, "cannot allocate thread local storage"); 16.1049 + return (int)key; 16.1050 +} 16.1051 + 16.1052 +// Note: This is currently not used by VM, as we don't destroy TLS key 16.1053 +// on VM exit. 16.1054 +void os::free_thread_local_storage(int index) { 16.1055 + int rslt = pthread_key_delete((pthread_key_t)index); 16.1056 + assert(rslt == 0, "invalid index"); 16.1057 +} 16.1058 + 16.1059 +void os::thread_local_storage_at_put(int index, void* value) { 16.1060 + int rslt = pthread_setspecific((pthread_key_t)index, value); 16.1061 + assert(rslt == 0, "pthread_setspecific failed"); 16.1062 +} 16.1063 + 16.1064 +extern "C" Thread* get_thread() { 16.1065 + return ThreadLocalStorage::thread(); 16.1066 +} 16.1067 + 16.1068 +//////////////////////////////////////////////////////////////////////////////// 16.1069 +// time support 16.1070 + 16.1071 +// Time since start-up in seconds to a fine granularity. 16.1072 +// Used by VMSelfDestructTimer and the MemProfiler. 16.1073 +double os::elapsedTime() { 16.1074 + return (double)(os::elapsed_counter()) * 0.000001; 16.1075 +} 16.1076 + 16.1077 +jlong os::elapsed_counter() { 16.1078 + timeval time; 16.1079 + int status = gettimeofday(&time, NULL); 16.1080 + return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count; 16.1081 +} 16.1082 + 16.1083 +jlong os::elapsed_frequency() { 16.1084 + return (1000 * 1000); 16.1085 +} 16.1086 + 16.1087 +// For now, we say that linux does not support vtime. I have no idea 16.1088 +// whether it can actually be made to (DLD, 9/13/05). 16.1089 + 16.1090 +bool os::supports_vtime() { return false; } 16.1091 +bool os::enable_vtime() { return false; } 16.1092 +bool os::vtime_enabled() { return false; } 16.1093 +double os::elapsedVTime() { 16.1094 + // better than nothing, but not much 16.1095 + return elapsedTime(); 16.1096 +} 16.1097 + 16.1098 +jlong os::javaTimeMillis() { 16.1099 + timeval time; 16.1100 + int status = gettimeofday(&time, NULL); 16.1101 + assert(status != -1, "aix error at gettimeofday()"); 16.1102 + return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); 16.1103 +} 16.1104 + 16.1105 +// We need to manually declare mread_real_time, 16.1106 +// because IBM didn't provide a prototype in time.h. 16.1107 +// (they probably only ever tested in C, not C++) 16.1108 +extern "C" 16.1109 +int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t); 16.1110 + 16.1111 +jlong os::javaTimeNanos() { 16.1112 + if (os::Aix::on_pase()) { 16.1113 + Unimplemented(); 16.1114 + return 0; 16.1115 + } 16.1116 + else { 16.1117 + // On AIX use the precision of processors real time clock 16.1118 + // or time base registers. 16.1119 + timebasestruct_t time; 16.1120 + int rc; 16.1121 + 16.1122 + // If the CPU has a time register, it will be used and 16.1123 + // we have to convert to real time first. After convertion we have following data: 16.1124 + // time.tb_high [seconds since 00:00:00 UTC on 1.1.1970] 16.1125 + // time.tb_low [nanoseconds after the last full second above] 16.1126 + // We better use mread_real_time here instead of read_real_time 16.1127 + // to ensure that we will get a monotonic increasing time. 16.1128 + if (mread_real_time(&time, TIMEBASE_SZ) != RTC_POWER) { 16.1129 + rc = time_base_to_time(&time, TIMEBASE_SZ); 16.1130 + assert(rc != -1, "aix error at time_base_to_time()"); 16.1131 + } 16.1132 + return jlong(time.tb_high) * (1000 * 1000 * 1000) + jlong(time.tb_low); 16.1133 + } 16.1134 +} 16.1135 + 16.1136 +void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { 16.1137 + { 16.1138 + // gettimeofday - based on time in seconds since the Epoch thus does not wrap 16.1139 + info_ptr->max_value = ALL_64_BITS; 16.1140 + 16.1141 + // gettimeofday is a real time clock so it skips 16.1142 + info_ptr->may_skip_backward = true; 16.1143 + info_ptr->may_skip_forward = true; 16.1144 + } 16.1145 + 16.1146 + info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time 16.1147 +} 16.1148 + 16.1149 +// Return the real, user, and system times in seconds from an 16.1150 +// arbitrary fixed point in the past. 16.1151 +bool os::getTimesSecs(double* process_real_time, 16.1152 + double* process_user_time, 16.1153 + double* process_system_time) { 16.1154 + Unimplemented(); 16.1155 + return false; 16.1156 +} 16.1157 + 16.1158 + 16.1159 +char * os::local_time_string(char *buf, size_t buflen) { 16.1160 + struct tm t; 16.1161 + time_t long_time; 16.1162 + time(&long_time); 16.1163 + localtime_r(&long_time, &t); 16.1164 + jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d", 16.1165 + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, 16.1166 + t.tm_hour, t.tm_min, t.tm_sec); 16.1167 + return buf; 16.1168 +} 16.1169 + 16.1170 +struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { 16.1171 + return localtime_r(clock, res); 16.1172 +} 16.1173 + 16.1174 +//////////////////////////////////////////////////////////////////////////////// 16.1175 +// runtime exit support 16.1176 + 16.1177 +// Note: os::shutdown() might be called very early during initialization, or 16.1178 +// called from signal handler. Before adding something to os::shutdown(), make 16.1179 +// sure it is async-safe and can handle partially initialized VM. 16.1180 +void os::shutdown() { 16.1181 + 16.1182 + // allow PerfMemory to attempt cleanup of any persistent resources 16.1183 + perfMemory_exit(); 16.1184 + 16.1185 + // needs to remove object in file system 16.1186 + AttachListener::abort(); 16.1187 + 16.1188 + // flush buffered output, finish log files 16.1189 + ostream_abort(); 16.1190 + 16.1191 + // Check for abort hook 16.1192 + abort_hook_t abort_hook = Arguments::abort_hook(); 16.1193 + if (abort_hook != NULL) { 16.1194 + abort_hook(); 16.1195 + } 16.1196 + 16.1197 +} 16.1198 + 16.1199 +// Note: os::abort() might be called very early during initialization, or 16.1200 +// called from signal handler. Before adding something to os::abort(), make 16.1201 +// sure it is async-safe and can handle partially initialized VM. 16.1202 +void os::abort(bool dump_core) { 16.1203 + os::shutdown(); 16.1204 + if (dump_core) { 16.1205 +#ifndef PRODUCT 16.1206 + fdStream out(defaultStream::output_fd()); 16.1207 + out.print_raw("Current thread is "); 16.1208 + char buf[16]; 16.1209 + jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id()); 16.1210 + out.print_raw_cr(buf); 16.1211 + out.print_raw_cr("Dumping core ..."); 16.1212 +#endif 16.1213 + ::abort(); // dump core 16.1214 + } 16.1215 + 16.1216 + ::exit(1); 16.1217 +} 16.1218 + 16.1219 +// Die immediately, no exit hook, no abort hook, no cleanup. 16.1220 +void os::die() { 16.1221 + ::abort(); 16.1222 +} 16.1223 + 16.1224 +// Unused on Aix for now. 16.1225 +void os::set_error_file(const char *logfile) {} 16.1226 + 16.1227 + 16.1228 +// This method is a copy of JDK's sysGetLastErrorString 16.1229 +// from src/solaris/hpi/src/system_md.c 16.1230 + 16.1231 +size_t os::lasterror(char *buf, size_t len) { 16.1232 + 16.1233 + if (errno == 0) return 0; 16.1234 + 16.1235 + const char *s = ::strerror(errno); 16.1236 + size_t n = ::strlen(s); 16.1237 + if (n >= len) { 16.1238 + n = len - 1; 16.1239 + } 16.1240 + ::strncpy(buf, s, n); 16.1241 + buf[n] = '\0'; 16.1242 + return n; 16.1243 +} 16.1244 + 16.1245 +intx os::current_thread_id() { return (intx)pthread_self(); } 16.1246 +int os::current_process_id() { 16.1247 + 16.1248 + // This implementation returns a unique pid, the pid of the 16.1249 + // launcher thread that starts the vm 'process'. 16.1250 + 16.1251 + // Under POSIX, getpid() returns the same pid as the 16.1252 + // launcher thread rather than a unique pid per thread. 16.1253 + // Use gettid() if you want the old pre NPTL behaviour. 16.1254 + 16.1255 + // if you are looking for the result of a call to getpid() that 16.1256 + // returns a unique pid for the calling thread, then look at the 16.1257 + // OSThread::thread_id() method in osThread_linux.hpp file 16.1258 + 16.1259 + return (int)(_initial_pid ? _initial_pid : getpid()); 16.1260 +} 16.1261 + 16.1262 +// DLL functions 16.1263 + 16.1264 +const char* os::dll_file_extension() { return ".so"; } 16.1265 + 16.1266 +// This must be hard coded because it's the system's temporary 16.1267 +// directory not the java application's temp directory, ala java.io.tmpdir. 16.1268 +const char* os::get_temp_directory() { return "/tmp"; } 16.1269 + 16.1270 +static bool file_exists(const char* filename) { 16.1271 + struct stat statbuf; 16.1272 + if (filename == NULL || strlen(filename) == 0) { 16.1273 + return false; 16.1274 + } 16.1275 + return os::stat(filename, &statbuf) == 0; 16.1276 +} 16.1277 + 16.1278 +bool os::dll_build_name(char* buffer, size_t buflen, 16.1279 + const char* pname, const char* fname) { 16.1280 + bool retval = false; 16.1281 + // Copied from libhpi 16.1282 + const size_t pnamelen = pname ? strlen(pname) : 0; 16.1283 + 16.1284 + // Return error on buffer overflow. 16.1285 + if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { 16.1286 + *buffer = '\0'; 16.1287 + return retval; 16.1288 + } 16.1289 + 16.1290 + if (pnamelen == 0) { 16.1291 + snprintf(buffer, buflen, "lib%s.so", fname); 16.1292 + retval = true; 16.1293 + } else if (strchr(pname, *os::path_separator()) != NULL) { 16.1294 + int n; 16.1295 + char** pelements = split_path(pname, &n); 16.1296 + for (int i = 0; i < n; i++) { 16.1297 + // Really shouldn't be NULL, but check can't hurt 16.1298 + if (pelements[i] == NULL || strlen(pelements[i]) == 0) { 16.1299 + continue; // skip the empty path values 16.1300 + } 16.1301 + snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); 16.1302 + if (file_exists(buffer)) { 16.1303 + retval = true; 16.1304 + break; 16.1305 + } 16.1306 + } 16.1307 + // release the storage 16.1308 + for (int i = 0; i < n; i++) { 16.1309 + if (pelements[i] != NULL) { 16.1310 + FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); 16.1311 + } 16.1312 + } 16.1313 + if (pelements != NULL) { 16.1314 + FREE_C_HEAP_ARRAY(char*, pelements, mtInternal); 16.1315 + } 16.1316 + } else { 16.1317 + snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); 16.1318 + retval = true; 16.1319 + } 16.1320 + return retval; 16.1321 +} 16.1322 + 16.1323 +// Check if addr is inside libjvm.so. 16.1324 +bool os::address_is_in_vm(address addr) { 16.1325 + 16.1326 + // Input could be a real pc or a function pointer literal. The latter 16.1327 + // would be a function descriptor residing in the data segment of a module. 16.1328 + 16.1329 + const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr); 16.1330 + if (lib) { 16.1331 + if (strcmp(lib->get_shortname(), "libjvm.so") == 0) { 16.1332 + return true; 16.1333 + } else { 16.1334 + return false; 16.1335 + } 16.1336 + } else { 16.1337 + lib = LoadedLibraries::find_for_data_address(addr); 16.1338 + if (lib) { 16.1339 + if (strcmp(lib->get_shortname(), "libjvm.so") == 0) { 16.1340 + return true; 16.1341 + } else { 16.1342 + return false; 16.1343 + } 16.1344 + } else { 16.1345 + return false; 16.1346 + } 16.1347 + } 16.1348 +} 16.1349 + 16.1350 +// Resolve an AIX function descriptor literal to a code pointer. 16.1351 +// If the input is a valid code pointer to a text segment of a loaded module, 16.1352 +// it is returned unchanged. 16.1353 +// If the input is a valid AIX function descriptor, it is resolved to the 16.1354 +// code entry point. 16.1355 +// If the input is neither a valid function descriptor nor a valid code pointer, 16.1356 +// NULL is returned. 16.1357 +static address resolve_function_descriptor_to_code_pointer(address p) { 16.1358 + 16.1359 + const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(p); 16.1360 + if (lib) { 16.1361 + // its a real code pointer 16.1362 + return p; 16.1363 + } else { 16.1364 + lib = LoadedLibraries::find_for_data_address(p); 16.1365 + if (lib) { 16.1366 + // pointer to data segment, potential function descriptor 16.1367 + address code_entry = (address)(((FunctionDescriptor*)p)->entry()); 16.1368 + if (LoadedLibraries::find_for_text_address(code_entry)) { 16.1369 + // Its a function descriptor 16.1370 + return code_entry; 16.1371 + } 16.1372 + } 16.1373 + } 16.1374 + return NULL; 16.1375 +} 16.1376 + 16.1377 +bool os::dll_address_to_function_name(address addr, char *buf, 16.1378 + int buflen, int *offset) { 16.1379 + if (offset) { 16.1380 + *offset = -1; 16.1381 + } 16.1382 + if (buf) { 16.1383 + buf[0] = '\0'; 16.1384 + } 16.1385 + 16.1386 + // Resolve function ptr literals first. 16.1387 + addr = resolve_function_descriptor_to_code_pointer(addr); 16.1388 + if (!addr) { 16.1389 + return false; 16.1390 + } 16.1391 + 16.1392 + // Go through Decoder::decode to call getFuncName which reads the name from the traceback table. 16.1393 + return Decoder::decode(addr, buf, buflen, offset); 16.1394 +} 16.1395 + 16.1396 +static int getModuleName(codeptr_t pc, // [in] program counter 16.1397 + char* p_name, size_t namelen, // [out] optional: function name 16.1398 + char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages 16.1399 + ) { 16.1400 + 16.1401 + // initialize output parameters 16.1402 + if (p_name && namelen > 0) { 16.1403 + *p_name = '\0'; 16.1404 + } 16.1405 + if (p_errmsg && errmsglen > 0) { 16.1406 + *p_errmsg = '\0'; 16.1407 + } 16.1408 + 16.1409 + const LoadedLibraryModule* const lib = LoadedLibraries::find_for_text_address((address)pc); 16.1410 + if (lib) { 16.1411 + if (p_name && namelen > 0) { 16.1412 + sprintf(p_name, "%.*s", namelen, lib->get_shortname()); 16.1413 + } 16.1414 + return 0; 16.1415 + } 16.1416 + 16.1417 + if (Verbose) { 16.1418 + fprintf(stderr, "pc outside any module"); 16.1419 + } 16.1420 + 16.1421 + return -1; 16.1422 + 16.1423 +} 16.1424 + 16.1425 +bool os::dll_address_to_library_name(address addr, char* buf, 16.1426 + int buflen, int* offset) { 16.1427 + if (offset) { 16.1428 + *offset = -1; 16.1429 + } 16.1430 + if (buf) { 16.1431 + buf[0] = '\0'; 16.1432 + } 16.1433 + 16.1434 + // Resolve function ptr literals first. 16.1435 + addr = resolve_function_descriptor_to_code_pointer(addr); 16.1436 + if (!addr) { 16.1437 + return false; 16.1438 + } 16.1439 + 16.1440 + if (::getModuleName((codeptr_t) addr, buf, buflen, 0, 0) == 0) { 16.1441 + return true; 16.1442 + } 16.1443 + return false; 16.1444 +} 16.1445 + 16.1446 +// Loads .dll/.so and in case of error it checks if .dll/.so was built 16.1447 +// for the same architecture as Hotspot is running on 16.1448 +void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { 16.1449 + 16.1450 + if (ebuf && ebuflen > 0) { 16.1451 + ebuf[0] = '\0'; 16.1452 + ebuf[ebuflen - 1] = '\0'; 16.1453 + } 16.1454 + 16.1455 + if (!filename || strlen(filename) == 0) { 16.1456 + ::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1); 16.1457 + return NULL; 16.1458 + } 16.1459 + 16.1460 + // RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants. 16.1461 + void * result= ::dlopen(filename, RTLD_LAZY); 16.1462 + if (result != NULL) { 16.1463 + // Reload dll cache. Don't do this in signal handling. 16.1464 + LoadedLibraries::reload(); 16.1465 + return result; 16.1466 + } else { 16.1467 + // error analysis when dlopen fails 16.1468 + const char* const error_report = ::dlerror(); 16.1469 + if (error_report && ebuf && ebuflen > 0) { 16.1470 + snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s", 16.1471 + filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report); 16.1472 + } 16.1473 + } 16.1474 + return NULL; 16.1475 +} 16.1476 + 16.1477 +// Glibc-2.0 libdl is not MT safe. If you are building with any glibc, 16.1478 +// chances are you might want to run the generated bits against glibc-2.0 16.1479 +// libdl.so, so always use locking for any version of glibc. 16.1480 +void* os::dll_lookup(void* handle, const char* name) { 16.1481 + pthread_mutex_lock(&dl_mutex); 16.1482 + void* res = dlsym(handle, name); 16.1483 + pthread_mutex_unlock(&dl_mutex); 16.1484 + return res; 16.1485 +} 16.1486 + 16.1487 +void os::print_dll_info(outputStream *st) { 16.1488 + st->print_cr("Dynamic libraries:"); 16.1489 + LoadedLibraries::print(st); 16.1490 +} 16.1491 + 16.1492 +void os::print_os_info(outputStream* st) { 16.1493 + st->print("OS:"); 16.1494 + 16.1495 + st->print("uname:"); 16.1496 + struct utsname name; 16.1497 + uname(&name); 16.1498 + st->print(name.sysname); st->print(" "); 16.1499 + st->print(name.nodename); st->print(" "); 16.1500 + st->print(name.release); st->print(" "); 16.1501 + st->print(name.version); st->print(" "); 16.1502 + st->print(name.machine); 16.1503 + st->cr(); 16.1504 + 16.1505 + // rlimit 16.1506 + st->print("rlimit:"); 16.1507 + struct rlimit rlim; 16.1508 + 16.1509 + st->print(" STACK "); 16.1510 + getrlimit(RLIMIT_STACK, &rlim); 16.1511 + if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 16.1512 + else st->print("%uk", rlim.rlim_cur >> 10); 16.1513 + 16.1514 + st->print(", CORE "); 16.1515 + getrlimit(RLIMIT_CORE, &rlim); 16.1516 + if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 16.1517 + else st->print("%uk", rlim.rlim_cur >> 10); 16.1518 + 16.1519 + st->print(", NPROC "); 16.1520 + st->print("%d", sysconf(_SC_CHILD_MAX)); 16.1521 + 16.1522 + st->print(", NOFILE "); 16.1523 + getrlimit(RLIMIT_NOFILE, &rlim); 16.1524 + if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 16.1525 + else st->print("%d", rlim.rlim_cur); 16.1526 + 16.1527 + st->print(", AS "); 16.1528 + getrlimit(RLIMIT_AS, &rlim); 16.1529 + if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 16.1530 + else st->print("%uk", rlim.rlim_cur >> 10); 16.1531 + 16.1532 + // Print limits on DATA, because it limits the C-heap. 16.1533 + st->print(", DATA "); 16.1534 + getrlimit(RLIMIT_DATA, &rlim); 16.1535 + if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 16.1536 + else st->print("%uk", rlim.rlim_cur >> 10); 16.1537 + st->cr(); 16.1538 + 16.1539 + // load average 16.1540 + st->print("load average:"); 16.1541 + double loadavg[3] = {-1.L, -1.L, -1.L}; 16.1542 + os::loadavg(loadavg, 3); 16.1543 + st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); 16.1544 + st->cr(); 16.1545 +} 16.1546 + 16.1547 +void os::print_memory_info(outputStream* st) { 16.1548 + 16.1549 + st->print_cr("Memory:"); 16.1550 + 16.1551 + st->print_cr(" default page size: %s", describe_pagesize(os::vm_page_size())); 16.1552 + st->print_cr(" default stack page size: %s", describe_pagesize(os::vm_page_size())); 16.1553 + st->print_cr(" default shm page size: %s", describe_pagesize(os::Aix::shm_default_page_size())); 16.1554 + st->print_cr(" can use 64K pages dynamically: %s", (os::Aix::can_use_64K_pages() ? "yes" :"no")); 16.1555 + st->print_cr(" can use 16M pages dynamically: %s", (os::Aix::can_use_16M_pages() ? "yes" :"no")); 16.1556 + if (g_multipage_error != 0) { 16.1557 + st->print_cr(" multipage error: %d", g_multipage_error); 16.1558 + } 16.1559 + 16.1560 + // print out LDR_CNTRL because it affects the default page sizes 16.1561 + const char* const ldr_cntrl = ::getenv("LDR_CNTRL"); 16.1562 + st->print_cr(" LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>"); 16.1563 + 16.1564 + const char* const extshm = ::getenv("EXTSHM"); 16.1565 + st->print_cr(" EXTSHM=%s.", extshm ? extshm : "<unset>"); 16.1566 + 16.1567 + // Call os::Aix::get_meminfo() to retrieve memory statistics. 16.1568 + os::Aix::meminfo_t mi; 16.1569 + if (os::Aix::get_meminfo(&mi)) { 16.1570 + char buffer[256]; 16.1571 + if (os::Aix::on_aix()) { 16.1572 + jio_snprintf(buffer, sizeof(buffer), 16.1573 + " physical total : %llu\n" 16.1574 + " physical free : %llu\n" 16.1575 + " swap total : %llu\n" 16.1576 + " swap free : %llu\n", 16.1577 + mi.real_total, 16.1578 + mi.real_free, 16.1579 + mi.pgsp_total, 16.1580 + mi.pgsp_free); 16.1581 + } else { 16.1582 + Unimplemented(); 16.1583 + } 16.1584 + st->print_raw(buffer); 16.1585 + } else { 16.1586 + st->print_cr(" (no more information available)"); 16.1587 + } 16.1588 +} 16.1589 + 16.1590 +void os::pd_print_cpu_info(outputStream* st) { 16.1591 + // cpu 16.1592 + st->print("CPU:"); 16.1593 + st->print("total %d", os::processor_count()); 16.1594 + // It's not safe to query number of active processors after crash 16.1595 + // st->print("(active %d)", os::active_processor_count()); 16.1596 + st->print(" %s", VM_Version::cpu_features()); 16.1597 + st->cr(); 16.1598 +} 16.1599 + 16.1600 +void os::print_siginfo(outputStream* st, void* siginfo) { 16.1601 + // Use common posix version. 16.1602 + os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo); 16.1603 + st->cr(); 16.1604 +} 16.1605 + 16.1606 + 16.1607 +static void print_signal_handler(outputStream* st, int sig, 16.1608 + char* buf, size_t buflen); 16.1609 + 16.1610 +void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { 16.1611 + st->print_cr("Signal Handlers:"); 16.1612 + print_signal_handler(st, SIGSEGV, buf, buflen); 16.1613 + print_signal_handler(st, SIGBUS , buf, buflen); 16.1614 + print_signal_handler(st, SIGFPE , buf, buflen); 16.1615 + print_signal_handler(st, SIGPIPE, buf, buflen); 16.1616 + print_signal_handler(st, SIGXFSZ, buf, buflen); 16.1617 + print_signal_handler(st, SIGILL , buf, buflen); 16.1618 + print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen); 16.1619 + print_signal_handler(st, SR_signum, buf, buflen); 16.1620 + print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen); 16.1621 + print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); 16.1622 + print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen); 16.1623 + print_signal_handler(st, BREAK_SIGNAL, buf, buflen); 16.1624 + print_signal_handler(st, SIGTRAP, buf, buflen); 16.1625 + print_signal_handler(st, SIGDANGER, buf, buflen); 16.1626 +} 16.1627 + 16.1628 +static char saved_jvm_path[MAXPATHLEN] = {0}; 16.1629 + 16.1630 +// Find the full path to the current module, libjvm.so or libjvm_g.so 16.1631 +void os::jvm_path(char *buf, jint buflen) { 16.1632 + // Error checking. 16.1633 + if (buflen < MAXPATHLEN) { 16.1634 + assert(false, "must use a large-enough buffer"); 16.1635 + buf[0] = '\0'; 16.1636 + return; 16.1637 + } 16.1638 + // Lazy resolve the path to current module. 16.1639 + if (saved_jvm_path[0] != 0) { 16.1640 + strcpy(buf, saved_jvm_path); 16.1641 + return; 16.1642 + } 16.1643 + 16.1644 + Dl_info dlinfo; 16.1645 + int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); 16.1646 + assert(ret != 0, "cannot locate libjvm"); 16.1647 + char* rp = realpath((char *)dlinfo.dli_fname, buf); 16.1648 + assert(rp != NULL, "error in realpath(): maybe the 'path' argument is too long?"); 16.1649 + 16.1650 + strcpy(saved_jvm_path, buf); 16.1651 +} 16.1652 + 16.1653 +void os::print_jni_name_prefix_on(outputStream* st, int args_size) { 16.1654 + // no prefix required, not even "_" 16.1655 +} 16.1656 + 16.1657 +void os::print_jni_name_suffix_on(outputStream* st, int args_size) { 16.1658 + // no suffix required 16.1659 +} 16.1660 + 16.1661 +//////////////////////////////////////////////////////////////////////////////// 16.1662 +// sun.misc.Signal support 16.1663 + 16.1664 +static volatile jint sigint_count = 0; 16.1665 + 16.1666 +static void 16.1667 +UserHandler(int sig, void *siginfo, void *context) { 16.1668 + // 4511530 - sem_post is serialized and handled by the manager thread. When 16.1669 + // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We 16.1670 + // don't want to flood the manager thread with sem_post requests. 16.1671 + if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) 16.1672 + return; 16.1673 + 16.1674 + // Ctrl-C is pressed during error reporting, likely because the error 16.1675 + // handler fails to abort. Let VM die immediately. 16.1676 + if (sig == SIGINT && is_error_reported()) { 16.1677 + os::die(); 16.1678 + } 16.1679 + 16.1680 + os::signal_notify(sig); 16.1681 +} 16.1682 + 16.1683 +void* os::user_handler() { 16.1684 + return CAST_FROM_FN_PTR(void*, UserHandler); 16.1685 +} 16.1686 + 16.1687 +extern "C" { 16.1688 + typedef void (*sa_handler_t)(int); 16.1689 + typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 16.1690 +} 16.1691 + 16.1692 +void* os::signal(int signal_number, void* handler) { 16.1693 + struct sigaction sigAct, oldSigAct; 16.1694 + 16.1695 + sigfillset(&(sigAct.sa_mask)); 16.1696 + 16.1697 + // Do not block out synchronous signals in the signal handler. 16.1698 + // Blocking synchronous signals only makes sense if you can really 16.1699 + // be sure that those signals won't happen during signal handling, 16.1700 + // when the blocking applies. Normal signal handlers are lean and 16.1701 + // do not cause signals. But our signal handlers tend to be "risky" 16.1702 + // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. 16.1703 + // On AIX, PASE there was a case where a SIGSEGV happened, followed 16.1704 + // by a SIGILL, which was blocked due to the signal mask. The process 16.1705 + // just hung forever. Better to crash from a secondary signal than to hang. 16.1706 + sigdelset(&(sigAct.sa_mask), SIGSEGV); 16.1707 + sigdelset(&(sigAct.sa_mask), SIGBUS); 16.1708 + sigdelset(&(sigAct.sa_mask), SIGILL); 16.1709 + sigdelset(&(sigAct.sa_mask), SIGFPE); 16.1710 + sigdelset(&(sigAct.sa_mask), SIGTRAP); 16.1711 + 16.1712 + sigAct.sa_flags = SA_RESTART|SA_SIGINFO; 16.1713 + 16.1714 + sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 16.1715 + 16.1716 + if (sigaction(signal_number, &sigAct, &oldSigAct)) { 16.1717 + // -1 means registration failed 16.1718 + return (void *)-1; 16.1719 + } 16.1720 + 16.1721 + return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 16.1722 +} 16.1723 + 16.1724 +void os::signal_raise(int signal_number) { 16.1725 + ::raise(signal_number); 16.1726 +} 16.1727 + 16.1728 +// 16.1729 +// The following code is moved from os.cpp for making this 16.1730 +// code platform specific, which it is by its very nature. 16.1731 +// 16.1732 + 16.1733 +// Will be modified when max signal is changed to be dynamic 16.1734 +int os::sigexitnum_pd() { 16.1735 + return NSIG; 16.1736 +} 16.1737 + 16.1738 +// a counter for each possible signal value 16.1739 +static volatile jint pending_signals[NSIG+1] = { 0 }; 16.1740 + 16.1741 +// Linux(POSIX) specific hand shaking semaphore. 16.1742 +static sem_t sig_sem; 16.1743 + 16.1744 +void os::signal_init_pd() { 16.1745 + // Initialize signal structures 16.1746 + ::memset((void*)pending_signals, 0, sizeof(pending_signals)); 16.1747 + 16.1748 + // Initialize signal semaphore 16.1749 + int rc = ::sem_init(&sig_sem, 0, 0); 16.1750 + guarantee(rc != -1, "sem_init failed"); 16.1751 +} 16.1752 + 16.1753 +void os::signal_notify(int sig) { 16.1754 + Atomic::inc(&pending_signals[sig]); 16.1755 + ::sem_post(&sig_sem); 16.1756 +} 16.1757 + 16.1758 +static int check_pending_signals(bool wait) { 16.1759 + Atomic::store(0, &sigint_count); 16.1760 + for (;;) { 16.1761 + for (int i = 0; i < NSIG + 1; i++) { 16.1762 + jint n = pending_signals[i]; 16.1763 + if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { 16.1764 + return i; 16.1765 + } 16.1766 + } 16.1767 + if (!wait) { 16.1768 + return -1; 16.1769 + } 16.1770 + JavaThread *thread = JavaThread::current(); 16.1771 + ThreadBlockInVM tbivm(thread); 16.1772 + 16.1773 + bool threadIsSuspended; 16.1774 + do { 16.1775 + thread->set_suspend_equivalent(); 16.1776 + // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 16.1777 + 16.1778 + ::sem_wait(&sig_sem); 16.1779 + 16.1780 + // were we externally suspended while we were waiting? 16.1781 + threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); 16.1782 + if (threadIsSuspended) { 16.1783 + // 16.1784 + // The semaphore has been incremented, but while we were waiting 16.1785 + // another thread suspended us. We don't want to continue running 16.1786 + // while suspended because that would surprise the thread that 16.1787 + // suspended us. 16.1788 + // 16.1789 + ::sem_post(&sig_sem); 16.1790 + 16.1791 + thread->java_suspend_self(); 16.1792 + } 16.1793 + } while (threadIsSuspended); 16.1794 + } 16.1795 +} 16.1796 + 16.1797 +int os::signal_lookup() { 16.1798 + return check_pending_signals(false); 16.1799 +} 16.1800 + 16.1801 +int os::signal_wait() { 16.1802 + return check_pending_signals(true); 16.1803 +} 16.1804 + 16.1805 +//////////////////////////////////////////////////////////////////////////////// 16.1806 +// Virtual Memory 16.1807 + 16.1808 +// AddrRange describes an immutable address range 16.1809 +// 16.1810 +// This is a helper class for the 'shared memory bookkeeping' below. 16.1811 +class AddrRange { 16.1812 + friend class ShmBkBlock; 16.1813 + 16.1814 + char* _start; 16.1815 + size_t _size; 16.1816 + 16.1817 +public: 16.1818 + 16.1819 + AddrRange(char* start, size_t size) 16.1820 + : _start(start), _size(size) 16.1821 + {} 16.1822 + 16.1823 + AddrRange(const AddrRange& r) 16.1824 + : _start(r.start()), _size(r.size()) 16.1825 + {} 16.1826 + 16.1827 + char* start() const { return _start; } 16.1828 + size_t size() const { return _size; } 16.1829 + char* end() const { return _start + _size; } 16.1830 + bool is_empty() const { return _size == 0 ? true : false; } 16.1831 + 16.1832 + static AddrRange empty_range() { return AddrRange(NULL, 0); } 16.1833 + 16.1834 + bool contains(const char* p) const { 16.1835 + return start() <= p && end() > p; 16.1836 + } 16.1837 + 16.1838 + bool contains(const AddrRange& range) const { 16.1839 + return start() <= range.start() && end() >= range.end(); 16.1840 + } 16.1841 + 16.1842 + bool intersects(const AddrRange& range) const { 16.1843 + return (range.start() <= start() && range.end() > start()) || 16.1844 + (range.start() < end() && range.end() >= end()) || 16.1845 + contains(range); 16.1846 + } 16.1847 + 16.1848 + bool is_same_range(const AddrRange& range) const { 16.1849 + return start() == range.start() && size() == range.size(); 16.1850 + } 16.1851 + 16.1852 + // return the closest inside range consisting of whole pages 16.1853 + AddrRange find_closest_aligned_range(size_t pagesize) const { 16.1854 + if (pagesize == 0 || is_empty()) { 16.1855 + return empty_range(); 16.1856 + } 16.1857 + char* const from = (char*)align_size_up((intptr_t)_start, pagesize); 16.1858 + char* const to = (char*)align_size_down((intptr_t)end(), pagesize); 16.1859 + if (from > to) { 16.1860 + return empty_range(); 16.1861 + } 16.1862 + return AddrRange(from, to - from); 16.1863 + } 16.1864 +}; 16.1865 + 16.1866 +//////////////////////////////////////////////////////////////////////////// 16.1867 +// shared memory bookkeeping 16.1868 +// 16.1869 +// the os::reserve_memory() API and friends hand out different kind of memory, depending 16.1870 +// on need and circumstances. Memory may be allocated with mmap() or with shmget/shmat. 16.1871 +// 16.1872 +// But these memory types have to be treated differently. For example, to uncommit 16.1873 +// mmap-based memory, msync(MS_INVALIDATE) is needed, to uncommit shmat-based memory, 16.1874 +// disclaim64() is needed. 16.1875 +// 16.1876 +// Therefore we need to keep track of the allocated memory segments and their 16.1877 +// properties. 16.1878 + 16.1879 +// ShmBkBlock: base class for all blocks in the shared memory bookkeeping 16.1880 +class ShmBkBlock { 16.1881 + 16.1882 + ShmBkBlock* _next; 16.1883 + 16.1884 +protected: 16.1885 + 16.1886 + AddrRange _range; 16.1887 + const size_t _pagesize; 16.1888 + const bool _pinned; 16.1889 + 16.1890 +public: 16.1891 + 16.1892 + ShmBkBlock(AddrRange range, size_t pagesize, bool pinned) 16.1893 + : _range(range), _pagesize(pagesize), _pinned(pinned) , _next(NULL) { 16.1894 + 16.1895 + assert(_pagesize == SIZE_4K || _pagesize == SIZE_64K || _pagesize == SIZE_16M, "invalid page size"); 16.1896 + assert(!_range.is_empty(), "invalid range"); 16.1897 + } 16.1898 + 16.1899 + virtual void print(outputStream* st) const { 16.1900 + st->print("0x%p ... 0x%p (%llu) - %d %s pages - %s", 16.1901 + _range.start(), _range.end(), _range.size(), 16.1902 + _range.size() / _pagesize, describe_pagesize(_pagesize), 16.1903 + _pinned ? "pinned" : ""); 16.1904 + } 16.1905 + 16.1906 + enum Type { MMAP, SHMAT }; 16.1907 + virtual Type getType() = 0; 16.1908 + 16.1909 + char* base() const { return _range.start(); } 16.1910 + size_t size() const { return _range.size(); } 16.1911 + 16.1912 + void setAddrRange(AddrRange range) { 16.1913 + _range = range; 16.1914 + } 16.1915 + 16.1916 + bool containsAddress(const char* p) const { 16.1917 + return _range.contains(p); 16.1918 + } 16.1919 + 16.1920 + bool containsRange(const char* p, size_t size) const { 16.1921 + return _range.contains(AddrRange((char*)p, size)); 16.1922 + } 16.1923 + 16.1924 + bool isSameRange(const char* p, size_t size) const { 16.1925 + return _range.is_same_range(AddrRange((char*)p, size)); 16.1926 + } 16.1927 + 16.1928 + virtual bool disclaim(char* p, size_t size) = 0; 16.1929 + virtual bool release() = 0; 16.1930 + 16.1931 + // blocks live in a list. 16.1932 + ShmBkBlock* next() const { return _next; } 16.1933 + void set_next(ShmBkBlock* blk) { _next = blk; } 16.1934 + 16.1935 +}; // end: ShmBkBlock 16.1936 + 16.1937 + 16.1938 +// ShmBkMappedBlock: describes an block allocated with mmap() 16.1939 +class ShmBkMappedBlock : public ShmBkBlock { 16.1940 +public: 16.1941 + 16.1942 + ShmBkMappedBlock(AddrRange range) 16.1943 + : ShmBkBlock(range, SIZE_4K, false) {} // mmap: always 4K, never pinned 16.1944 + 16.1945 + void print(outputStream* st) const { 16.1946 + ShmBkBlock::print(st); 16.1947 + st->print_cr(" - mmap'ed"); 16.1948 + } 16.1949 + 16.1950 + Type getType() { 16.1951 + return MMAP; 16.1952 + } 16.1953 + 16.1954 + bool disclaim(char* p, size_t size) { 16.1955 + 16.1956 + AddrRange r(p, size); 16.1957 + 16.1958 + guarantee(_range.contains(r), "invalid disclaim"); 16.1959 + 16.1960 + // only disclaim whole ranges. 16.1961 + const AddrRange r2 = r.find_closest_aligned_range(_pagesize); 16.1962 + if (r2.is_empty()) { 16.1963 + return true; 16.1964 + } 16.1965 + 16.1966 + const int rc = ::msync(r2.start(), r2.size(), MS_INVALIDATE); 16.1967 + 16.1968 + if (rc != 0) { 16.1969 + warning("msync(0x%p, %llu, MS_INVALIDATE) failed (%d)\n", r2.start(), r2.size(), errno); 16.1970 + } 16.1971 + 16.1972 + return rc == 0 ? true : false; 16.1973 + } 16.1974 + 16.1975 + bool release() { 16.1976 + // mmap'ed blocks are released using munmap 16.1977 + if (::munmap(_range.start(), _range.size()) != 0) { 16.1978 + warning("munmap(0x%p, %llu) failed (%d)\n", _range.start(), _range.size(), errno); 16.1979 + return false; 16.1980 + } 16.1981 + return true; 16.1982 + } 16.1983 +}; // end: ShmBkMappedBlock 16.1984 + 16.1985 +// ShmBkShmatedBlock: describes an block allocated with shmget/shmat() 16.1986 +class ShmBkShmatedBlock : public ShmBkBlock { 16.1987 +public: 16.1988 + 16.1989 + ShmBkShmatedBlock(AddrRange range, size_t pagesize, bool pinned) 16.1990 + : ShmBkBlock(range, pagesize, pinned) {} 16.1991 + 16.1992 + void print(outputStream* st) const { 16.1993 + ShmBkBlock::print(st); 16.1994 + st->print_cr(" - shmat'ed"); 16.1995 + } 16.1996 + 16.1997 + Type getType() { 16.1998 + return SHMAT; 16.1999 + } 16.2000 + 16.2001 + bool disclaim(char* p, size_t size) { 16.2002 + 16.2003 + AddrRange r(p, size); 16.2004 + 16.2005 + if (_pinned) { 16.2006 + return true; 16.2007 + } 16.2008 + 16.2009 + // shmat'ed blocks are disclaimed using disclaim64 16.2010 + guarantee(_range.contains(r), "invalid disclaim"); 16.2011 + 16.2012 + // only disclaim whole ranges. 16.2013 + const AddrRange r2 = r.find_closest_aligned_range(_pagesize); 16.2014 + if (r2.is_empty()) { 16.2015 + return true; 16.2016 + } 16.2017 + 16.2018 + const bool rc = my_disclaim64(r2.start(), r2.size()); 16.2019 + 16.2020 + if (Verbose && !rc) { 16.2021 + warning("failed to disclaim shm %p-%p\n", r2.start(), r2.end()); 16.2022 + } 16.2023 + 16.2024 + return rc; 16.2025 + } 16.2026 + 16.2027 + bool release() { 16.2028 + bool rc = false; 16.2029 + if (::shmdt(_range.start()) != 0) { 16.2030 + warning("shmdt(0x%p) failed (%d)\n", _range.start(), errno); 16.2031 + } else { 16.2032 + rc = true; 16.2033 + } 16.2034 + return rc; 16.2035 + } 16.2036 + 16.2037 +}; // end: ShmBkShmatedBlock 16.2038 + 16.2039 +static ShmBkBlock* g_shmbk_list = NULL; 16.2040 +static volatile jint g_shmbk_table_lock = 0; 16.2041 + 16.2042 +// keep some usage statistics 16.2043 +static struct { 16.2044 + int nodes; // number of nodes in list 16.2045 + size_t bytes; // reserved - not committed - bytes. 16.2046 + int reserves; // how often reserve was called 16.2047 + int lookups; // how often a lookup was made 16.2048 +} g_shmbk_stats = { 0, 0, 0, 0 }; 16.2049 + 16.2050 +// add information about a shared memory segment to the bookkeeping 16.2051 +static void shmbk_register(ShmBkBlock* p_block) { 16.2052 + guarantee(p_block, "logic error"); 16.2053 + p_block->set_next(g_shmbk_list); 16.2054 + g_shmbk_list = p_block; 16.2055 + g_shmbk_stats.reserves ++; 16.2056 + g_shmbk_stats.bytes += p_block->size(); 16.2057 + g_shmbk_stats.nodes ++; 16.2058 +} 16.2059 + 16.2060 +// remove information about a shared memory segment by its starting address 16.2061 +static void shmbk_unregister(ShmBkBlock* p_block) { 16.2062 + ShmBkBlock* p = g_shmbk_list; 16.2063 + ShmBkBlock* prev = NULL; 16.2064 + while (p) { 16.2065 + if (p == p_block) { 16.2066 + if (prev) { 16.2067 + prev->set_next(p->next()); 16.2068 + } else { 16.2069 + g_shmbk_list = p->next(); 16.2070 + } 16.2071 + g_shmbk_stats.nodes --; 16.2072 + g_shmbk_stats.bytes -= p->size(); 16.2073 + return; 16.2074 + } 16.2075 + prev = p; 16.2076 + p = p->next(); 16.2077 + } 16.2078 + assert(false, "should not happen"); 16.2079 +} 16.2080 + 16.2081 +// given a pointer, return shared memory bookkeeping record for the segment it points into 16.2082 +// using the returned block info must happen under lock protection 16.2083 +static ShmBkBlock* shmbk_find_by_containing_address(const char* addr) { 16.2084 + g_shmbk_stats.lookups ++; 16.2085 + ShmBkBlock* p = g_shmbk_list; 16.2086 + while (p) { 16.2087 + if (p->containsAddress(addr)) { 16.2088 + return p; 16.2089 + } 16.2090 + p = p->next(); 16.2091 + } 16.2092 + return NULL; 16.2093 +} 16.2094 + 16.2095 +// dump all information about all memory segments allocated with os::reserve_memory() 16.2096 +void shmbk_dump_info() { 16.2097 + tty->print_cr("-- shared mem bookkeeping (alive: %d segments, %llu bytes, " 16.2098 + "total reserves: %d total lookups: %d)", 16.2099 + g_shmbk_stats.nodes, g_shmbk_stats.bytes, g_shmbk_stats.reserves, g_shmbk_stats.lookups); 16.2100 + const ShmBkBlock* p = g_shmbk_list; 16.2101 + int i = 0; 16.2102 + while (p) { 16.2103 + p->print(tty); 16.2104 + p = p->next(); 16.2105 + i ++; 16.2106 + } 16.2107 +} 16.2108 + 16.2109 +#define LOCK_SHMBK { ThreadCritical _LOCK_SHMBK; 16.2110 +#define UNLOCK_SHMBK } 16.2111 + 16.2112 +// End: shared memory bookkeeping 16.2113 +//////////////////////////////////////////////////////////////////////////////////////////////////// 16.2114 + 16.2115 +int os::vm_page_size() { 16.2116 + // Seems redundant as all get out 16.2117 + assert(os::Aix::page_size() != -1, "must call os::init"); 16.2118 + return os::Aix::page_size(); 16.2119 +} 16.2120 + 16.2121 +// Aix allocates memory by pages. 16.2122 +int os::vm_allocation_granularity() { 16.2123 + assert(os::Aix::page_size() != -1, "must call os::init"); 16.2124 + return os::Aix::page_size(); 16.2125 +} 16.2126 + 16.2127 +int os::Aix::commit_memory_impl(char* addr, size_t size, bool exec) { 16.2128 + 16.2129 + // Commit is a noop. There is no explicit commit 16.2130 + // needed on AIX. Memory is committed when touched. 16.2131 + // 16.2132 + // Debug : check address range for validity 16.2133 +#ifdef ASSERT 16.2134 + LOCK_SHMBK 16.2135 + ShmBkBlock* const block = shmbk_find_by_containing_address(addr); 16.2136 + if (!block) { 16.2137 + fprintf(stderr, "invalid pointer: " INTPTR_FORMAT "\n", addr); 16.2138 + shmbk_dump_info(); 16.2139 + assert(false, "invalid pointer"); 16.2140 + return false; 16.2141 + } else if (!block->containsRange(addr, size)) { 16.2142 + fprintf(stderr, "invalid range: " INTPTR_FORMAT " .. " INTPTR_FORMAT "\n", addr, addr + size); 16.2143 + shmbk_dump_info(); 16.2144 + assert(false, "invalid range"); 16.2145 + return false; 16.2146 + } 16.2147 + UNLOCK_SHMBK 16.2148 +#endif // ASSERT 16.2149 + 16.2150 + return 0; 16.2151 +} 16.2152 + 16.2153 +bool os::pd_commit_memory(char* addr, size_t size, bool exec) { 16.2154 + return os::Aix::commit_memory_impl(addr, size, exec) == 0; 16.2155 +} 16.2156 + 16.2157 +void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, 16.2158 + const char* mesg) { 16.2159 + assert(mesg != NULL, "mesg must be specified"); 16.2160 + os::Aix::commit_memory_impl(addr, size, exec); 16.2161 +} 16.2162 + 16.2163 +int os::Aix::commit_memory_impl(char* addr, size_t size, 16.2164 + size_t alignment_hint, bool exec) { 16.2165 + return os::Aix::commit_memory_impl(addr, size, exec); 16.2166 +} 16.2167 + 16.2168 +bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, 16.2169 + bool exec) { 16.2170 + return os::Aix::commit_memory_impl(addr, size, alignment_hint, exec) == 0; 16.2171 +} 16.2172 + 16.2173 +void os::pd_commit_memory_or_exit(char* addr, size_t size, 16.2174 + size_t alignment_hint, bool exec, 16.2175 + const char* mesg) { 16.2176 + os::Aix::commit_memory_impl(addr, size, alignment_hint, exec); 16.2177 +} 16.2178 + 16.2179 +bool os::pd_uncommit_memory(char* addr, size_t size) { 16.2180 + 16.2181 + // Delegate to ShmBkBlock class which knows how to uncommit its memory. 16.2182 + 16.2183 + bool rc = false; 16.2184 + LOCK_SHMBK 16.2185 + ShmBkBlock* const block = shmbk_find_by_containing_address(addr); 16.2186 + if (!block) { 16.2187 + fprintf(stderr, "invalid pointer: 0x%p.\n", addr); 16.2188 + shmbk_dump_info(); 16.2189 + assert(false, "invalid pointer"); 16.2190 + return false; 16.2191 + } else if (!block->containsRange(addr, size)) { 16.2192 + fprintf(stderr, "invalid range: 0x%p .. 0x%p.\n", addr, addr + size); 16.2193 + shmbk_dump_info(); 16.2194 + assert(false, "invalid range"); 16.2195 + return false; 16.2196 + } 16.2197 + rc = block->disclaim(addr, size); 16.2198 + UNLOCK_SHMBK 16.2199 + 16.2200 + if (Verbose && !rc) { 16.2201 + warning("failed to disclaim 0x%p .. 0x%p (0x%llX bytes).", addr, addr + size, size); 16.2202 + } 16.2203 + return rc; 16.2204 +} 16.2205 + 16.2206 +bool os::pd_create_stack_guard_pages(char* addr, size_t size) { 16.2207 + return os::guard_memory(addr, size); 16.2208 +} 16.2209 + 16.2210 +bool os::remove_stack_guard_pages(char* addr, size_t size) { 16.2211 + return os::unguard_memory(addr, size); 16.2212 +} 16.2213 + 16.2214 +void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 16.2215 +} 16.2216 + 16.2217 +void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { 16.2218 +} 16.2219 + 16.2220 +void os::numa_make_global(char *addr, size_t bytes) { 16.2221 +} 16.2222 + 16.2223 +void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { 16.2224 +} 16.2225 + 16.2226 +bool os::numa_topology_changed() { 16.2227 + return false; 16.2228 +} 16.2229 + 16.2230 +size_t os::numa_get_groups_num() { 16.2231 + return 1; 16.2232 +} 16.2233 + 16.2234 +int os::numa_get_group_id() { 16.2235 + return 0; 16.2236 +} 16.2237 + 16.2238 +size_t os::numa_get_leaf_groups(int *ids, size_t size) { 16.2239 + if (size > 0) { 16.2240 + ids[0] = 0; 16.2241 + return 1; 16.2242 + } 16.2243 + return 0; 16.2244 +} 16.2245 + 16.2246 +bool os::get_page_info(char *start, page_info* info) { 16.2247 + return false; 16.2248 +} 16.2249 + 16.2250 +char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { 16.2251 + return end; 16.2252 +} 16.2253 + 16.2254 +// Flags for reserve_shmatted_memory: 16.2255 +#define RESSHM_WISHADDR_OR_FAIL 1 16.2256 +#define RESSHM_TRY_16M_PAGES 2 16.2257 +#define RESSHM_16M_PAGES_OR_FAIL 4 16.2258 + 16.2259 +// Result of reserve_shmatted_memory: 16.2260 +struct shmatted_memory_info_t { 16.2261 + char* addr; 16.2262 + size_t pagesize; 16.2263 + bool pinned; 16.2264 +}; 16.2265 + 16.2266 +// Reserve a section of shmatted memory. 16.2267 +// params: 16.2268 +// bytes [in]: size of memory, in bytes 16.2269 +// requested_addr [in]: wish address. 16.2270 +// NULL = no wish. 16.2271 +// If RESSHM_WISHADDR_OR_FAIL is set in flags and wish address cannot 16.2272 +// be obtained, function will fail. Otherwise wish address is treated as hint and 16.2273 +// another pointer is returned. 16.2274 +// flags [in]: some flags. Valid flags are: 16.2275 +// RESSHM_WISHADDR_OR_FAIL - fail if wish address is given and cannot be obtained. 16.2276 +// RESSHM_TRY_16M_PAGES - try to allocate from 16M page pool 16.2277 +// (requires UseLargePages and Use16MPages) 16.2278 +// RESSHM_16M_PAGES_OR_FAIL - if you cannot allocate from 16M page pool, fail. 16.2279 +// Otherwise any other page size will do. 16.2280 +// p_info [out] : holds information about the created shared memory segment. 16.2281 +static bool reserve_shmatted_memory(size_t bytes, char* requested_addr, int flags, shmatted_memory_info_t* p_info) { 16.2282 + 16.2283 + assert(p_info, "parameter error"); 16.2284 + 16.2285 + // init output struct. 16.2286 + p_info->addr = NULL; 16.2287 + 16.2288 + // neither should we be here for EXTSHM=ON. 16.2289 + if (os::Aix::extshm()) { 16.2290 + ShouldNotReachHere(); 16.2291 + } 16.2292 + 16.2293 + // extract flags. sanity checks. 16.2294 + const bool wishaddr_or_fail = 16.2295 + flags & RESSHM_WISHADDR_OR_FAIL; 16.2296 + const bool try_16M_pages = 16.2297 + flags & RESSHM_TRY_16M_PAGES; 16.2298 + const bool f16M_pages_or_fail = 16.2299 + flags & RESSHM_16M_PAGES_OR_FAIL; 16.2300 + 16.2301 + // first check: if a wish address is given and it is mandatory, but not aligned to segment boundary, 16.2302 + // shmat will fail anyway, so save some cycles by failing right away 16.2303 + if (requested_addr && ((uintptr_t)requested_addr % SIZE_256M == 0)) { 16.2304 + if (wishaddr_or_fail) { 16.2305 + return false; 16.2306 + } else { 16.2307 + requested_addr = NULL; 16.2308 + } 16.2309 + } 16.2310 + 16.2311 + char* addr = NULL; 16.2312 + 16.2313 + // Align size of shm up to the largest possible page size, to avoid errors later on when we try to change 16.2314 + // pagesize dynamically. 16.2315 + const size_t size = align_size_up(bytes, SIZE_16M); 16.2316 + 16.2317 + // reserve the shared segment 16.2318 + int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR); 16.2319 + if (shmid == -1) { 16.2320 + warning("shmget(.., %lld, ..) failed (errno: %d).", size, errno); 16.2321 + return false; 16.2322 + } 16.2323 + 16.2324 + // Important note: 16.2325 + // It is very important that we, upon leaving this function, do not leave a shm segment alive. 16.2326 + // We must right after attaching it remove it from the system. System V shm segments are global and 16.2327 + // survive the process. 16.2328 + // So, from here on: Do not assert. Do not return. Always do a "goto cleanup_shm". 16.2329 + 16.2330 + // try forcing the page size 16.2331 + size_t pagesize = -1; // unknown so far 16.2332 + 16.2333 + if (UseLargePages) { 16.2334 + 16.2335 + struct shmid_ds shmbuf; 16.2336 + memset(&shmbuf, 0, sizeof(shmbuf)); 16.2337 + 16.2338 + // First, try to take from 16M page pool if... 16.2339 + if (os::Aix::can_use_16M_pages() // we can ... 16.2340 + && Use16MPages // we are not explicitly forbidden to do so (-XX:-Use16MPages).. 16.2341 + && try_16M_pages) { // caller wants us to. 16.2342 + shmbuf.shm_pagesize = SIZE_16M; 16.2343 + if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) == 0) { 16.2344 + pagesize = SIZE_16M; 16.2345 + } else { 16.2346 + warning("Failed to allocate %d 16M pages. 16M page pool might be exhausted. (shmctl failed with %d)", 16.2347 + size / SIZE_16M, errno); 16.2348 + if (f16M_pages_or_fail) { 16.2349 + goto cleanup_shm; 16.2350 + } 16.2351 + } 16.2352 + } 16.2353 + 16.2354 + // Nothing yet? Try setting 64K pages. Note that I never saw this fail, but in theory it might, 16.2355 + // because the 64K page pool may also be exhausted. 16.2356 + if (pagesize == -1) { 16.2357 + shmbuf.shm_pagesize = SIZE_64K; 16.2358 + if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) == 0) { 16.2359 + pagesize = SIZE_64K; 16.2360 + } else { 16.2361 + warning("Failed to allocate %d 64K pages. (shmctl failed with %d)", 16.2362 + size / SIZE_64K, errno); 16.2363 + // here I give up. leave page_size -1 - later, after attaching, we will query the 16.2364 + // real page size of the attached memory. (in theory, it may be something different 16.2365 + // from 4K if LDR_CNTRL SHM_PSIZE is set) 16.2366 + } 16.2367 + } 16.2368 + } 16.2369 + 16.2370 + // sanity point 16.2371 + assert(pagesize == -1 || pagesize == SIZE_16M || pagesize == SIZE_64K, "wrong page size"); 16.2372 + 16.2373 + // Now attach the shared segment. 16.2374 + addr = (char*) shmat(shmid, requested_addr, 0); 16.2375 + if (addr == (char*)-1) { 16.2376 + // How to handle attach failure: 16.2377 + // If it failed for a specific wish address, tolerate this: in that case, if wish address was 16.2378 + // mandatory, fail, if not, retry anywhere. 16.2379 + // If it failed for any other reason, treat that as fatal error. 16.2380 + addr = NULL; 16.2381 + if (requested_addr) { 16.2382 + if (wishaddr_or_fail) { 16.2383 + goto cleanup_shm; 16.2384 + } else { 16.2385 + addr = (char*) shmat(shmid, NULL, 0); 16.2386 + if (addr == (char*)-1) { // fatal 16.2387 + addr = NULL; 16.2388 + warning("shmat failed (errno: %d)", errno); 16.2389 + goto cleanup_shm; 16.2390 + } 16.2391 + } 16.2392 + } else { // fatal 16.2393 + addr = NULL; 16.2394 + warning("shmat failed (errno: %d)", errno); 16.2395 + goto cleanup_shm; 16.2396 + } 16.2397 + } 16.2398 + 16.2399 + // sanity point 16.2400 + assert(addr && addr != (char*) -1, "wrong address"); 16.2401 + 16.2402 + // after successful Attach remove the segment - right away. 16.2403 + if (::shmctl(shmid, IPC_RMID, NULL) == -1) { 16.2404 + warning("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno); 16.2405 + guarantee(false, "failed to remove shared memory segment!"); 16.2406 + } 16.2407 + shmid = -1; 16.2408 + 16.2409 + // query the real page size. In case setting the page size did not work (see above), the system 16.2410 + // may have given us something other then 4K (LDR_CNTRL) 16.2411 + { 16.2412 + const size_t real_pagesize = os::Aix::query_pagesize(addr); 16.2413 + if (pagesize != -1) { 16.2414 + assert(pagesize == real_pagesize, "unexpected pagesize after shmat"); 16.2415 + } else { 16.2416 + pagesize = real_pagesize; 16.2417 + } 16.2418 + } 16.2419 + 16.2420 + // Now register the reserved block with internal book keeping. 16.2421 + LOCK_SHMBK 16.2422 + const bool pinned = pagesize >= SIZE_16M ? true : false; 16.2423 + ShmBkShmatedBlock* const p_block = new ShmBkShmatedBlock(AddrRange(addr, size), pagesize, pinned); 16.2424 + assert(p_block, ""); 16.2425 + shmbk_register(p_block); 16.2426 + UNLOCK_SHMBK 16.2427 + 16.2428 +cleanup_shm: 16.2429 + 16.2430 + // if we have not done so yet, remove the shared memory segment. This is very important. 16.2431 + if (shmid != -1) { 16.2432 + if (::shmctl(shmid, IPC_RMID, NULL) == -1) { 16.2433 + warning("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno); 16.2434 + guarantee(false, "failed to remove shared memory segment!"); 16.2435 + } 16.2436 + shmid = -1; 16.2437 + } 16.2438 + 16.2439 + // trace 16.2440 + if (Verbose && !addr) { 16.2441 + if (requested_addr != NULL) { 16.2442 + warning("failed to shm-allocate 0x%llX bytes at with address 0x%p.", size, requested_addr); 16.2443 + } else { 16.2444 + warning("failed to shm-allocate 0x%llX bytes at any address.", size); 16.2445 + } 16.2446 + } 16.2447 + 16.2448 + // hand info to caller 16.2449 + if (addr) { 16.2450 + p_info->addr = addr; 16.2451 + p_info->pagesize = pagesize; 16.2452 + p_info->pinned = pagesize == SIZE_16M ? true : false; 16.2453 + } 16.2454 + 16.2455 + // sanity test: 16.2456 + if (requested_addr && addr && wishaddr_or_fail) { 16.2457 + guarantee(addr == requested_addr, "shmat error"); 16.2458 + } 16.2459 + 16.2460 + // just one more test to really make sure we have no dangling shm segments. 16.2461 + guarantee(shmid == -1, "dangling shm segments"); 16.2462 + 16.2463 + return addr ? true : false; 16.2464 + 16.2465 +} // end: reserve_shmatted_memory 16.2466 + 16.2467 +// Reserve memory using mmap. Behaves the same as reserve_shmatted_memory(): 16.2468 +// will return NULL in case of an error. 16.2469 +static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) { 16.2470 + 16.2471 + // if a wish address is given, but not aligned to 4K page boundary, mmap will fail. 16.2472 + if (requested_addr && ((uintptr_t)requested_addr % os::vm_page_size() != 0)) { 16.2473 + warning("Wish address 0x%p not aligned to page boundary.", requested_addr); 16.2474 + return NULL; 16.2475 + } 16.2476 + 16.2477 + const size_t size = align_size_up(bytes, SIZE_4K); 16.2478 + 16.2479 + // Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to 16.2480 + // msync(MS_INVALIDATE) (see os::uncommit_memory) 16.2481 + int flags = MAP_ANONYMOUS | MAP_SHARED; 16.2482 + 16.2483 + // MAP_FIXED is needed to enforce requested_addr - manpage is vague about what 16.2484 + // it means if wishaddress is given but MAP_FIXED is not set. 16.2485 + // 16.2486 + // Note however that this changes semantics in SPEC1170 mode insofar as MAP_FIXED 16.2487 + // clobbers the address range, which is probably not what the caller wants. That's 16.2488 + // why I assert here (again) that the SPEC1170 compat mode is off. 16.2489 + // If we want to be able to run under SPEC1170, we have to do some porting and 16.2490 + // testing. 16.2491 + if (requested_addr != NULL) { 16.2492 + assert(!os::Aix::xpg_sus_mode(), "SPEC1170 mode not allowed."); 16.2493 + flags |= MAP_FIXED; 16.2494 + } 16.2495 + 16.2496 + char* addr = (char*)::mmap(requested_addr, size, PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0); 16.2497 + 16.2498 + if (addr == MAP_FAILED) { 16.2499 + // attach failed: tolerate for specific wish addresses. Not being able to attach 16.2500 + // anywhere is a fatal error. 16.2501 + if (requested_addr == NULL) { 16.2502 + // It's ok to fail here if the machine has not enough memory. 16.2503 + warning("mmap(NULL, 0x%llX, ..) failed (%d)", size, errno); 16.2504 + } 16.2505 + addr = NULL; 16.2506 + goto cleanup_mmap; 16.2507 + } 16.2508 + 16.2509 + // If we did request a specific address and that address was not available, fail. 16.2510 + if (addr && requested_addr) { 16.2511 + guarantee(addr == requested_addr, "unexpected"); 16.2512 + } 16.2513 + 16.2514 + // register this mmap'ed segment with book keeping 16.2515 + LOCK_SHMBK 16.2516 + ShmBkMappedBlock* const p_block = new ShmBkMappedBlock(AddrRange(addr, size)); 16.2517 + assert(p_block, ""); 16.2518 + shmbk_register(p_block); 16.2519 + UNLOCK_SHMBK 16.2520 + 16.2521 +cleanup_mmap: 16.2522 + 16.2523 + if (addr) { 16.2524 + if (Verbose) { 16.2525 + fprintf(stderr, "mmap-allocated 0x%p .. 0x%p (0x%llX bytes)\n", addr, addr + bytes, bytes); 16.2526 + } 16.2527 + } 16.2528 + else { 16.2529 + if (requested_addr != NULL) { 16.2530 + warning("failed to mmap-allocate 0x%llX bytes at wish address 0x%p.", bytes, requested_addr); 16.2531 + } else { 16.2532 + warning("failed to mmap-allocate 0x%llX bytes at any address.", bytes); 16.2533 + } 16.2534 + } 16.2535 + 16.2536 + return addr; 16.2537 + 16.2538 +} // end: reserve_mmaped_memory 16.2539 + 16.2540 +// Reserves and attaches a shared memory segment. 16.2541 +// Will assert if a wish address is given and could not be obtained. 16.2542 +char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { 16.2543 + return os::attempt_reserve_memory_at(bytes, requested_addr); 16.2544 +} 16.2545 + 16.2546 +bool os::pd_release_memory(char* addr, size_t size) { 16.2547 + 16.2548 + // delegate to ShmBkBlock class which knows how to uncommit its memory. 16.2549 + 16.2550 + bool rc = false; 16.2551 + LOCK_SHMBK 16.2552 + ShmBkBlock* const block = shmbk_find_by_containing_address(addr); 16.2553 + if (!block) { 16.2554 + fprintf(stderr, "invalid pointer: 0x%p.\n", addr); 16.2555 + shmbk_dump_info(); 16.2556 + assert(false, "invalid pointer"); 16.2557 + return false; 16.2558 + } 16.2559 + else if (!block->isSameRange(addr, size)) { 16.2560 + if (block->getType() == ShmBkBlock::MMAP) { 16.2561 + // Release only the same range or a the beginning or the end of a range. 16.2562 + if (block->base() == addr && size < block->size()) { 16.2563 + ShmBkMappedBlock* const b = new ShmBkMappedBlock(AddrRange(block->base() + size, block->size() - size)); 16.2564 + assert(b, ""); 16.2565 + shmbk_register(b); 16.2566 + block->setAddrRange(AddrRange(addr, size)); 16.2567 + } 16.2568 + else if (addr > block->base() && addr + size == block->base() + block->size()) { 16.2569 + ShmBkMappedBlock* const b = new ShmBkMappedBlock(AddrRange(block->base(), block->size() - size)); 16.2570 + assert(b, ""); 16.2571 + shmbk_register(b); 16.2572 + block->setAddrRange(AddrRange(addr, size)); 16.2573 + } 16.2574 + else { 16.2575 + fprintf(stderr, "invalid mmap range: 0x%p .. 0x%p.\n", addr, addr + size); 16.2576 + shmbk_dump_info(); 16.2577 + assert(false, "invalid mmap range"); 16.2578 + return false; 16.2579 + } 16.2580 + } 16.2581 + else { 16.2582 + // Release only the same range. No partial release allowed. 16.2583 + // Soften the requirement a bit, because the user may think he owns a smaller size 16.2584 + // than the block is due to alignment etc. 16.2585 + if (block->base() != addr || block->size() < size) { 16.2586 + fprintf(stderr, "invalid shmget range: 0x%p .. 0x%p.\n", addr, addr + size); 16.2587 + shmbk_dump_info(); 16.2588 + assert(false, "invalid shmget range"); 16.2589 + return false; 16.2590 + } 16.2591 + } 16.2592 + } 16.2593 + rc = block->release(); 16.2594 + assert(rc, "release failed"); 16.2595 + // remove block from bookkeeping 16.2596 + shmbk_unregister(block); 16.2597 + delete block; 16.2598 + UNLOCK_SHMBK 16.2599 + 16.2600 + if (!rc) { 16.2601 + warning("failed to released %lu bytes at 0x%p", size, addr); 16.2602 + } 16.2603 + 16.2604 + return rc; 16.2605 +} 16.2606 + 16.2607 +static bool checked_mprotect(char* addr, size_t size, int prot) { 16.2608 + 16.2609 + // Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will 16.2610 + // not tell me if protection failed when trying to protect an un-protectable range. 16.2611 + // 16.2612 + // This means if the memory was allocated using shmget/shmat, protection wont work 16.2613 + // but mprotect will still return 0: 16.2614 + // 16.2615 + // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm 16.2616 + 16.2617 + bool rc = ::mprotect(addr, size, prot) == 0 ? true : false; 16.2618 + 16.2619 + if (!rc) { 16.2620 + const char* const s_errno = strerror(errno); 16.2621 + warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno); 16.2622 + return false; 16.2623 + } 16.2624 + 16.2625 + // mprotect success check 16.2626 + // 16.2627 + // Mprotect said it changed the protection but can I believe it? 16.2628 + // 16.2629 + // To be sure I need to check the protection afterwards. Try to 16.2630 + // read from protected memory and check whether that causes a segfault. 16.2631 + // 16.2632 + if (!os::Aix::xpg_sus_mode()) { 16.2633 + 16.2634 + if (StubRoutines::SafeFetch32_stub()) { 16.2635 + 16.2636 + const bool read_protected = 16.2637 + (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 && 16.2638 + SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false; 16.2639 + 16.2640 + if (prot & PROT_READ) { 16.2641 + rc = !read_protected; 16.2642 + } else { 16.2643 + rc = read_protected; 16.2644 + } 16.2645 + } 16.2646 + } 16.2647 + if (!rc) { 16.2648 + assert(false, "mprotect failed."); 16.2649 + } 16.2650 + return rc; 16.2651 +} 16.2652 + 16.2653 +// Set protections specified 16.2654 +bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) { 16.2655 + unsigned int p = 0; 16.2656 + switch (prot) { 16.2657 + case MEM_PROT_NONE: p = PROT_NONE; break; 16.2658 + case MEM_PROT_READ: p = PROT_READ; break; 16.2659 + case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; 16.2660 + case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; 16.2661 + default: 16.2662 + ShouldNotReachHere(); 16.2663 + } 16.2664 + // is_committed is unused. 16.2665 + return checked_mprotect(addr, size, p); 16.2666 +} 16.2667 + 16.2668 +bool os::guard_memory(char* addr, size_t size) { 16.2669 + return checked_mprotect(addr, size, PROT_NONE); 16.2670 +} 16.2671 + 16.2672 +bool os::unguard_memory(char* addr, size_t size) { 16.2673 + return checked_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC); 16.2674 +} 16.2675 + 16.2676 +// Large page support 16.2677 + 16.2678 +static size_t _large_page_size = 0; 16.2679 + 16.2680 +// Enable large page support if OS allows that. 16.2681 +void os::large_page_init() { 16.2682 + 16.2683 + // Note: os::Aix::query_multipage_support must run first. 16.2684 + 16.2685 + if (!UseLargePages) { 16.2686 + return; 16.2687 + } 16.2688 + 16.2689 + if (!Aix::can_use_64K_pages()) { 16.2690 + assert(!Aix::can_use_16M_pages(), "64K is a precondition for 16M."); 16.2691 + UseLargePages = false; 16.2692 + return; 16.2693 + } 16.2694 + 16.2695 + if (!Aix::can_use_16M_pages() && Use16MPages) { 16.2696 + fprintf(stderr, "Cannot use 16M pages. Please ensure that there is a 16M page pool " 16.2697 + " and that the VM runs with CAP_BYPASS_RAC_VMM and CAP_PROPAGATE capabilities.\n"); 16.2698 + } 16.2699 + 16.2700 + // Do not report 16M page alignment as part of os::_page_sizes if we are 16.2701 + // explicitly forbidden from using 16M pages. Doing so would increase the 16.2702 + // alignment the garbage collector calculates with, slightly increasing 16.2703 + // heap usage. We should only pay for 16M alignment if we really want to 16.2704 + // use 16M pages. 16.2705 + if (Use16MPages && Aix::can_use_16M_pages()) { 16.2706 + _large_page_size = SIZE_16M; 16.2707 + _page_sizes[0] = SIZE_16M; 16.2708 + _page_sizes[1] = SIZE_64K; 16.2709 + _page_sizes[2] = SIZE_4K; 16.2710 + _page_sizes[3] = 0; 16.2711 + } else if (Aix::can_use_64K_pages()) { 16.2712 + _large_page_size = SIZE_64K; 16.2713 + _page_sizes[0] = SIZE_64K; 16.2714 + _page_sizes[1] = SIZE_4K; 16.2715 + _page_sizes[2] = 0; 16.2716 + } 16.2717 + 16.2718 + if (Verbose) { 16.2719 + ("Default large page size is 0x%llX.", _large_page_size); 16.2720 + } 16.2721 +} // end: os::large_page_init() 16.2722 + 16.2723 +char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) { 16.2724 + // "exec" is passed in but not used. Creating the shared image for 16.2725 + // the code cache doesn't have an SHM_X executable permission to check. 16.2726 + Unimplemented(); 16.2727 + return 0; 16.2728 +} 16.2729 + 16.2730 +bool os::release_memory_special(char* base, size_t bytes) { 16.2731 + // detaching the SHM segment will also delete it, see reserve_memory_special() 16.2732 + Unimplemented(); 16.2733 + return false; 16.2734 +} 16.2735 + 16.2736 +size_t os::large_page_size() { 16.2737 + return _large_page_size; 16.2738 +} 16.2739 + 16.2740 +bool os::can_commit_large_page_memory() { 16.2741 + // Well, sadly we cannot commit anything at all (see comment in 16.2742 + // os::commit_memory) but we claim to so we can make use of large pages 16.2743 + return true; 16.2744 +} 16.2745 + 16.2746 +bool os::can_execute_large_page_memory() { 16.2747 + // We can do that 16.2748 + return true; 16.2749 +} 16.2750 + 16.2751 +// Reserve memory at an arbitrary address, only if that area is 16.2752 +// available (and not reserved for something else). 16.2753 +char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) { 16.2754 + 16.2755 + bool use_mmap = false; 16.2756 + 16.2757 + // mmap: smaller graining, no large page support 16.2758 + // shm: large graining (256M), large page support, limited number of shm segments 16.2759 + // 16.2760 + // Prefer mmap wherever we either do not need large page support or have OS limits 16.2761 + 16.2762 + if (!UseLargePages || bytes < SIZE_16M) { 16.2763 + use_mmap = true; 16.2764 + } 16.2765 + 16.2766 + char* addr = NULL; 16.2767 + if (use_mmap) { 16.2768 + addr = reserve_mmaped_memory(bytes, requested_addr); 16.2769 + } else { 16.2770 + // shmat: wish address is mandatory, and do not try 16M pages here. 16.2771 + shmatted_memory_info_t info; 16.2772 + const int flags = RESSHM_WISHADDR_OR_FAIL; 16.2773 + if (reserve_shmatted_memory(bytes, requested_addr, flags, &info)) { 16.2774 + addr = info.addr; 16.2775 + } 16.2776 + } 16.2777 + 16.2778 + return addr; 16.2779 +} 16.2780 + 16.2781 +size_t os::read(int fd, void *buf, unsigned int nBytes) { 16.2782 + return ::read(fd, buf, nBytes); 16.2783 +} 16.2784 + 16.2785 +#define NANOSECS_PER_MILLISEC 1000000 16.2786 + 16.2787 +int os::sleep(Thread* thread, jlong millis, bool interruptible) { 16.2788 + assert(thread == Thread::current(), "thread consistency check"); 16.2789 + 16.2790 + // Prevent nasty overflow in deadline calculation 16.2791 + // by handling long sleeps similar to solaris or windows. 16.2792 + const jlong limit = INT_MAX; 16.2793 + int result; 16.2794 + while (millis > limit) { 16.2795 + if ((result = os::sleep(thread, limit, interruptible)) != OS_OK) { 16.2796 + return result; 16.2797 + } 16.2798 + millis -= limit; 16.2799 + } 16.2800 + 16.2801 + ParkEvent * const slp = thread->_SleepEvent; 16.2802 + slp->reset(); 16.2803 + OrderAccess::fence(); 16.2804 + 16.2805 + if (interruptible) { 16.2806 + jlong prevtime = javaTimeNanos(); 16.2807 + 16.2808 + // Prevent precision loss and too long sleeps 16.2809 + jlong deadline = prevtime + millis * NANOSECS_PER_MILLISEC; 16.2810 + 16.2811 + for (;;) { 16.2812 + if (os::is_interrupted(thread, true)) { 16.2813 + return OS_INTRPT; 16.2814 + } 16.2815 + 16.2816 + jlong newtime = javaTimeNanos(); 16.2817 + 16.2818 + assert(newtime >= prevtime, "time moving backwards"); 16.2819 + // Doing prevtime and newtime in microseconds doesn't help precision, 16.2820 + // and trying to round up to avoid lost milliseconds can result in a 16.2821 + // too-short delay. 16.2822 + millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; 16.2823 + 16.2824 + if (millis <= 0) { 16.2825 + return OS_OK; 16.2826 + } 16.2827 + 16.2828 + // Stop sleeping if we passed the deadline 16.2829 + if (newtime >= deadline) { 16.2830 + return OS_OK; 16.2831 + } 16.2832 + 16.2833 + prevtime = newtime; 16.2834 + 16.2835 + { 16.2836 + assert(thread->is_Java_thread(), "sanity check"); 16.2837 + JavaThread *jt = (JavaThread *) thread; 16.2838 + ThreadBlockInVM tbivm(jt); 16.2839 + OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); 16.2840 + 16.2841 + jt->set_suspend_equivalent(); 16.2842 + 16.2843 + slp->park(millis); 16.2844 + 16.2845 + // were we externally suspended while we were waiting? 16.2846 + jt->check_and_wait_while_suspended(); 16.2847 + } 16.2848 + } 16.2849 + } else { 16.2850 + OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); 16.2851 + jlong prevtime = javaTimeNanos(); 16.2852 + 16.2853 + // Prevent precision loss and too long sleeps 16.2854 + jlong deadline = prevtime + millis * NANOSECS_PER_MILLISEC; 16.2855 + 16.2856 + for (;;) { 16.2857 + // It'd be nice to avoid the back-to-back javaTimeNanos() calls on 16.2858 + // the 1st iteration ... 16.2859 + jlong newtime = javaTimeNanos(); 16.2860 + 16.2861 + if (newtime - prevtime < 0) { 16.2862 + // time moving backwards, should only happen if no monotonic clock 16.2863 + // not a guarantee() because JVM should not abort on kernel/glibc bugs 16.2864 + // - HS14 Commented out as not implemented. 16.2865 + // - TODO Maybe we should implement it? 16.2866 + //assert(!Aix::supports_monotonic_clock(), "time moving backwards"); 16.2867 + } else { 16.2868 + millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; 16.2869 + } 16.2870 + 16.2871 + if (millis <= 0) break; 16.2872 + 16.2873 + if (newtime >= deadline) { 16.2874 + break; 16.2875 + } 16.2876 + 16.2877 + prevtime = newtime; 16.2878 + slp->park(millis); 16.2879 + } 16.2880 + return OS_OK; 16.2881 + } 16.2882 +} 16.2883 + 16.2884 +int os::naked_sleep() { 16.2885 + // %% make the sleep time an integer flag. for now use 1 millisec. 16.2886 + return os::sleep(Thread::current(), 1, false); 16.2887 +} 16.2888 + 16.2889 +// Sleep forever; naked call to OS-specific sleep; use with CAUTION 16.2890 +void os::infinite_sleep() { 16.2891 + while (true) { // sleep forever ... 16.2892 + ::sleep(100); // ... 100 seconds at a time 16.2893 + } 16.2894 +} 16.2895 + 16.2896 +// Used to convert frequent JVM_Yield() to nops 16.2897 +bool os::dont_yield() { 16.2898 + return DontYieldALot; 16.2899 +} 16.2900 + 16.2901 +void os::yield() { 16.2902 + sched_yield(); 16.2903 +} 16.2904 + 16.2905 +os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN; } 16.2906 + 16.2907 +void os::yield_all(int attempts) { 16.2908 + // Yields to all threads, including threads with lower priorities 16.2909 + // Threads on Linux are all with same priority. The Solaris style 16.2910 + // os::yield_all() with nanosleep(1ms) is not necessary. 16.2911 + sched_yield(); 16.2912 +} 16.2913 + 16.2914 +// Called from the tight loops to possibly influence time-sharing heuristics 16.2915 +void os::loop_breaker(int attempts) { 16.2916 + os::yield_all(attempts); 16.2917 +} 16.2918 + 16.2919 +//////////////////////////////////////////////////////////////////////////////// 16.2920 +// thread priority support 16.2921 + 16.2922 +// From AIX manpage to pthread_setschedparam 16.2923 +// (see: http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp? 16.2924 +// topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_setschedparam.htm): 16.2925 +// 16.2926 +// "If schedpolicy is SCHED_OTHER, then sched_priority must be in the 16.2927 +// range from 40 to 80, where 40 is the least favored priority and 80 16.2928 +// is the most favored." 16.2929 +// 16.2930 +// (Actually, I doubt this even has an impact on AIX, as we do kernel 16.2931 +// scheduling there; however, this still leaves iSeries.) 16.2932 +// 16.2933 +// We use the same values for AIX and PASE. 16.2934 +int os::java_to_os_priority[CriticalPriority + 1] = { 16.2935 + 54, // 0 Entry should never be used 16.2936 + 16.2937 + 55, // 1 MinPriority 16.2938 + 55, // 2 16.2939 + 56, // 3 16.2940 + 16.2941 + 56, // 4 16.2942 + 57, // 5 NormPriority 16.2943 + 57, // 6 16.2944 + 16.2945 + 58, // 7 16.2946 + 58, // 8 16.2947 + 59, // 9 NearMaxPriority 16.2948 + 16.2949 + 60, // 10 MaxPriority 16.2950 + 16.2951 + 60 // 11 CriticalPriority 16.2952 +}; 16.2953 + 16.2954 +OSReturn os::set_native_priority(Thread* thread, int newpri) { 16.2955 + if (!UseThreadPriorities) return OS_OK; 16.2956 + pthread_t thr = thread->osthread()->pthread_id(); 16.2957 + int policy = SCHED_OTHER; 16.2958 + struct sched_param param; 16.2959 + param.sched_priority = newpri; 16.2960 + int ret = pthread_setschedparam(thr, policy, ¶m); 16.2961 + 16.2962 + if (Verbose) { 16.2963 + if (ret == 0) { 16.2964 + fprintf(stderr, "changed priority of thread %d to %d\n", (int)thr, newpri); 16.2965 + } else { 16.2966 + fprintf(stderr, "Could not changed priority for thread %d to %d (error %d, %s)\n", 16.2967 + (int)thr, newpri, ret, strerror(ret)); 16.2968 + } 16.2969 + } 16.2970 + return (ret == 0) ? OS_OK : OS_ERR; 16.2971 +} 16.2972 + 16.2973 +OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { 16.2974 + if (!UseThreadPriorities) { 16.2975 + *priority_ptr = java_to_os_priority[NormPriority]; 16.2976 + return OS_OK; 16.2977 + } 16.2978 + pthread_t thr = thread->osthread()->pthread_id(); 16.2979 + int policy = SCHED_OTHER; 16.2980 + struct sched_param param; 16.2981 + int ret = pthread_getschedparam(thr, &policy, ¶m); 16.2982 + *priority_ptr = param.sched_priority; 16.2983 + 16.2984 + return (ret == 0) ? OS_OK : OS_ERR; 16.2985 +} 16.2986 + 16.2987 +// Hint to the underlying OS that a task switch would not be good. 16.2988 +// Void return because it's a hint and can fail. 16.2989 +void os::hint_no_preempt() {} 16.2990 + 16.2991 +//////////////////////////////////////////////////////////////////////////////// 16.2992 +// suspend/resume support 16.2993 + 16.2994 +// the low-level signal-based suspend/resume support is a remnant from the 16.2995 +// old VM-suspension that used to be for java-suspension, safepoints etc, 16.2996 +// within hotspot. Now there is a single use-case for this: 16.2997 +// - calling get_thread_pc() on the VMThread by the flat-profiler task 16.2998 +// that runs in the watcher thread. 16.2999 +// The remaining code is greatly simplified from the more general suspension 16.3000 +// code that used to be used. 16.3001 +// 16.3002 +// The protocol is quite simple: 16.3003 +// - suspend: 16.3004 +// - sends a signal to the target thread 16.3005 +// - polls the suspend state of the osthread using a yield loop 16.3006 +// - target thread signal handler (SR_handler) sets suspend state 16.3007 +// and blocks in sigsuspend until continued 16.3008 +// - resume: 16.3009 +// - sets target osthread state to continue 16.3010 +// - sends signal to end the sigsuspend loop in the SR_handler 16.3011 +// 16.3012 +// Note that the SR_lock plays no role in this suspend/resume protocol. 16.3013 +// 16.3014 + 16.3015 +static void resume_clear_context(OSThread *osthread) { 16.3016 + osthread->set_ucontext(NULL); 16.3017 + osthread->set_siginfo(NULL); 16.3018 +} 16.3019 + 16.3020 +static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { 16.3021 + osthread->set_ucontext(context); 16.3022 + osthread->set_siginfo(siginfo); 16.3023 +} 16.3024 + 16.3025 +// 16.3026 +// Handler function invoked when a thread's execution is suspended or 16.3027 +// resumed. We have to be careful that only async-safe functions are 16.3028 +// called here (Note: most pthread functions are not async safe and 16.3029 +// should be avoided.) 16.3030 +// 16.3031 +// Note: sigwait() is a more natural fit than sigsuspend() from an 16.3032 +// interface point of view, but sigwait() prevents the signal hander 16.3033 +// from being run. libpthread would get very confused by not having 16.3034 +// its signal handlers run and prevents sigwait()'s use with the 16.3035 +// mutex granting granting signal. 16.3036 +// 16.3037 +// Currently only ever called on the VMThread and JavaThreads (PC sampling). 16.3038 +// 16.3039 +static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { 16.3040 + // Save and restore errno to avoid confusing native code with EINTR 16.3041 + // after sigsuspend. 16.3042 + int old_errno = errno; 16.3043 + 16.3044 + Thread* thread = Thread::current(); 16.3045 + OSThread* osthread = thread->osthread(); 16.3046 + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); 16.3047 + 16.3048 + os::SuspendResume::State current = osthread->sr.state(); 16.3049 + if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { 16.3050 + suspend_save_context(osthread, siginfo, context); 16.3051 + 16.3052 + // attempt to switch the state, we assume we had a SUSPEND_REQUEST 16.3053 + os::SuspendResume::State state = osthread->sr.suspended(); 16.3054 + if (state == os::SuspendResume::SR_SUSPENDED) { 16.3055 + sigset_t suspend_set; // signals for sigsuspend() 16.3056 + 16.3057 + // get current set of blocked signals and unblock resume signal 16.3058 + pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); 16.3059 + sigdelset(&suspend_set, SR_signum); 16.3060 + 16.3061 + // wait here until we are resumed 16.3062 + while (1) { 16.3063 + sigsuspend(&suspend_set); 16.3064 + 16.3065 + os::SuspendResume::State result = osthread->sr.running(); 16.3066 + if (result == os::SuspendResume::SR_RUNNING) { 16.3067 + break; 16.3068 + } 16.3069 + } 16.3070 + 16.3071 + } else if (state == os::SuspendResume::SR_RUNNING) { 16.3072 + // request was cancelled, continue 16.3073 + } else { 16.3074 + ShouldNotReachHere(); 16.3075 + } 16.3076 + 16.3077 + resume_clear_context(osthread); 16.3078 + } else if (current == os::SuspendResume::SR_RUNNING) { 16.3079 + // request was cancelled, continue 16.3080 + } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { 16.3081 + // ignore 16.3082 + } else { 16.3083 + ShouldNotReachHere(); 16.3084 + } 16.3085 + 16.3086 + errno = old_errno; 16.3087 +} 16.3088 + 16.3089 + 16.3090 +static int SR_initialize() { 16.3091 + struct sigaction act; 16.3092 + char *s; 16.3093 + // Get signal number to use for suspend/resume 16.3094 + if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { 16.3095 + int sig = ::strtol(s, 0, 10); 16.3096 + if (sig > 0 || sig < NSIG) { 16.3097 + SR_signum = sig; 16.3098 + } 16.3099 + } 16.3100 + 16.3101 + assert(SR_signum > SIGSEGV && SR_signum > SIGBUS, 16.3102 + "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769"); 16.3103 + 16.3104 + sigemptyset(&SR_sigset); 16.3105 + sigaddset(&SR_sigset, SR_signum); 16.3106 + 16.3107 + // Set up signal handler for suspend/resume. 16.3108 + act.sa_flags = SA_RESTART|SA_SIGINFO; 16.3109 + act.sa_handler = (void (*)(int)) SR_handler; 16.3110 + 16.3111 + // SR_signum is blocked by default. 16.3112 + // 4528190 - We also need to block pthread restart signal (32 on all 16.3113 + // supported Linux platforms). Note that LinuxThreads need to block 16.3114 + // this signal for all threads to work properly. So we don't have 16.3115 + // to use hard-coded signal number when setting up the mask. 16.3116 + pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask); 16.3117 + 16.3118 + if (sigaction(SR_signum, &act, 0) == -1) { 16.3119 + return -1; 16.3120 + } 16.3121 + 16.3122 + // Save signal flag 16.3123 + os::Aix::set_our_sigflags(SR_signum, act.sa_flags); 16.3124 + return 0; 16.3125 +} 16.3126 + 16.3127 +static int SR_finalize() { 16.3128 + return 0; 16.3129 +} 16.3130 + 16.3131 +static int sr_notify(OSThread* osthread) { 16.3132 + int status = pthread_kill(osthread->pthread_id(), SR_signum); 16.3133 + assert_status(status == 0, status, "pthread_kill"); 16.3134 + return status; 16.3135 +} 16.3136 + 16.3137 +// "Randomly" selected value for how long we want to spin 16.3138 +// before bailing out on suspending a thread, also how often 16.3139 +// we send a signal to a thread we want to resume 16.3140 +static const int RANDOMLY_LARGE_INTEGER = 1000000; 16.3141 +static const int RANDOMLY_LARGE_INTEGER2 = 100; 16.3142 + 16.3143 +// returns true on success and false on error - really an error is fatal 16.3144 +// but this seems the normal response to library errors 16.3145 +static bool do_suspend(OSThread* osthread) { 16.3146 + assert(osthread->sr.is_running(), "thread should be running"); 16.3147 + // mark as suspended and send signal 16.3148 + 16.3149 + if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { 16.3150 + // failed to switch, state wasn't running? 16.3151 + ShouldNotReachHere(); 16.3152 + return false; 16.3153 + } 16.3154 + 16.3155 + if (sr_notify(osthread) != 0) { 16.3156 + // try to cancel, switch to running 16.3157 + 16.3158 + os::SuspendResume::State result = osthread->sr.cancel_suspend(); 16.3159 + if (result == os::SuspendResume::SR_RUNNING) { 16.3160 + // cancelled 16.3161 + return false; 16.3162 + } else if (result == os::SuspendResume::SR_SUSPENDED) { 16.3163 + // somehow managed to suspend 16.3164 + return true; 16.3165 + } else { 16.3166 + ShouldNotReachHere(); 16.3167 + return false; 16.3168 + } 16.3169 + } 16.3170 + 16.3171 + // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED 16.3172 + 16.3173 + for (int n = 0; !osthread->sr.is_suspended(); n++) { 16.3174 + for (int i = 0; i < RANDOMLY_LARGE_INTEGER2 && !osthread->sr.is_suspended(); i++) { 16.3175 + os::yield_all(i); 16.3176 + } 16.3177 + 16.3178 + // timeout, try to cancel the request 16.3179 + if (n >= RANDOMLY_LARGE_INTEGER) { 16.3180 + os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); 16.3181 + if (cancelled == os::SuspendResume::SR_RUNNING) { 16.3182 + return false; 16.3183 + } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { 16.3184 + return true; 16.3185 + } else { 16.3186 + ShouldNotReachHere(); 16.3187 + return false; 16.3188 + } 16.3189 + } 16.3190 + } 16.3191 + 16.3192 + guarantee(osthread->sr.is_suspended(), "Must be suspended"); 16.3193 + return true; 16.3194 +} 16.3195 + 16.3196 +static void do_resume(OSThread* osthread) { 16.3197 + //assert(osthread->sr.is_suspended(), "thread should be suspended"); 16.3198 + 16.3199 + if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { 16.3200 + // failed to switch to WAKEUP_REQUEST 16.3201 + ShouldNotReachHere(); 16.3202 + return; 16.3203 + } 16.3204 + 16.3205 + while (!osthread->sr.is_running()) { 16.3206 + if (sr_notify(osthread) == 0) { 16.3207 + for (int n = 0; n < RANDOMLY_LARGE_INTEGER && !osthread->sr.is_running(); n++) { 16.3208 + for (int i = 0; i < 100 && !osthread->sr.is_running(); i++) { 16.3209 + os::yield_all(i); 16.3210 + } 16.3211 + } 16.3212 + } else { 16.3213 + ShouldNotReachHere(); 16.3214 + } 16.3215 + } 16.3216 + 16.3217 + guarantee(osthread->sr.is_running(), "Must be running!"); 16.3218 +} 16.3219 + 16.3220 +//////////////////////////////////////////////////////////////////////////////// 16.3221 +// interrupt support 16.3222 + 16.3223 +void os::interrupt(Thread* thread) { 16.3224 + assert(Thread::current() == thread || Threads_lock->owned_by_self(), 16.3225 + "possibility of dangling Thread pointer"); 16.3226 + 16.3227 + OSThread* osthread = thread->osthread(); 16.3228 + 16.3229 + if (!osthread->interrupted()) { 16.3230 + osthread->set_interrupted(true); 16.3231 + // More than one thread can get here with the same value of osthread, 16.3232 + // resulting in multiple notifications. We do, however, want the store 16.3233 + // to interrupted() to be visible to other threads before we execute unpark(). 16.3234 + OrderAccess::fence(); 16.3235 + ParkEvent * const slp = thread->_SleepEvent; 16.3236 + if (slp != NULL) slp->unpark(); 16.3237 + } 16.3238 + 16.3239 + // For JSR166. Unpark even if interrupt status already was set 16.3240 + if (thread->is_Java_thread()) 16.3241 + ((JavaThread*)thread)->parker()->unpark(); 16.3242 + 16.3243 + ParkEvent * ev = thread->_ParkEvent; 16.3244 + if (ev != NULL) ev->unpark(); 16.3245 + 16.3246 +} 16.3247 + 16.3248 +bool os::is_interrupted(Thread* thread, bool clear_interrupted) { 16.3249 + assert(Thread::current() == thread || Threads_lock->owned_by_self(), 16.3250 + "possibility of dangling Thread pointer"); 16.3251 + 16.3252 + OSThread* osthread = thread->osthread(); 16.3253 + 16.3254 + bool interrupted = osthread->interrupted(); 16.3255 + 16.3256 + if (interrupted && clear_interrupted) { 16.3257 + osthread->set_interrupted(false); 16.3258 + // consider thread->_SleepEvent->reset() ... optional optimization 16.3259 + } 16.3260 + 16.3261 + return interrupted; 16.3262 +} 16.3263 + 16.3264 +/////////////////////////////////////////////////////////////////////////////////// 16.3265 +// signal handling (except suspend/resume) 16.3266 + 16.3267 +// This routine may be used by user applications as a "hook" to catch signals. 16.3268 +// The user-defined signal handler must pass unrecognized signals to this 16.3269 +// routine, and if it returns true (non-zero), then the signal handler must 16.3270 +// return immediately. If the flag "abort_if_unrecognized" is true, then this 16.3271 +// routine will never retun false (zero), but instead will execute a VM panic 16.3272 +// routine kill the process. 16.3273 +// 16.3274 +// If this routine returns false, it is OK to call it again. This allows 16.3275 +// the user-defined signal handler to perform checks either before or after 16.3276 +// the VM performs its own checks. Naturally, the user code would be making 16.3277 +// a serious error if it tried to handle an exception (such as a null check 16.3278 +// or breakpoint) that the VM was generating for its own correct operation. 16.3279 +// 16.3280 +// This routine may recognize any of the following kinds of signals: 16.3281 +// SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1. 16.3282 +// It should be consulted by handlers for any of those signals. 16.3283 +// 16.3284 +// The caller of this routine must pass in the three arguments supplied 16.3285 +// to the function referred to in the "sa_sigaction" (not the "sa_handler") 16.3286 +// field of the structure passed to sigaction(). This routine assumes that 16.3287 +// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART. 16.3288 +// 16.3289 +// Note that the VM will print warnings if it detects conflicting signal 16.3290 +// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". 16.3291 +// 16.3292 +extern "C" JNIEXPORT int 16.3293 +JVM_handle_aix_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); 16.3294 + 16.3295 +// Set thread signal mask (for some reason on AIX sigthreadmask() seems 16.3296 +// to be the thing to call; documentation is not terribly clear about whether 16.3297 +// pthread_sigmask also works, and if it does, whether it does the same. 16.3298 +bool set_thread_signal_mask(int how, const sigset_t* set, sigset_t* oset) { 16.3299 + const int rc = ::pthread_sigmask(how, set, oset); 16.3300 + // return value semantics differ slightly for error case: 16.3301 + // pthread_sigmask returns error number, sigthreadmask -1 and sets global errno 16.3302 + // (so, pthread_sigmask is more theadsafe for error handling) 16.3303 + // But success is always 0. 16.3304 + return rc == 0 ? true : false; 16.3305 +} 16.3306 + 16.3307 +// Function to unblock all signals which are, according 16.3308 +// to POSIX, typical program error signals. If they happen while being blocked, 16.3309 +// they typically will bring down the process immediately. 16.3310 +bool unblock_program_error_signals() { 16.3311 + sigset_t set; 16.3312 + ::sigemptyset(&set); 16.3313 + ::sigaddset(&set, SIGILL); 16.3314 + ::sigaddset(&set, SIGBUS); 16.3315 + ::sigaddset(&set, SIGFPE); 16.3316 + ::sigaddset(&set, SIGSEGV); 16.3317 + return set_thread_signal_mask(SIG_UNBLOCK, &set, NULL); 16.3318 +} 16.3319 + 16.3320 +// Renamed from 'signalHandler' to avoid collision with other shared libs. 16.3321 +void javaSignalHandler(int sig, siginfo_t* info, void* uc) { 16.3322 + assert(info != NULL && uc != NULL, "it must be old kernel"); 16.3323 + 16.3324 + // Never leave program error signals blocked; 16.3325 + // on all our platforms they would bring down the process immediately when 16.3326 + // getting raised while being blocked. 16.3327 + unblock_program_error_signals(); 16.3328 + 16.3329 + JVM_handle_aix_signal(sig, info, uc, true); 16.3330 +} 16.3331 + 16.3332 + 16.3333 +// This boolean allows users to forward their own non-matching signals 16.3334 +// to JVM_handle_aix_signal, harmlessly. 16.3335 +bool os::Aix::signal_handlers_are_installed = false; 16.3336 + 16.3337 +// For signal-chaining 16.3338 +struct sigaction os::Aix::sigact[MAXSIGNUM]; 16.3339 +unsigned int os::Aix::sigs = 0; 16.3340 +bool os::Aix::libjsig_is_loaded = false; 16.3341 +typedef struct sigaction *(*get_signal_t)(int); 16.3342 +get_signal_t os::Aix::get_signal_action = NULL; 16.3343 + 16.3344 +struct sigaction* os::Aix::get_chained_signal_action(int sig) { 16.3345 + struct sigaction *actp = NULL; 16.3346 + 16.3347 + if (libjsig_is_loaded) { 16.3348 + // Retrieve the old signal handler from libjsig 16.3349 + actp = (*get_signal_action)(sig); 16.3350 + } 16.3351 + if (actp == NULL) { 16.3352 + // Retrieve the preinstalled signal handler from jvm 16.3353 + actp = get_preinstalled_handler(sig); 16.3354 + } 16.3355 + 16.3356 + return actp; 16.3357 +} 16.3358 + 16.3359 +static bool call_chained_handler(struct sigaction *actp, int sig, 16.3360 + siginfo_t *siginfo, void *context) { 16.3361 + Unimplemented(); 16.3362 + return true; 16.3363 +} 16.3364 + 16.3365 +bool os::Aix::chained_handler(int sig, siginfo_t* siginfo, void* context) { 16.3366 + bool chained = false; 16.3367 + // signal-chaining 16.3368 + if (UseSignalChaining) { 16.3369 + struct sigaction *actp = get_chained_signal_action(sig); 16.3370 + if (actp != NULL) { 16.3371 + chained = call_chained_handler(actp, sig, siginfo, context); 16.3372 + } 16.3373 + } 16.3374 + return chained; 16.3375 +} 16.3376 + 16.3377 +struct sigaction* os::Aix::get_preinstalled_handler(int sig) { 16.3378 + if ((((unsigned int)1 << sig) & sigs) != 0) { 16.3379 + return &sigact[sig]; 16.3380 + } 16.3381 + return NULL; 16.3382 +} 16.3383 + 16.3384 +void os::Aix::save_preinstalled_handler(int sig, struct sigaction& oldAct) { 16.3385 + assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); 16.3386 + sigact[sig] = oldAct; 16.3387 + sigs |= (unsigned int)1 << sig; 16.3388 +} 16.3389 + 16.3390 +// for diagnostic 16.3391 +int os::Aix::sigflags[MAXSIGNUM]; 16.3392 + 16.3393 +int os::Aix::get_our_sigflags(int sig) { 16.3394 + assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); 16.3395 + return sigflags[sig]; 16.3396 +} 16.3397 + 16.3398 +void os::Aix::set_our_sigflags(int sig, int flags) { 16.3399 + assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); 16.3400 + sigflags[sig] = flags; 16.3401 +} 16.3402 + 16.3403 +void os::Aix::set_signal_handler(int sig, bool set_installed) { 16.3404 + // Check for overwrite. 16.3405 + struct sigaction oldAct; 16.3406 + sigaction(sig, (struct sigaction*)NULL, &oldAct); 16.3407 + 16.3408 + void* oldhand = oldAct.sa_sigaction 16.3409 + ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 16.3410 + : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 16.3411 + // Renamed 'signalHandler' to avoid collision with other shared libs. 16.3412 + if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && 16.3413 + oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && 16.3414 + oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)javaSignalHandler)) { 16.3415 + if (AllowUserSignalHandlers || !set_installed) { 16.3416 + // Do not overwrite; user takes responsibility to forward to us. 16.3417 + return; 16.3418 + } else if (UseSignalChaining) { 16.3419 + // save the old handler in jvm 16.3420 + save_preinstalled_handler(sig, oldAct); 16.3421 + // libjsig also interposes the sigaction() call below and saves the 16.3422 + // old sigaction on it own. 16.3423 + } else { 16.3424 + fatal(err_msg("Encountered unexpected pre-existing sigaction handler " 16.3425 + "%#lx for signal %d.", (long)oldhand, sig)); 16.3426 + } 16.3427 + } 16.3428 + 16.3429 + struct sigaction sigAct; 16.3430 + sigfillset(&(sigAct.sa_mask)); 16.3431 + if (!set_installed) { 16.3432 + sigAct.sa_handler = SIG_DFL; 16.3433 + sigAct.sa_flags = SA_RESTART; 16.3434 + } else { 16.3435 + // Renamed 'signalHandler' to avoid collision with other shared libs. 16.3436 + sigAct.sa_sigaction = javaSignalHandler; 16.3437 + sigAct.sa_flags = SA_SIGINFO|SA_RESTART; 16.3438 + } 16.3439 + // Save flags, which are set by ours 16.3440 + assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); 16.3441 + sigflags[sig] = sigAct.sa_flags; 16.3442 + 16.3443 + int ret = sigaction(sig, &sigAct, &oldAct); 16.3444 + assert(ret == 0, "check"); 16.3445 + 16.3446 + void* oldhand2 = oldAct.sa_sigaction 16.3447 + ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 16.3448 + : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 16.3449 + assert(oldhand2 == oldhand, "no concurrent signal handler installation"); 16.3450 +} 16.3451 + 16.3452 +// install signal handlers for signals that HotSpot needs to 16.3453 +// handle in order to support Java-level exception handling. 16.3454 +void os::Aix::install_signal_handlers() { 16.3455 + if (!signal_handlers_are_installed) { 16.3456 + signal_handlers_are_installed = true; 16.3457 + 16.3458 + // signal-chaining 16.3459 + typedef void (*signal_setting_t)(); 16.3460 + signal_setting_t begin_signal_setting = NULL; 16.3461 + signal_setting_t end_signal_setting = NULL; 16.3462 + begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t, 16.3463 + dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting")); 16.3464 + if (begin_signal_setting != NULL) { 16.3465 + end_signal_setting = CAST_TO_FN_PTR(signal_setting_t, 16.3466 + dlsym(RTLD_DEFAULT, "JVM_end_signal_setting")); 16.3467 + get_signal_action = CAST_TO_FN_PTR(get_signal_t, 16.3468 + dlsym(RTLD_DEFAULT, "JVM_get_signal_action")); 16.3469 + libjsig_is_loaded = true; 16.3470 + assert(UseSignalChaining, "should enable signal-chaining"); 16.3471 + } 16.3472 + if (libjsig_is_loaded) { 16.3473 + // Tell libjsig jvm is setting signal handlers 16.3474 + (*begin_signal_setting)(); 16.3475 + } 16.3476 + 16.3477 + set_signal_handler(SIGSEGV, true); 16.3478 + set_signal_handler(SIGPIPE, true); 16.3479 + set_signal_handler(SIGBUS, true); 16.3480 + set_signal_handler(SIGILL, true); 16.3481 + set_signal_handler(SIGFPE, true); 16.3482 + set_signal_handler(SIGTRAP, true); 16.3483 + set_signal_handler(SIGXFSZ, true); 16.3484 + set_signal_handler(SIGDANGER, true); 16.3485 + 16.3486 + if (libjsig_is_loaded) { 16.3487 + // Tell libjsig jvm finishes setting signal handlers 16.3488 + (*end_signal_setting)(); 16.3489 + } 16.3490 + 16.3491 + // We don't activate signal checker if libjsig is in place, we trust ourselves 16.3492 + // and if UserSignalHandler is installed all bets are off. 16.3493 + // Log that signal checking is off only if -verbose:jni is specified. 16.3494 + if (CheckJNICalls) { 16.3495 + if (libjsig_is_loaded) { 16.3496 + tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); 16.3497 + check_signals = false; 16.3498 + } 16.3499 + if (AllowUserSignalHandlers) { 16.3500 + tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); 16.3501 + check_signals = false; 16.3502 + } 16.3503 + // need to initialize check_signal_done 16.3504 + ::sigemptyset(&check_signal_done); 16.3505 + } 16.3506 + } 16.3507 +} 16.3508 + 16.3509 +static const char* get_signal_handler_name(address handler, 16.3510 + char* buf, int buflen) { 16.3511 + int offset; 16.3512 + bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset); 16.3513 + if (found) { 16.3514 + // skip directory names 16.3515 + const char *p1, *p2; 16.3516 + p1 = buf; 16.3517 + size_t len = strlen(os::file_separator()); 16.3518 + while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; 16.3519 + // The way os::dll_address_to_library_name is implemented on Aix 16.3520 + // right now, it always returns -1 for the offset which is not 16.3521 + // terribly informative. 16.3522 + // Will fix that. For now, omit the offset. 16.3523 + jio_snprintf(buf, buflen, "%s", p1); 16.3524 + } else { 16.3525 + jio_snprintf(buf, buflen, PTR_FORMAT, handler); 16.3526 + } 16.3527 + return buf; 16.3528 +} 16.3529 + 16.3530 +static void print_signal_handler(outputStream* st, int sig, 16.3531 + char* buf, size_t buflen) { 16.3532 + struct sigaction sa; 16.3533 + sigaction(sig, NULL, &sa); 16.3534 + 16.3535 + st->print("%s: ", os::exception_name(sig, buf, buflen)); 16.3536 + 16.3537 + address handler = (sa.sa_flags & SA_SIGINFO) 16.3538 + ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) 16.3539 + : CAST_FROM_FN_PTR(address, sa.sa_handler); 16.3540 + 16.3541 + if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) { 16.3542 + st->print("SIG_DFL"); 16.3543 + } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) { 16.3544 + st->print("SIG_IGN"); 16.3545 + } else { 16.3546 + st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); 16.3547 + } 16.3548 + 16.3549 + // Print readable mask. 16.3550 + st->print(", sa_mask[0]="); 16.3551 + os::Posix::print_signal_set_short(st, &sa.sa_mask); 16.3552 + 16.3553 + address rh = VMError::get_resetted_sighandler(sig); 16.3554 + // May be, handler was resetted by VMError? 16.3555 + if (rh != NULL) { 16.3556 + handler = rh; 16.3557 + sa.sa_flags = VMError::get_resetted_sigflags(sig); 16.3558 + } 16.3559 + 16.3560 + // Print textual representation of sa_flags. 16.3561 + st->print(", sa_flags="); 16.3562 + os::Posix::print_sa_flags(st, sa.sa_flags); 16.3563 + 16.3564 + // Check: is it our handler? 16.3565 + if (handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)javaSignalHandler) || 16.3566 + handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) { 16.3567 + // It is our signal handler. 16.3568 + // Check for flags, reset system-used one! 16.3569 + if ((int)sa.sa_flags != os::Aix::get_our_sigflags(sig)) { 16.3570 + st->print(", flags was changed from " PTR32_FORMAT ", consider using jsig library", 16.3571 + os::Aix::get_our_sigflags(sig)); 16.3572 + } 16.3573 + } 16.3574 + st->cr(); 16.3575 +} 16.3576 + 16.3577 + 16.3578 +#define DO_SIGNAL_CHECK(sig) \ 16.3579 + if (!sigismember(&check_signal_done, sig)) \ 16.3580 + os::Aix::check_signal_handler(sig) 16.3581 + 16.3582 +// This method is a periodic task to check for misbehaving JNI applications 16.3583 +// under CheckJNI, we can add any periodic checks here 16.3584 + 16.3585 +void os::run_periodic_checks() { 16.3586 + 16.3587 + if (check_signals == false) return; 16.3588 + 16.3589 + // SEGV and BUS if overridden could potentially prevent 16.3590 + // generation of hs*.log in the event of a crash, debugging 16.3591 + // such a case can be very challenging, so we absolutely 16.3592 + // check the following for a good measure: 16.3593 + DO_SIGNAL_CHECK(SIGSEGV); 16.3594 + DO_SIGNAL_CHECK(SIGILL); 16.3595 + DO_SIGNAL_CHECK(SIGFPE); 16.3596 + DO_SIGNAL_CHECK(SIGBUS); 16.3597 + DO_SIGNAL_CHECK(SIGPIPE); 16.3598 + DO_SIGNAL_CHECK(SIGXFSZ); 16.3599 + if (UseSIGTRAP) { 16.3600 + DO_SIGNAL_CHECK(SIGTRAP); 16.3601 + } 16.3602 + DO_SIGNAL_CHECK(SIGDANGER); 16.3603 + 16.3604 + // ReduceSignalUsage allows the user to override these handlers 16.3605 + // see comments at the very top and jvm_solaris.h 16.3606 + if (!ReduceSignalUsage) { 16.3607 + DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); 16.3608 + DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); 16.3609 + DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL); 16.3610 + DO_SIGNAL_CHECK(BREAK_SIGNAL); 16.3611 + } 16.3612 + 16.3613 + DO_SIGNAL_CHECK(SR_signum); 16.3614 + DO_SIGNAL_CHECK(INTERRUPT_SIGNAL); 16.3615 +} 16.3616 + 16.3617 +typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *); 16.3618 + 16.3619 +static os_sigaction_t os_sigaction = NULL; 16.3620 + 16.3621 +void os::Aix::check_signal_handler(int sig) { 16.3622 + char buf[O_BUFLEN]; 16.3623 + address jvmHandler = NULL; 16.3624 + 16.3625 + struct sigaction act; 16.3626 + if (os_sigaction == NULL) { 16.3627 + // only trust the default sigaction, in case it has been interposed 16.3628 + os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); 16.3629 + if (os_sigaction == NULL) return; 16.3630 + } 16.3631 + 16.3632 + os_sigaction(sig, (struct sigaction*)NULL, &act); 16.3633 + 16.3634 + address thisHandler = (act.sa_flags & SA_SIGINFO) 16.3635 + ? CAST_FROM_FN_PTR(address, act.sa_sigaction) 16.3636 + : CAST_FROM_FN_PTR(address, act.sa_handler); 16.3637 + 16.3638 + 16.3639 + switch(sig) { 16.3640 + case SIGSEGV: 16.3641 + case SIGBUS: 16.3642 + case SIGFPE: 16.3643 + case SIGPIPE: 16.3644 + case SIGILL: 16.3645 + case SIGXFSZ: 16.3646 + // Renamed 'signalHandler' to avoid collision with other shared libs. 16.3647 + jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)javaSignalHandler); 16.3648 + break; 16.3649 + 16.3650 + case SHUTDOWN1_SIGNAL: 16.3651 + case SHUTDOWN2_SIGNAL: 16.3652 + case SHUTDOWN3_SIGNAL: 16.3653 + case BREAK_SIGNAL: 16.3654 + jvmHandler = (address)user_handler(); 16.3655 + break; 16.3656 + 16.3657 + case INTERRUPT_SIGNAL: 16.3658 + jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL); 16.3659 + break; 16.3660 + 16.3661 + default: 16.3662 + if (sig == SR_signum) { 16.3663 + jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler); 16.3664 + } else { 16.3665 + return; 16.3666 + } 16.3667 + break; 16.3668 + } 16.3669 + 16.3670 + if (thisHandler != jvmHandler) { 16.3671 + tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN)); 16.3672 + tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN)); 16.3673 + tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN)); 16.3674 + // No need to check this sig any longer 16.3675 + sigaddset(&check_signal_done, sig); 16.3676 + } else if (os::Aix::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Aix::get_our_sigflags(sig)) { 16.3677 + tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN)); 16.3678 + tty->print("expected:" PTR32_FORMAT, os::Aix::get_our_sigflags(sig)); 16.3679 + tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags); 16.3680 + // No need to check this sig any longer 16.3681 + sigaddset(&check_signal_done, sig); 16.3682 + } 16.3683 + 16.3684 + // Dump all the signal 16.3685 + if (sigismember(&check_signal_done, sig)) { 16.3686 + print_signal_handlers(tty, buf, O_BUFLEN); 16.3687 + } 16.3688 +} 16.3689 + 16.3690 +extern bool signal_name(int signo, char* buf, size_t len); 16.3691 + 16.3692 +const char* os::exception_name(int exception_code, char* buf, size_t size) { 16.3693 + if (0 < exception_code && exception_code <= SIGRTMAX) { 16.3694 + // signal 16.3695 + if (!signal_name(exception_code, buf, size)) { 16.3696 + jio_snprintf(buf, size, "SIG%d", exception_code); 16.3697 + } 16.3698 + return buf; 16.3699 + } else { 16.3700 + return NULL; 16.3701 + } 16.3702 +} 16.3703 + 16.3704 +// To install functions for atexit system call 16.3705 +extern "C" { 16.3706 + static void perfMemory_exit_helper() { 16.3707 + perfMemory_exit(); 16.3708 + } 16.3709 +} 16.3710 + 16.3711 +// This is called _before_ the most of global arguments have been parsed. 16.3712 +void os::init(void) { 16.3713 + // This is basic, we want to know if that ever changes. 16.3714 + // (shared memory boundary is supposed to be a 256M aligned) 16.3715 + assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected"); 16.3716 + 16.3717 + // First off, we need to know whether we run on AIX or PASE, and 16.3718 + // the OS level we run on. 16.3719 + os::Aix::initialize_os_info(); 16.3720 + 16.3721 + // Scan environment (SPEC1170 behaviour, etc) 16.3722 + os::Aix::scan_environment(); 16.3723 + 16.3724 + // Check which pages are supported by AIX. 16.3725 + os::Aix::query_multipage_support(); 16.3726 + 16.3727 + // Next, we need to initialize libo4 and libperfstat libraries. 16.3728 + if (os::Aix::on_pase()) { 16.3729 + os::Aix::initialize_libo4(); 16.3730 + } else { 16.3731 + os::Aix::initialize_libperfstat(); 16.3732 + } 16.3733 + 16.3734 + // Reset the perfstat information provided by ODM. 16.3735 + if (os::Aix::on_aix()) { 16.3736 + libperfstat::perfstat_reset(); 16.3737 + } 16.3738 + 16.3739 + // Now initialze basic system properties. Note that for some of the values we 16.3740 + // need libperfstat etc. 16.3741 + os::Aix::initialize_system_info(); 16.3742 + 16.3743 + // Initialize large page support. 16.3744 + if (UseLargePages) { 16.3745 + os::large_page_init(); 16.3746 + if (!UseLargePages) { 16.3747 + // initialize os::_page_sizes 16.3748 + _page_sizes[0] = Aix::page_size(); 16.3749 + _page_sizes[1] = 0; 16.3750 + if (Verbose) { 16.3751 + fprintf(stderr, "Large Page initialization failed: setting UseLargePages=0.\n"); 16.3752 + } 16.3753 + } 16.3754 + } else { 16.3755 + // initialize os::_page_sizes 16.3756 + _page_sizes[0] = Aix::page_size(); 16.3757 + _page_sizes[1] = 0; 16.3758 + } 16.3759 + 16.3760 + // debug trace 16.3761 + if (Verbose) { 16.3762 + fprintf(stderr, "os::vm_page_size 0x%llX\n", os::vm_page_size()); 16.3763 + fprintf(stderr, "os::large_page_size 0x%llX\n", os::large_page_size()); 16.3764 + fprintf(stderr, "os::_page_sizes = ( "); 16.3765 + for (int i = 0; _page_sizes[i]; i ++) { 16.3766 + fprintf(stderr, " %s ", describe_pagesize(_page_sizes[i])); 16.3767 + } 16.3768 + fprintf(stderr, ")\n"); 16.3769 + } 16.3770 + 16.3771 + _initial_pid = getpid(); 16.3772 + 16.3773 + clock_tics_per_sec = sysconf(_SC_CLK_TCK); 16.3774 + 16.3775 + init_random(1234567); 16.3776 + 16.3777 + ThreadCritical::initialize(); 16.3778 + 16.3779 + // Main_thread points to the aboriginal thread. 16.3780 + Aix::_main_thread = pthread_self(); 16.3781 + 16.3782 + initial_time_count = os::elapsed_counter(); 16.3783 + pthread_mutex_init(&dl_mutex, NULL); 16.3784 +} 16.3785 + 16.3786 +// this is called _after_ the global arguments have been parsed 16.3787 +jint os::init_2(void) { 16.3788 + 16.3789 + if (Verbose) { 16.3790 + fprintf(stderr, "processor count: %d\n", os::_processor_count); 16.3791 + fprintf(stderr, "physical memory: %lu\n", Aix::_physical_memory); 16.3792 + } 16.3793 + 16.3794 + // initially build up the loaded dll map 16.3795 + LoadedLibraries::reload(); 16.3796 + 16.3797 + const int page_size = Aix::page_size(); 16.3798 + const int map_size = page_size; 16.3799 + 16.3800 + address map_address = (address) MAP_FAILED; 16.3801 + const int prot = PROT_READ; 16.3802 + const int flags = MAP_PRIVATE|MAP_ANONYMOUS; 16.3803 + 16.3804 + // use optimized addresses for the polling page, 16.3805 + // e.g. map it to a special 32-bit address. 16.3806 + if (OptimizePollingPageLocation) { 16.3807 + // architecture-specific list of address wishes: 16.3808 + address address_wishes[] = { 16.3809 + // AIX: addresses lower than 0x30000000 don't seem to work on AIX. 16.3810 + // PPC64: all address wishes are non-negative 32 bit values where 16.3811 + // the lower 16 bits are all zero. we can load these addresses 16.3812 + // with a single ppc_lis instruction. 16.3813 + (address) 0x30000000, (address) 0x31000000, 16.3814 + (address) 0x32000000, (address) 0x33000000, 16.3815 + (address) 0x40000000, (address) 0x41000000, 16.3816 + (address) 0x42000000, (address) 0x43000000, 16.3817 + (address) 0x50000000, (address) 0x51000000, 16.3818 + (address) 0x52000000, (address) 0x53000000, 16.3819 + (address) 0x60000000, (address) 0x61000000, 16.3820 + (address) 0x62000000, (address) 0x63000000 16.3821 + }; 16.3822 + int address_wishes_length = sizeof(address_wishes)/sizeof(address); 16.3823 + 16.3824 + // iterate over the list of address wishes: 16.3825 + for (int i=0; i<address_wishes_length; i++) { 16.3826 + // try to map with current address wish. 16.3827 + // AIX: AIX needs MAP_FIXED if we provide an address and mmap will 16.3828 + // fail if the address is already mapped. 16.3829 + map_address = (address) ::mmap(address_wishes[i] - (ssize_t)page_size, 16.3830 + map_size, prot, 16.3831 + flags | MAP_FIXED, 16.3832 + -1, 0); 16.3833 + if (Verbose) { 16.3834 + fprintf(stderr, "SafePoint Polling Page address: %p (wish) => %p\n", 16.3835 + address_wishes[i], map_address + (ssize_t)page_size); 16.3836 + } 16.3837 + 16.3838 + if (map_address + (ssize_t)page_size == address_wishes[i]) { 16.3839 + // map succeeded and map_address is at wished address, exit loop. 16.3840 + break; 16.3841 + } 16.3842 + 16.3843 + if (map_address != (address) MAP_FAILED) { 16.3844 + // map succeeded, but polling_page is not at wished address, unmap and continue. 16.3845 + ::munmap(map_address, map_size); 16.3846 + map_address = (address) MAP_FAILED; 16.3847 + } 16.3848 + // map failed, continue loop. 16.3849 + } 16.3850 + } // end OptimizePollingPageLocation 16.3851 + 16.3852 + if (map_address == (address) MAP_FAILED) { 16.3853 + map_address = (address) ::mmap(NULL, map_size, prot, flags, -1, 0); 16.3854 + } 16.3855 + guarantee(map_address != MAP_FAILED, "os::init_2: failed to allocate polling page"); 16.3856 + os::set_polling_page(map_address); 16.3857 + 16.3858 + if (!UseMembar) { 16.3859 + address mem_serialize_page = (address) ::mmap(NULL, Aix::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 16.3860 + guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); 16.3861 + os::set_memory_serialize_page(mem_serialize_page); 16.3862 + 16.3863 +#ifndef PRODUCT 16.3864 + if (Verbose && PrintMiscellaneous) 16.3865 + tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 16.3866 +#endif 16.3867 + } 16.3868 + 16.3869 + // initialize suspend/resume support - must do this before signal_sets_init() 16.3870 + if (SR_initialize() != 0) { 16.3871 + perror("SR_initialize failed"); 16.3872 + return JNI_ERR; 16.3873 + } 16.3874 + 16.3875 + Aix::signal_sets_init(); 16.3876 + Aix::install_signal_handlers(); 16.3877 + 16.3878 + // Check minimum allowable stack size for thread creation and to initialize 16.3879 + // the java system classes, including StackOverflowError - depends on page 16.3880 + // size. Add a page for compiler2 recursion in main thread. 16.3881 + // Add in 2*BytesPerWord times page size to account for VM stack during 16.3882 + // class initialization depending on 32 or 64 bit VM. 16.3883 + os::Aix::min_stack_allowed = MAX2(os::Aix::min_stack_allowed, 16.3884 + (size_t)(StackYellowPages+StackRedPages+StackShadowPages + 16.3885 + 2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::page_size()); 16.3886 + 16.3887 + size_t threadStackSizeInBytes = ThreadStackSize * K; 16.3888 + if (threadStackSizeInBytes != 0 && 16.3889 + threadStackSizeInBytes < os::Aix::min_stack_allowed) { 16.3890 + tty->print_cr("\nThe stack size specified is too small, " 16.3891 + "Specify at least %dk", 16.3892 + os::Aix::min_stack_allowed / K); 16.3893 + return JNI_ERR; 16.3894 + } 16.3895 + 16.3896 + // Make the stack size a multiple of the page size so that 16.3897 + // the yellow/red zones can be guarded. 16.3898 + // note that this can be 0, if no default stacksize was set 16.3899 + JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); 16.3900 + 16.3901 + Aix::libpthread_init(); 16.3902 + 16.3903 + if (MaxFDLimit) { 16.3904 + // set the number of file descriptors to max. print out error 16.3905 + // if getrlimit/setrlimit fails but continue regardless. 16.3906 + struct rlimit nbr_files; 16.3907 + int status = getrlimit(RLIMIT_NOFILE, &nbr_files); 16.3908 + if (status != 0) { 16.3909 + if (PrintMiscellaneous && (Verbose || WizardMode)) 16.3910 + perror("os::init_2 getrlimit failed"); 16.3911 + } else { 16.3912 + nbr_files.rlim_cur = nbr_files.rlim_max; 16.3913 + status = setrlimit(RLIMIT_NOFILE, &nbr_files); 16.3914 + if (status != 0) { 16.3915 + if (PrintMiscellaneous && (Verbose || WizardMode)) 16.3916 + perror("os::init_2 setrlimit failed"); 16.3917 + } 16.3918 + } 16.3919 + } 16.3920 + 16.3921 + if (PerfAllowAtExitRegistration) { 16.3922 + // only register atexit functions if PerfAllowAtExitRegistration is set. 16.3923 + // atexit functions can be delayed until process exit time, which 16.3924 + // can be problematic for embedded VM situations. Embedded VMs should 16.3925 + // call DestroyJavaVM() to assure that VM resources are released. 16.3926 + 16.3927 + // note: perfMemory_exit_helper atexit function may be removed in 16.3928 + // the future if the appropriate cleanup code can be added to the 16.3929 + // VM_Exit VMOperation's doit method. 16.3930 + if (atexit(perfMemory_exit_helper) != 0) { 16.3931 + warning("os::init_2 atexit(perfMemory_exit_helper) failed"); 16.3932 + } 16.3933 + } 16.3934 + 16.3935 + return JNI_OK; 16.3936 +} 16.3937 + 16.3938 +// this is called at the end of vm_initialization 16.3939 +void os::init_3(void) { 16.3940 + return; 16.3941 +} 16.3942 + 16.3943 +// Mark the polling page as unreadable 16.3944 +void os::make_polling_page_unreadable(void) { 16.3945 + if (!guard_memory((char*)_polling_page, Aix::page_size())) { 16.3946 + fatal("Could not disable polling page"); 16.3947 + } 16.3948 +}; 16.3949 + 16.3950 +// Mark the polling page as readable 16.3951 +void os::make_polling_page_readable(void) { 16.3952 + // Changed according to os_linux.cpp. 16.3953 + if (!checked_mprotect((char *)_polling_page, Aix::page_size(), PROT_READ)) { 16.3954 + fatal(err_msg("Could not enable polling page at " PTR_FORMAT, _polling_page)); 16.3955 + } 16.3956 +}; 16.3957 + 16.3958 +int os::active_processor_count() { 16.3959 + int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); 16.3960 + assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); 16.3961 + return online_cpus; 16.3962 +} 16.3963 + 16.3964 +void os::set_native_thread_name(const char *name) { 16.3965 + // Not yet implemented. 16.3966 + return; 16.3967 +} 16.3968 + 16.3969 +bool os::distribute_processes(uint length, uint* distribution) { 16.3970 + // Not yet implemented. 16.3971 + return false; 16.3972 +} 16.3973 + 16.3974 +bool os::bind_to_processor(uint processor_id) { 16.3975 + // Not yet implemented. 16.3976 + return false; 16.3977 +} 16.3978 + 16.3979 +void os::SuspendedThreadTask::internal_do_task() { 16.3980 + if (do_suspend(_thread->osthread())) { 16.3981 + SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); 16.3982 + do_task(context); 16.3983 + do_resume(_thread->osthread()); 16.3984 + } 16.3985 +} 16.3986 + 16.3987 +class PcFetcher : public os::SuspendedThreadTask { 16.3988 +public: 16.3989 + PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} 16.3990 + ExtendedPC result(); 16.3991 +protected: 16.3992 + void do_task(const os::SuspendedThreadTaskContext& context); 16.3993 +private: 16.3994 + ExtendedPC _epc; 16.3995 +}; 16.3996 + 16.3997 +ExtendedPC PcFetcher::result() { 16.3998 + guarantee(is_done(), "task is not done yet."); 16.3999 + return _epc; 16.4000 +} 16.4001 + 16.4002 +void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { 16.4003 + Thread* thread = context.thread(); 16.4004 + OSThread* osthread = thread->osthread(); 16.4005 + if (osthread->ucontext() != NULL) { 16.4006 + _epc = os::Aix::ucontext_get_pc((ucontext_t *) context.ucontext()); 16.4007 + } else { 16.4008 + // NULL context is unexpected, double-check this is the VMThread. 16.4009 + guarantee(thread->is_VM_thread(), "can only be called for VMThread"); 16.4010 + } 16.4011 +} 16.4012 + 16.4013 +// Suspends the target using the signal mechanism and then grabs the PC before 16.4014 +// resuming the target. Used by the flat-profiler only 16.4015 +ExtendedPC os::get_thread_pc(Thread* thread) { 16.4016 + // Make sure that it is called by the watcher for the VMThread. 16.4017 + assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); 16.4018 + assert(thread->is_VM_thread(), "Can only be called for VMThread"); 16.4019 + 16.4020 + PcFetcher fetcher(thread); 16.4021 + fetcher.run(); 16.4022 + return fetcher.result(); 16.4023 +} 16.4024 + 16.4025 +// Not neede on Aix. 16.4026 +// int os::Aix::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) { 16.4027 +// } 16.4028 + 16.4029 +//////////////////////////////////////////////////////////////////////////////// 16.4030 +// debug support 16.4031 + 16.4032 +static address same_page(address x, address y) { 16.4033 + intptr_t page_bits = -os::vm_page_size(); 16.4034 + if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) 16.4035 + return x; 16.4036 + else if (x > y) 16.4037 + return (address)(intptr_t(y) | ~page_bits) + 1; 16.4038 + else 16.4039 + return (address)(intptr_t(y) & page_bits); 16.4040 +} 16.4041 + 16.4042 +bool os::find(address addr, outputStream* st) { 16.4043 + Unimplemented(); 16.4044 + return false; 16.4045 +} 16.4046 + 16.4047 +//////////////////////////////////////////////////////////////////////////////// 16.4048 +// misc 16.4049 + 16.4050 +// This does not do anything on Aix. This is basically a hook for being 16.4051 +// able to use structured exception handling (thread-local exception filters) 16.4052 +// on, e.g., Win32. 16.4053 +void 16.4054 +os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, 16.4055 + JavaCallArguments* args, Thread* thread) { 16.4056 + f(value, method, args, thread); 16.4057 +} 16.4058 + 16.4059 +void os::print_statistics() { 16.4060 +} 16.4061 + 16.4062 +int os::message_box(const char* title, const char* message) { 16.4063 + int i; 16.4064 + fdStream err(defaultStream::error_fd()); 16.4065 + for (i = 0; i < 78; i++) err.print_raw("="); 16.4066 + err.cr(); 16.4067 + err.print_raw_cr(title); 16.4068 + for (i = 0; i < 78; i++) err.print_raw("-"); 16.4069 + err.cr(); 16.4070 + err.print_raw_cr(message); 16.4071 + for (i = 0; i < 78; i++) err.print_raw("="); 16.4072 + err.cr(); 16.4073 + 16.4074 + char buf[16]; 16.4075 + // Prevent process from exiting upon "read error" without consuming all CPU 16.4076 + while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); } 16.4077 + 16.4078 + return buf[0] == 'y' || buf[0] == 'Y'; 16.4079 +} 16.4080 + 16.4081 +int os::stat(const char *path, struct stat *sbuf) { 16.4082 + char pathbuf[MAX_PATH]; 16.4083 + if (strlen(path) > MAX_PATH - 1) { 16.4084 + errno = ENAMETOOLONG; 16.4085 + return -1; 16.4086 + } 16.4087 + os::native_path(strcpy(pathbuf, path)); 16.4088 + return ::stat(pathbuf, sbuf); 16.4089 +} 16.4090 + 16.4091 +bool os::check_heap(bool force) { 16.4092 + return true; 16.4093 +} 16.4094 + 16.4095 +// int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { 16.4096 +// return ::vsnprintf(buf, count, format, args); 16.4097 +// } 16.4098 + 16.4099 +// Is a (classpath) directory empty? 16.4100 +bool os::dir_is_empty(const char* path) { 16.4101 + Unimplemented(); 16.4102 + return false; 16.4103 +} 16.4104 + 16.4105 +// This code originates from JDK's sysOpen and open64_w 16.4106 +// from src/solaris/hpi/src/system_md.c 16.4107 + 16.4108 +#ifndef O_DELETE 16.4109 +#define O_DELETE 0x10000 16.4110 +#endif 16.4111 + 16.4112 +// Open a file. Unlink the file immediately after open returns 16.4113 +// if the specified oflag has the O_DELETE flag set. 16.4114 +// O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c 16.4115 + 16.4116 +int os::open(const char *path, int oflag, int mode) { 16.4117 + 16.4118 + if (strlen(path) > MAX_PATH - 1) { 16.4119 + errno = ENAMETOOLONG; 16.4120 + return -1; 16.4121 + } 16.4122 + int fd; 16.4123 + int o_delete = (oflag & O_DELETE); 16.4124 + oflag = oflag & ~O_DELETE; 16.4125 + 16.4126 + fd = ::open64(path, oflag, mode); 16.4127 + if (fd == -1) return -1; 16.4128 + 16.4129 + //If the open succeeded, the file might still be a directory 16.4130 + { 16.4131 + struct stat64 buf64; 16.4132 + int ret = ::fstat64(fd, &buf64); 16.4133 + int st_mode = buf64.st_mode; 16.4134 + 16.4135 + if (ret != -1) { 16.4136 + if ((st_mode & S_IFMT) == S_IFDIR) { 16.4137 + errno = EISDIR; 16.4138 + ::close(fd); 16.4139 + return -1; 16.4140 + } 16.4141 + } else { 16.4142 + ::close(fd); 16.4143 + return -1; 16.4144 + } 16.4145 + } 16.4146 + 16.4147 + // All file descriptors that are opened in the JVM and not 16.4148 + // specifically destined for a subprocess should have the 16.4149 + // close-on-exec flag set. If we don't set it, then careless 3rd 16.4150 + // party native code might fork and exec without closing all 16.4151 + // appropriate file descriptors (e.g. as we do in closeDescriptors in 16.4152 + // UNIXProcess.c), and this in turn might: 16.4153 + // 16.4154 + // - cause end-of-file to fail to be detected on some file 16.4155 + // descriptors, resulting in mysterious hangs, or 16.4156 + // 16.4157 + // - might cause an fopen in the subprocess to fail on a system 16.4158 + // suffering from bug 1085341. 16.4159 + // 16.4160 + // (Yes, the default setting of the close-on-exec flag is a Unix 16.4161 + // design flaw.) 16.4162 + // 16.4163 + // See: 16.4164 + // 1085341: 32-bit stdio routines should support file descriptors >255 16.4165 + // 4843136: (process) pipe file descriptor from Runtime.exec not being closed 16.4166 + // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 16.4167 +#ifdef FD_CLOEXEC 16.4168 + { 16.4169 + int flags = ::fcntl(fd, F_GETFD); 16.4170 + if (flags != -1) 16.4171 + ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 16.4172 + } 16.4173 +#endif 16.4174 + 16.4175 + if (o_delete != 0) { 16.4176 + ::unlink(path); 16.4177 + } 16.4178 + return fd; 16.4179 +} 16.4180 + 16.4181 + 16.4182 +// create binary file, rewriting existing file if required 16.4183 +int os::create_binary_file(const char* path, bool rewrite_existing) { 16.4184 + Unimplemented(); 16.4185 + return 0; 16.4186 +} 16.4187 + 16.4188 +// return current position of file pointer 16.4189 +jlong os::current_file_offset(int fd) { 16.4190 + return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); 16.4191 +} 16.4192 + 16.4193 +// move file pointer to the specified offset 16.4194 +jlong os::seek_to_file_offset(int fd, jlong offset) { 16.4195 + return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); 16.4196 +} 16.4197 + 16.4198 +// This code originates from JDK's sysAvailable 16.4199 +// from src/solaris/hpi/src/native_threads/src/sys_api_td.c 16.4200 + 16.4201 +int os::available(int fd, jlong *bytes) { 16.4202 + jlong cur, end; 16.4203 + int mode; 16.4204 + struct stat64 buf64; 16.4205 + 16.4206 + if (::fstat64(fd, &buf64) >= 0) { 16.4207 + mode = buf64.st_mode; 16.4208 + if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { 16.4209 + // XXX: is the following call interruptible? If so, this might 16.4210 + // need to go through the INTERRUPT_IO() wrapper as for other 16.4211 + // blocking, interruptible calls in this file. 16.4212 + int n; 16.4213 + if (::ioctl(fd, FIONREAD, &n) >= 0) { 16.4214 + *bytes = n; 16.4215 + return 1; 16.4216 + } 16.4217 + } 16.4218 + } 16.4219 + if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) { 16.4220 + return 0; 16.4221 + } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) { 16.4222 + return 0; 16.4223 + } else if (::lseek64(fd, cur, SEEK_SET) == -1) { 16.4224 + return 0; 16.4225 + } 16.4226 + *bytes = end - cur; 16.4227 + return 1; 16.4228 +} 16.4229 + 16.4230 +int os::socket_available(int fd, jint *pbytes) { 16.4231 + // Linux doc says EINTR not returned, unlike Solaris 16.4232 + int ret = ::ioctl(fd, FIONREAD, pbytes); 16.4233 + 16.4234 + //%% note ioctl can return 0 when successful, JVM_SocketAvailable 16.4235 + // is expected to return 0 on failure and 1 on success to the jdk. 16.4236 + return (ret < 0) ? 0 : 1; 16.4237 +} 16.4238 + 16.4239 +// Map a block of memory. 16.4240 +char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, 16.4241 + char *addr, size_t bytes, bool read_only, 16.4242 + bool allow_exec) { 16.4243 + Unimplemented(); 16.4244 + return NULL; 16.4245 +} 16.4246 + 16.4247 + 16.4248 +// Remap a block of memory. 16.4249 +char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, 16.4250 + char *addr, size_t bytes, bool read_only, 16.4251 + bool allow_exec) { 16.4252 + // same as map_memory() on this OS 16.4253 + return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, 16.4254 + allow_exec); 16.4255 +} 16.4256 + 16.4257 +// Unmap a block of memory. 16.4258 +bool os::pd_unmap_memory(char* addr, size_t bytes) { 16.4259 + return munmap(addr, bytes) == 0; 16.4260 +} 16.4261 + 16.4262 +// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) 16.4263 +// are used by JVM M&M and JVMTI to get user+sys or user CPU time 16.4264 +// of a thread. 16.4265 +// 16.4266 +// current_thread_cpu_time() and thread_cpu_time(Thread*) returns 16.4267 +// the fast estimate available on the platform. 16.4268 + 16.4269 +jlong os::current_thread_cpu_time() { 16.4270 + // return user + sys since the cost is the same 16.4271 + const jlong n = os::thread_cpu_time(Thread::current(), true /* user + sys */); 16.4272 + assert(n >= 0, "negative CPU time"); 16.4273 + return n; 16.4274 +} 16.4275 + 16.4276 +jlong os::thread_cpu_time(Thread* thread) { 16.4277 + // consistent with what current_thread_cpu_time() returns 16.4278 + const jlong n = os::thread_cpu_time(thread, true /* user + sys */); 16.4279 + assert(n >= 0, "negative CPU time"); 16.4280 + return n; 16.4281 +} 16.4282 + 16.4283 +jlong os::current_thread_cpu_time(bool user_sys_cpu_time) { 16.4284 + const jlong n = os::thread_cpu_time(Thread::current(), user_sys_cpu_time); 16.4285 + assert(n >= 0, "negative CPU time"); 16.4286 + return n; 16.4287 +} 16.4288 + 16.4289 +static bool thread_cpu_time_unchecked(Thread* thread, jlong* p_sys_time, jlong* p_user_time) { 16.4290 + bool error = false; 16.4291 + 16.4292 + jlong sys_time = 0; 16.4293 + jlong user_time = 0; 16.4294 + 16.4295 + // reimplemented using getthrds64(). 16.4296 + // 16.4297 + // goes like this: 16.4298 + // For the thread in question, get the kernel thread id. Then get the 16.4299 + // kernel thread statistics using that id. 16.4300 + // 16.4301 + // This only works of course when no pthread scheduling is used, 16.4302 + // ie there is a 1:1 relationship to kernel threads. 16.4303 + // On AIX, see AIXTHREAD_SCOPE variable. 16.4304 + 16.4305 + pthread_t pthtid = thread->osthread()->pthread_id(); 16.4306 + 16.4307 + // retrieve kernel thread id for the pthread: 16.4308 + tid64_t tid = 0; 16.4309 + struct __pthrdsinfo pinfo; 16.4310 + // I just love those otherworldly IBM APIs which force me to hand down 16.4311 + // dummy buffers for stuff I dont care for... 16.4312 + char dummy[1]; 16.4313 + int dummy_size = sizeof(dummy); 16.4314 + if (pthread_getthrds_np(&pthtid, PTHRDSINFO_QUERY_TID, &pinfo, sizeof(pinfo), 16.4315 + dummy, &dummy_size) == 0) { 16.4316 + tid = pinfo.__pi_tid; 16.4317 + } else { 16.4318 + tty->print_cr("pthread_getthrds_np failed."); 16.4319 + error = true; 16.4320 + } 16.4321 + 16.4322 + // retrieve kernel timing info for that kernel thread 16.4323 + if (!error) { 16.4324 + struct thrdentry64 thrdentry; 16.4325 + if (getthrds64(getpid(), &thrdentry, sizeof(thrdentry), &tid, 1) == 1) { 16.4326 + sys_time = thrdentry.ti_ru.ru_stime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_stime.tv_usec * 1000LL; 16.4327 + user_time = thrdentry.ti_ru.ru_utime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_utime.tv_usec * 1000LL; 16.4328 + } else { 16.4329 + tty->print_cr("pthread_getthrds_np failed."); 16.4330 + error = true; 16.4331 + } 16.4332 + } 16.4333 + 16.4334 + if (p_sys_time) { 16.4335 + *p_sys_time = sys_time; 16.4336 + } 16.4337 + 16.4338 + if (p_user_time) { 16.4339 + *p_user_time = user_time; 16.4340 + } 16.4341 + 16.4342 + if (error) { 16.4343 + return false; 16.4344 + } 16.4345 + 16.4346 + return true; 16.4347 +} 16.4348 + 16.4349 +jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { 16.4350 + jlong sys_time; 16.4351 + jlong user_time; 16.4352 + 16.4353 + if (!thread_cpu_time_unchecked(thread, &sys_time, &user_time)) { 16.4354 + return -1; 16.4355 + } 16.4356 + 16.4357 + return user_sys_cpu_time ? sys_time + user_time : user_time; 16.4358 +} 16.4359 + 16.4360 +void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { 16.4361 + info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits 16.4362 + info_ptr->may_skip_backward = false; // elapsed time not wall time 16.4363 + info_ptr->may_skip_forward = false; // elapsed time not wall time 16.4364 + info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned 16.4365 +} 16.4366 + 16.4367 +void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { 16.4368 + info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits 16.4369 + info_ptr->may_skip_backward = false; // elapsed time not wall time 16.4370 + info_ptr->may_skip_forward = false; // elapsed time not wall time 16.4371 + info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned 16.4372 +} 16.4373 + 16.4374 +bool os::is_thread_cpu_time_supported() { 16.4375 + return true; 16.4376 +} 16.4377 + 16.4378 +// System loadavg support. Returns -1 if load average cannot be obtained. 16.4379 +// For now just return the system wide load average (no processor sets). 16.4380 +int os::loadavg(double values[], int nelem) { 16.4381 + 16.4382 + // Implemented using libperfstat on AIX. 16.4383 + 16.4384 + guarantee(nelem >= 0 && nelem <= 3, "argument error"); 16.4385 + guarantee(values, "argument error"); 16.4386 + 16.4387 + if (os::Aix::on_pase()) { 16.4388 + Unimplemented(); 16.4389 + return -1; 16.4390 + } else { 16.4391 + // AIX: use libperfstat 16.4392 + // 16.4393 + // See also: 16.4394 + // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/perfstat_cputot.htm 16.4395 + // /usr/include/libperfstat.h: 16.4396 + 16.4397 + // Use the already AIX version independent get_cpuinfo. 16.4398 + os::Aix::cpuinfo_t ci; 16.4399 + if (os::Aix::get_cpuinfo(&ci)) { 16.4400 + for (int i = 0; i < nelem; i++) { 16.4401 + values[i] = ci.loadavg[i]; 16.4402 + } 16.4403 + } else { 16.4404 + return -1; 16.4405 + } 16.4406 + return nelem; 16.4407 + } 16.4408 +} 16.4409 + 16.4410 +void os::pause() { 16.4411 + char filename[MAX_PATH]; 16.4412 + if (PauseAtStartupFile && PauseAtStartupFile[0]) { 16.4413 + jio_snprintf(filename, MAX_PATH, PauseAtStartupFile); 16.4414 + } else { 16.4415 + jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id()); 16.4416 + } 16.4417 + 16.4418 + int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); 16.4419 + if (fd != -1) { 16.4420 + struct stat buf; 16.4421 + ::close(fd); 16.4422 + while (::stat(filename, &buf) == 0) { 16.4423 + (void)::poll(NULL, 0, 100); 16.4424 + } 16.4425 + } else { 16.4426 + jio_fprintf(stderr, 16.4427 + "Could not open pause file '%s', continuing immediately.\n", filename); 16.4428 + } 16.4429 +} 16.4430 + 16.4431 +bool os::Aix::is_primordial_thread() { 16.4432 + if (pthread_self() == (pthread_t)1) { 16.4433 + return true; 16.4434 + } else { 16.4435 + return false; 16.4436 + } 16.4437 +} 16.4438 + 16.4439 +// OS recognitions (PASE/AIX, OS level) call this before calling any 16.4440 +// one of Aix::on_pase(), Aix::os_version() static 16.4441 +void os::Aix::initialize_os_info() { 16.4442 + 16.4443 + assert(_on_pase == -1 && _os_version == -1, "already called."); 16.4444 + 16.4445 + struct utsname uts; 16.4446 + memset(&uts, 0, sizeof(uts)); 16.4447 + strcpy(uts.sysname, "?"); 16.4448 + if (::uname(&uts) == -1) { 16.4449 + fprintf(stderr, "uname failed (%d)\n", errno); 16.4450 + guarantee(0, "Could not determine whether we run on AIX or PASE"); 16.4451 + } else { 16.4452 + if (Verbose) { 16.4453 + fprintf(stderr,"uname says: sysname \"%s\" version \"%s\" release \"%s\" " 16.4454 + "node \"%s\" machine \"%s\"\n", 16.4455 + uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); 16.4456 + } 16.4457 + const int major = atoi(uts.version); 16.4458 + assert(major > 0, "invalid OS version"); 16.4459 + const int minor = atoi(uts.release); 16.4460 + assert(minor > 0, "invalid OS release"); 16.4461 + _os_version = (major << 8) | minor; 16.4462 + if (strcmp(uts.sysname, "OS400") == 0) { 16.4463 + Unimplemented(); 16.4464 + } else if (strcmp(uts.sysname, "AIX") == 0) { 16.4465 + // We run on AIX. We do not support versions older than AIX 5.3. 16.4466 + _on_pase = 0; 16.4467 + if (_os_version < 0x0503) { 16.4468 + fprintf(stderr, "AIX release older than AIX 5.3 not supported.\n"); 16.4469 + assert(false, "AIX release too old."); 16.4470 + } else { 16.4471 + if (Verbose) { 16.4472 + fprintf(stderr, "We run on AIX %d.%d\n", major, minor); 16.4473 + } 16.4474 + } 16.4475 + } else { 16.4476 + assert(false, "unknown OS"); 16.4477 + } 16.4478 + } 16.4479 + 16.4480 + guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release"); 16.4481 + 16.4482 +} // end: os::Aix::initialize_os_info() 16.4483 + 16.4484 +// Scan environment for important settings which might effect the VM. 16.4485 +// Trace out settings. Warn about invalid settings and/or correct them. 16.4486 +// 16.4487 +// Must run after os::Aix::initialue_os_info(). 16.4488 +void os::Aix::scan_environment() { 16.4489 + 16.4490 + char* p; 16.4491 + int rc; 16.4492 + 16.4493 + // Warn explicity if EXTSHM=ON is used. That switch changes how 16.4494 + // System V shared memory behaves. One effect is that page size of 16.4495 + // shared memory cannot be change dynamically, effectivly preventing 16.4496 + // large pages from working. 16.4497 + // This switch was needed on AIX 32bit, but on AIX 64bit the general 16.4498 + // recommendation is (in OSS notes) to switch it off. 16.4499 + p = ::getenv("EXTSHM"); 16.4500 + if (Verbose) { 16.4501 + fprintf(stderr, "EXTSHM=%s.\n", p ? p : "<unset>"); 16.4502 + } 16.4503 + if (p && strcmp(p, "ON") == 0) { 16.4504 + fprintf(stderr, "Unsupported setting: EXTSHM=ON. Large Page support will be disabled.\n"); 16.4505 + _extshm = 1; 16.4506 + } else { 16.4507 + _extshm = 0; 16.4508 + } 16.4509 + 16.4510 + // SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs. 16.4511 + // Not tested, not supported. 16.4512 + // 16.4513 + // Note that it might be worth the trouble to test and to require it, if only to 16.4514 + // get useful return codes for mprotect. 16.4515 + // 16.4516 + // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before 16.4517 + // exec() ? before loading the libjvm ? ....) 16.4518 + p = ::getenv("XPG_SUS_ENV"); 16.4519 + if (Verbose) { 16.4520 + fprintf(stderr, "XPG_SUS_ENV=%s.\n", p ? p : "<unset>"); 16.4521 + } 16.4522 + if (p && strcmp(p, "ON") == 0) { 16.4523 + _xpg_sus_mode = 1; 16.4524 + fprintf(stderr, "Unsupported setting: XPG_SUS_ENV=ON\n"); 16.4525 + // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to 16.4526 + // clobber address ranges. If we ever want to support that, we have to do some 16.4527 + // testing first. 16.4528 + guarantee(false, "XPG_SUS_ENV=ON not supported"); 16.4529 + } else { 16.4530 + _xpg_sus_mode = 0; 16.4531 + } 16.4532 + 16.4533 + // Switch off AIX internal (pthread) guard pages. This has 16.4534 + // immediate effect for any pthread_create calls which follow. 16.4535 + p = ::getenv("AIXTHREAD_GUARDPAGES"); 16.4536 + if (Verbose) { 16.4537 + fprintf(stderr, "AIXTHREAD_GUARDPAGES=%s.\n", p ? p : "<unset>"); 16.4538 + fprintf(stderr, "setting AIXTHREAD_GUARDPAGES=0.\n"); 16.4539 + } 16.4540 + rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); 16.4541 + guarantee(rc == 0, ""); 16.4542 + 16.4543 +} // end: os::Aix::scan_environment() 16.4544 + 16.4545 +// PASE: initialize the libo4 library (AS400 PASE porting library). 16.4546 +void os::Aix::initialize_libo4() { 16.4547 + Unimplemented(); 16.4548 +} 16.4549 + 16.4550 +// AIX: initialize the libperfstat library (we load this dynamically 16.4551 +// because it is only available on AIX. 16.4552 +void os::Aix::initialize_libperfstat() { 16.4553 + 16.4554 + assert(os::Aix::on_aix(), "AIX only"); 16.4555 + 16.4556 + if (!libperfstat::init()) { 16.4557 + fprintf(stderr, "libperfstat initialization failed.\n"); 16.4558 + assert(false, "libperfstat initialization failed"); 16.4559 + } else { 16.4560 + if (Verbose) { 16.4561 + fprintf(stderr, "libperfstat initialized.\n"); 16.4562 + } 16.4563 + } 16.4564 +} // end: os::Aix::initialize_libperfstat 16.4565 + 16.4566 +///////////////////////////////////////////////////////////////////////////// 16.4567 +// thread stack 16.4568 + 16.4569 +// function to query the current stack size using pthread_getthrds_np 16.4570 +// 16.4571 +// ! do not change anything here unless you know what you are doing ! 16.4572 +static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) { 16.4573 + 16.4574 + // This only works when invoked on a pthread. As we agreed not to use 16.4575 + // primordial threads anyway, I assert here 16.4576 + guarantee(!os::Aix::is_primordial_thread(), "not allowed on the primordial thread"); 16.4577 + 16.4578 + // information about this api can be found (a) in the pthread.h header and 16.4579 + // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm 16.4580 + // 16.4581 + // The use of this API to find out the current stack is kind of undefined. 16.4582 + // But after a lot of tries and asking IBM about it, I concluded that it is safe 16.4583 + // enough for cases where I let the pthread library create its stacks. For cases 16.4584 + // where I create an own stack and pass this to pthread_create, it seems not to 16.4585 + // work (the returned stack size in that case is 0). 16.4586 + 16.4587 + pthread_t tid = pthread_self(); 16.4588 + struct __pthrdsinfo pinfo; 16.4589 + char dummy[1]; // we only need this to satisfy the api and to not get E 16.4590 + int dummy_size = sizeof(dummy); 16.4591 + 16.4592 + memset(&pinfo, 0, sizeof(pinfo)); 16.4593 + 16.4594 + const int rc = pthread_getthrds_np (&tid, PTHRDSINFO_QUERY_ALL, &pinfo, 16.4595 + sizeof(pinfo), dummy, &dummy_size); 16.4596 + 16.4597 + if (rc != 0) { 16.4598 + fprintf(stderr, "pthread_getthrds_np failed (%d)\n", rc); 16.4599 + guarantee(0, "pthread_getthrds_np failed"); 16.4600 + } 16.4601 + 16.4602 + guarantee(pinfo.__pi_stackend, "returned stack base invalid"); 16.4603 + 16.4604 + // the following can happen when invoking pthread_getthrds_np on a pthread running on a user provided stack 16.4605 + // (when handing down a stack to pthread create, see pthread_attr_setstackaddr). 16.4606 + // Not sure what to do here - I feel inclined to forbid this use case completely. 16.4607 + guarantee(pinfo.__pi_stacksize, "returned stack size invalid"); 16.4608 + 16.4609 + // On AIX, stacks are not necessarily page aligned so round the base and size accordingly 16.4610 + if (p_stack_base) { 16.4611 + (*p_stack_base) = (address) align_size_up((intptr_t)pinfo.__pi_stackend, os::Aix::stack_page_size()); 16.4612 + } 16.4613 + 16.4614 + if (p_stack_size) { 16.4615 + (*p_stack_size) = pinfo.__pi_stacksize - os::Aix::stack_page_size(); 16.4616 + } 16.4617 + 16.4618 +#ifndef PRODUCT 16.4619 + if (Verbose) { 16.4620 + fprintf(stderr, 16.4621 + "query_stack_dimensions() -> real stack_base=" INTPTR_FORMAT ", real stack_addr=" INTPTR_FORMAT 16.4622 + ", real stack_size=" INTPTR_FORMAT 16.4623 + ", stack_base=" INTPTR_FORMAT ", stack_size=" INTPTR_FORMAT "\n", 16.4624 + (intptr_t)pinfo.__pi_stackend, (intptr_t)pinfo.__pi_stackaddr, pinfo.__pi_stacksize, 16.4625 + (intptr_t)align_size_up((intptr_t)pinfo.__pi_stackend, os::Aix::stack_page_size()), 16.4626 + pinfo.__pi_stacksize - os::Aix::stack_page_size()); 16.4627 + } 16.4628 +#endif 16.4629 + 16.4630 +} // end query_stack_dimensions 16.4631 + 16.4632 +// get the current stack base from the OS (actually, the pthread library) 16.4633 +address os::current_stack_base() { 16.4634 + address p; 16.4635 + query_stack_dimensions(&p, 0); 16.4636 + return p; 16.4637 +} 16.4638 + 16.4639 +// get the current stack size from the OS (actually, the pthread library) 16.4640 +size_t os::current_stack_size() { 16.4641 + size_t s; 16.4642 + query_stack_dimensions(0, &s); 16.4643 + return s; 16.4644 +} 16.4645 + 16.4646 +// Refer to the comments in os_solaris.cpp park-unpark. 16.4647 +// 16.4648 +// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can 16.4649 +// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. 16.4650 +// For specifics regarding the bug see GLIBC BUGID 261237 : 16.4651 +// http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. 16.4652 +// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future 16.4653 +// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar 16.4654 +// is used. (The simple C test-case provided in the GLIBC bug report manifests the 16.4655 +// hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos() 16.4656 +// and monitorenter when we're using 1-0 locking. All those operations may result in 16.4657 +// calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version 16.4658 +// of libpthread avoids the problem, but isn't practical. 16.4659 +// 16.4660 +// Possible remedies: 16.4661 +// 16.4662 +// 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work. 16.4663 +// This is palliative and probabilistic, however. If the thread is preempted 16.4664 +// between the call to compute_abstime() and pthread_cond_timedwait(), more 16.4665 +// than the minimum period may have passed, and the abstime may be stale (in the 16.4666 +// past) resultin in a hang. Using this technique reduces the odds of a hang 16.4667 +// but the JVM is still vulnerable, particularly on heavily loaded systems. 16.4668 +// 16.4669 +// 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead 16.4670 +// of the usual flag-condvar-mutex idiom. The write side of the pipe is set 16.4671 +// NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo) 16.4672 +// reduces to poll()+read(). This works well, but consumes 2 FDs per extant 16.4673 +// thread. 16.4674 +// 16.4675 +// 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread 16.4676 +// that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing 16.4677 +// a timeout request to the chron thread and then blocking via pthread_cond_wait(). 16.4678 +// This also works well. In fact it avoids kernel-level scalability impediments 16.4679 +// on certain platforms that don't handle lots of active pthread_cond_timedwait() 16.4680 +// timers in a graceful fashion. 16.4681 +// 16.4682 +// 4. When the abstime value is in the past it appears that control returns 16.4683 +// correctly from pthread_cond_timedwait(), but the condvar is left corrupt. 16.4684 +// Subsequent timedwait/wait calls may hang indefinitely. Given that, we 16.4685 +// can avoid the problem by reinitializing the condvar -- by cond_destroy() 16.4686 +// followed by cond_init() -- after all calls to pthread_cond_timedwait(). 16.4687 +// It may be possible to avoid reinitialization by checking the return 16.4688 +// value from pthread_cond_timedwait(). In addition to reinitializing the 16.4689 +// condvar we must establish the invariant that cond_signal() is only called 16.4690 +// within critical sections protected by the adjunct mutex. This prevents 16.4691 +// cond_signal() from "seeing" a condvar that's in the midst of being 16.4692 +// reinitialized or that is corrupt. Sadly, this invariant obviates the 16.4693 +// desirable signal-after-unlock optimization that avoids futile context switching. 16.4694 +// 16.4695 +// I'm also concerned that some versions of NTPL might allocate an auxilliary 16.4696 +// structure when a condvar is used or initialized. cond_destroy() would 16.4697 +// release the helper structure. Our reinitialize-after-timedwait fix 16.4698 +// put excessive stress on malloc/free and locks protecting the c-heap. 16.4699 +// 16.4700 +// We currently use (4). See the WorkAroundNTPLTimedWaitHang flag. 16.4701 +// It may be possible to refine (4) by checking the kernel and NTPL verisons 16.4702 +// and only enabling the work-around for vulnerable environments. 16.4703 + 16.4704 +// utility to compute the abstime argument to timedwait: 16.4705 +// millis is the relative timeout time 16.4706 +// abstime will be the absolute timeout time 16.4707 +// TODO: replace compute_abstime() with unpackTime() 16.4708 + 16.4709 +static struct timespec* compute_abstime(timespec* abstime, jlong millis) { 16.4710 + if (millis < 0) millis = 0; 16.4711 + struct timeval now; 16.4712 + int status = gettimeofday(&now, NULL); 16.4713 + assert(status == 0, "gettimeofday"); 16.4714 + jlong seconds = millis / 1000; 16.4715 + millis %= 1000; 16.4716 + if (seconds > 50000000) { // see man cond_timedwait(3T) 16.4717 + seconds = 50000000; 16.4718 + } 16.4719 + abstime->tv_sec = now.tv_sec + seconds; 16.4720 + long usec = now.tv_usec + millis * 1000; 16.4721 + if (usec >= 1000000) { 16.4722 + abstime->tv_sec += 1; 16.4723 + usec -= 1000000; 16.4724 + } 16.4725 + abstime->tv_nsec = usec * 1000; 16.4726 + return abstime; 16.4727 +} 16.4728 + 16.4729 + 16.4730 +// Test-and-clear _Event, always leaves _Event set to 0, returns immediately. 16.4731 +// Conceptually TryPark() should be equivalent to park(0). 16.4732 + 16.4733 +int os::PlatformEvent::TryPark() { 16.4734 + for (;;) { 16.4735 + const int v = _Event; 16.4736 + guarantee ((v == 0) || (v == 1), "invariant"); 16.4737 + if (Atomic::cmpxchg (0, &_Event, v) == v) return v; 16.4738 + } 16.4739 +} 16.4740 + 16.4741 +void os::PlatformEvent::park() { // AKA "down()" 16.4742 + // Invariant: Only the thread associated with the Event/PlatformEvent 16.4743 + // may call park(). 16.4744 + // TODO: assert that _Assoc != NULL or _Assoc == Self 16.4745 + int v; 16.4746 + for (;;) { 16.4747 + v = _Event; 16.4748 + if (Atomic::cmpxchg (v-1, &_Event, v) == v) break; 16.4749 + } 16.4750 + guarantee (v >= 0, "invariant"); 16.4751 + if (v == 0) { 16.4752 + // Do this the hard way by blocking ... 16.4753 + int status = pthread_mutex_lock(_mutex); 16.4754 + assert_status(status == 0, status, "mutex_lock"); 16.4755 + guarantee (_nParked == 0, "invariant"); 16.4756 + ++ _nParked; 16.4757 + while (_Event < 0) { 16.4758 + status = pthread_cond_wait(_cond, _mutex); 16.4759 + assert_status(status == 0 || status == ETIMEDOUT, status, "cond_timedwait"); 16.4760 + } 16.4761 + -- _nParked; 16.4762 + 16.4763 + // In theory we could move the ST of 0 into _Event past the unlock(), 16.4764 + // but then we'd need a MEMBAR after the ST. 16.4765 + _Event = 0; 16.4766 + status = pthread_mutex_unlock(_mutex); 16.4767 + assert_status(status == 0, status, "mutex_unlock"); 16.4768 + } 16.4769 + guarantee (_Event >= 0, "invariant"); 16.4770 +} 16.4771 + 16.4772 +int os::PlatformEvent::park(jlong millis) { 16.4773 + guarantee (_nParked == 0, "invariant"); 16.4774 + 16.4775 + int v; 16.4776 + for (;;) { 16.4777 + v = _Event; 16.4778 + if (Atomic::cmpxchg (v-1, &_Event, v) == v) break; 16.4779 + } 16.4780 + guarantee (v >= 0, "invariant"); 16.4781 + if (v != 0) return OS_OK; 16.4782 + 16.4783 + // We do this the hard way, by blocking the thread. 16.4784 + // Consider enforcing a minimum timeout value. 16.4785 + struct timespec abst; 16.4786 + compute_abstime(&abst, millis); 16.4787 + 16.4788 + int ret = OS_TIMEOUT; 16.4789 + int status = pthread_mutex_lock(_mutex); 16.4790 + assert_status(status == 0, status, "mutex_lock"); 16.4791 + guarantee (_nParked == 0, "invariant"); 16.4792 + ++_nParked; 16.4793 + 16.4794 + // Object.wait(timo) will return because of 16.4795 + // (a) notification 16.4796 + // (b) timeout 16.4797 + // (c) thread.interrupt 16.4798 + // 16.4799 + // Thread.interrupt and object.notify{All} both call Event::set. 16.4800 + // That is, we treat thread.interrupt as a special case of notification. 16.4801 + // The underlying Solaris implementation, cond_timedwait, admits 16.4802 + // spurious/premature wakeups, but the JLS/JVM spec prevents the 16.4803 + // JVM from making those visible to Java code. As such, we must 16.4804 + // filter out spurious wakeups. We assume all ETIME returns are valid. 16.4805 + // 16.4806 + // TODO: properly differentiate simultaneous notify+interrupt. 16.4807 + // In that case, we should propagate the notify to another waiter. 16.4808 + 16.4809 + while (_Event < 0) { 16.4810 + status = pthread_cond_timedwait(_cond, _mutex, &abst); 16.4811 + assert_status(status == 0 || status == ETIMEDOUT, 16.4812 + status, "cond_timedwait"); 16.4813 + if (!FilterSpuriousWakeups) break; // previous semantics 16.4814 + if (status == ETIMEDOUT) break; 16.4815 + // We consume and ignore EINTR and spurious wakeups. 16.4816 + } 16.4817 + --_nParked; 16.4818 + if (_Event >= 0) { 16.4819 + ret = OS_OK; 16.4820 + } 16.4821 + _Event = 0; 16.4822 + status = pthread_mutex_unlock(_mutex); 16.4823 + assert_status(status == 0, status, "mutex_unlock"); 16.4824 + assert (_nParked == 0, "invariant"); 16.4825 + return ret; 16.4826 +} 16.4827 + 16.4828 +void os::PlatformEvent::unpark() { 16.4829 + int v, AnyWaiters; 16.4830 + for (;;) { 16.4831 + v = _Event; 16.4832 + if (v > 0) { 16.4833 + // The LD of _Event could have reordered or be satisfied 16.4834 + // by a read-aside from this processor's write buffer. 16.4835 + // To avoid problems execute a barrier and then 16.4836 + // ratify the value. 16.4837 + OrderAccess::fence(); 16.4838 + if (_Event == v) return; 16.4839 + continue; 16.4840 + } 16.4841 + if (Atomic::cmpxchg (v+1, &_Event, v) == v) break; 16.4842 + } 16.4843 + if (v < 0) { 16.4844 + // Wait for the thread associated with the event to vacate 16.4845 + int status = pthread_mutex_lock(_mutex); 16.4846 + assert_status(status == 0, status, "mutex_lock"); 16.4847 + AnyWaiters = _nParked; 16.4848 + 16.4849 + if (AnyWaiters != 0) { 16.4850 + // We intentional signal *after* dropping the lock 16.4851 + // to avoid a common class of futile wakeups. 16.4852 + status = pthread_cond_signal(_cond); 16.4853 + assert_status(status == 0, status, "cond_signal"); 16.4854 + } 16.4855 + // Mutex should be locked for pthread_cond_signal(_cond). 16.4856 + status = pthread_mutex_unlock(_mutex); 16.4857 + assert_status(status == 0, status, "mutex_unlock"); 16.4858 + } 16.4859 + 16.4860 + // Note that we signal() _after dropping the lock for "immortal" Events. 16.4861 + // This is safe and avoids a common class of futile wakeups. In rare 16.4862 + // circumstances this can cause a thread to return prematurely from 16.4863 + // cond_{timed}wait() but the spurious wakeup is benign and the victim will 16.4864 + // simply re-test the condition and re-park itself. 16.4865 +} 16.4866 + 16.4867 + 16.4868 +// JSR166 16.4869 +// ------------------------------------------------------- 16.4870 + 16.4871 +// 16.4872 +// The solaris and linux implementations of park/unpark are fairly 16.4873 +// conservative for now, but can be improved. They currently use a 16.4874 +// mutex/condvar pair, plus a a count. 16.4875 +// Park decrements count if > 0, else does a condvar wait. Unpark 16.4876 +// sets count to 1 and signals condvar. Only one thread ever waits 16.4877 +// on the condvar. Contention seen when trying to park implies that someone 16.4878 +// is unparking you, so don't wait. And spurious returns are fine, so there 16.4879 +// is no need to track notifications. 16.4880 +// 16.4881 + 16.4882 +#define MAX_SECS 100000000 16.4883 +// 16.4884 +// This code is common to linux and solaris and will be moved to a 16.4885 +// common place in dolphin. 16.4886 +// 16.4887 +// The passed in time value is either a relative time in nanoseconds 16.4888 +// or an absolute time in milliseconds. Either way it has to be unpacked 16.4889 +// into suitable seconds and nanoseconds components and stored in the 16.4890 +// given timespec structure. 16.4891 +// Given time is a 64-bit value and the time_t used in the timespec is only 16.4892 +// a signed-32-bit value (except on 64-bit Linux) we have to watch for 16.4893 +// overflow if times way in the future are given. Further on Solaris versions 16.4894 +// prior to 10 there is a restriction (see cond_timedwait) that the specified 16.4895 +// number of seconds, in abstime, is less than current_time + 100,000,000. 16.4896 +// As it will be 28 years before "now + 100000000" will overflow we can 16.4897 +// ignore overflow and just impose a hard-limit on seconds using the value 16.4898 +// of "now + 100,000,000". This places a limit on the timeout of about 3.17 16.4899 +// years from "now". 16.4900 +// 16.4901 + 16.4902 +static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { 16.4903 + assert (time > 0, "convertTime"); 16.4904 + 16.4905 + struct timeval now; 16.4906 + int status = gettimeofday(&now, NULL); 16.4907 + assert(status == 0, "gettimeofday"); 16.4908 + 16.4909 + time_t max_secs = now.tv_sec + MAX_SECS; 16.4910 + 16.4911 + if (isAbsolute) { 16.4912 + jlong secs = time / 1000; 16.4913 + if (secs > max_secs) { 16.4914 + absTime->tv_sec = max_secs; 16.4915 + } 16.4916 + else { 16.4917 + absTime->tv_sec = secs; 16.4918 + } 16.4919 + absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; 16.4920 + } 16.4921 + else { 16.4922 + jlong secs = time / NANOSECS_PER_SEC; 16.4923 + if (secs >= MAX_SECS) { 16.4924 + absTime->tv_sec = max_secs; 16.4925 + absTime->tv_nsec = 0; 16.4926 + } 16.4927 + else { 16.4928 + absTime->tv_sec = now.tv_sec + secs; 16.4929 + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; 16.4930 + if (absTime->tv_nsec >= NANOSECS_PER_SEC) { 16.4931 + absTime->tv_nsec -= NANOSECS_PER_SEC; 16.4932 + ++absTime->tv_sec; // note: this must be <= max_secs 16.4933 + } 16.4934 + } 16.4935 + } 16.4936 + assert(absTime->tv_sec >= 0, "tv_sec < 0"); 16.4937 + assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); 16.4938 + assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); 16.4939 + assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); 16.4940 +} 16.4941 + 16.4942 +void Parker::park(bool isAbsolute, jlong time) { 16.4943 + // Optional fast-path check: 16.4944 + // Return immediately if a permit is available. 16.4945 + if (_counter > 0) { 16.4946 + _counter = 0; 16.4947 + OrderAccess::fence(); 16.4948 + return; 16.4949 + } 16.4950 + 16.4951 + Thread* thread = Thread::current(); 16.4952 + assert(thread->is_Java_thread(), "Must be JavaThread"); 16.4953 + JavaThread *jt = (JavaThread *)thread; 16.4954 + 16.4955 + // Optional optimization -- avoid state transitions if there's an interrupt pending. 16.4956 + // Check interrupt before trying to wait 16.4957 + if (Thread::is_interrupted(thread, false)) { 16.4958 + return; 16.4959 + } 16.4960 + 16.4961 + // Next, demultiplex/decode time arguments 16.4962 + timespec absTime; 16.4963 + if (time < 0 || (isAbsolute && time == 0)) { // don't wait at all 16.4964 + return; 16.4965 + } 16.4966 + if (time > 0) { 16.4967 + unpackTime(&absTime, isAbsolute, time); 16.4968 + } 16.4969 + 16.4970 + 16.4971 + // Enter safepoint region 16.4972 + // Beware of deadlocks such as 6317397. 16.4973 + // The per-thread Parker:: mutex is a classic leaf-lock. 16.4974 + // In particular a thread must never block on the Threads_lock while 16.4975 + // holding the Parker:: mutex. If safepoints are pending both the 16.4976 + // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. 16.4977 + ThreadBlockInVM tbivm(jt); 16.4978 + 16.4979 + // Don't wait if cannot get lock since interference arises from 16.4980 + // unblocking. Also. check interrupt before trying wait 16.4981 + if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { 16.4982 + return; 16.4983 + } 16.4984 + 16.4985 + int status; 16.4986 + if (_counter > 0) { // no wait needed 16.4987 + _counter = 0; 16.4988 + status = pthread_mutex_unlock(_mutex); 16.4989 + assert (status == 0, "invariant"); 16.4990 + OrderAccess::fence(); 16.4991 + return; 16.4992 + } 16.4993 + 16.4994 +#ifdef ASSERT 16.4995 + // Don't catch signals while blocked; let the running threads have the signals. 16.4996 + // (This allows a debugger to break into the running thread.) 16.4997 + sigset_t oldsigs; 16.4998 + sigset_t* allowdebug_blocked = os::Aix::allowdebug_blocked_signals(); 16.4999 + pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); 16.5000 +#endif 16.5001 + 16.5002 + OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); 16.5003 + jt->set_suspend_equivalent(); 16.5004 + // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 16.5005 + 16.5006 + if (time == 0) { 16.5007 + status = pthread_cond_wait (_cond, _mutex); 16.5008 + } else { 16.5009 + status = pthread_cond_timedwait (_cond, _mutex, &absTime); 16.5010 + if (status != 0 && WorkAroundNPTLTimedWaitHang) { 16.5011 + pthread_cond_destroy (_cond); 16.5012 + pthread_cond_init (_cond, NULL); 16.5013 + } 16.5014 + } 16.5015 + assert_status(status == 0 || status == EINTR || 16.5016 + status == ETIME || status == ETIMEDOUT, 16.5017 + status, "cond_timedwait"); 16.5018 + 16.5019 +#ifdef ASSERT 16.5020 + pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); 16.5021 +#endif 16.5022 + 16.5023 + _counter = 0; 16.5024 + status = pthread_mutex_unlock(_mutex); 16.5025 + assert_status(status == 0, status, "invariant"); 16.5026 + // If externally suspended while waiting, re-suspend 16.5027 + if (jt->handle_special_suspend_equivalent_condition()) { 16.5028 + jt->java_suspend_self(); 16.5029 + } 16.5030 + 16.5031 + OrderAccess::fence(); 16.5032 +} 16.5033 + 16.5034 +void Parker::unpark() { 16.5035 + int s, status; 16.5036 + status = pthread_mutex_lock(_mutex); 16.5037 + assert (status == 0, "invariant"); 16.5038 + s = _counter; 16.5039 + _counter = 1; 16.5040 + if (s < 1) { 16.5041 + if (WorkAroundNPTLTimedWaitHang) { 16.5042 + status = pthread_cond_signal (_cond); 16.5043 + assert (status == 0, "invariant"); 16.5044 + status = pthread_mutex_unlock(_mutex); 16.5045 + assert (status == 0, "invariant"); 16.5046 + } else { 16.5047 + status = pthread_mutex_unlock(_mutex); 16.5048 + assert (status == 0, "invariant"); 16.5049 + status = pthread_cond_signal (_cond); 16.5050 + assert (status == 0, "invariant"); 16.5051 + } 16.5052 + } else { 16.5053 + pthread_mutex_unlock(_mutex); 16.5054 + assert (status == 0, "invariant"); 16.5055 + } 16.5056 +} 16.5057 + 16.5058 + 16.5059 +extern char** environ; 16.5060 + 16.5061 +// Run the specified command in a separate process. Return its exit value, 16.5062 +// or -1 on failure (e.g. can't fork a new process). 16.5063 +// Unlike system(), this function can be called from signal handler. It 16.5064 +// doesn't block SIGINT et al. 16.5065 +int os::fork_and_exec(char* cmd) { 16.5066 + Unimplemented(); 16.5067 + return 0; 16.5068 +} 16.5069 + 16.5070 +// is_headless_jre() 16.5071 +// 16.5072 +// Test for the existence of xawt/libmawt.so or libawt_xawt.so 16.5073 +// in order to report if we are running in a headless jre. 16.5074 +// 16.5075 +// Since JDK8 xawt/libmawt.so is moved into the same directory 16.5076 +// as libawt.so, and renamed libawt_xawt.so 16.5077 +bool os::is_headless_jre() { 16.5078 + struct stat statbuf; 16.5079 + char buf[MAXPATHLEN]; 16.5080 + char libmawtpath[MAXPATHLEN]; 16.5081 + const char *xawtstr = "/xawt/libmawt.so"; 16.5082 + const char *new_xawtstr = "/libawt_xawt.so"; 16.5083 + 16.5084 + char *p; 16.5085 + 16.5086 + // Get path to libjvm.so 16.5087 + os::jvm_path(buf, sizeof(buf)); 16.5088 + 16.5089 + // Get rid of libjvm.so 16.5090 + p = strrchr(buf, '/'); 16.5091 + if (p == NULL) return false; 16.5092 + else *p = '\0'; 16.5093 + 16.5094 + // Get rid of client or server 16.5095 + p = strrchr(buf, '/'); 16.5096 + if (p == NULL) return false; 16.5097 + else *p = '\0'; 16.5098 + 16.5099 + // check xawt/libmawt.so 16.5100 + strcpy(libmawtpath, buf); 16.5101 + strcat(libmawtpath, xawtstr); 16.5102 + if (::stat(libmawtpath, &statbuf) == 0) return false; 16.5103 + 16.5104 + // check libawt_xawt.so 16.5105 + strcpy(libmawtpath, buf); 16.5106 + strcat(libmawtpath, new_xawtstr); 16.5107 + if (::stat(libmawtpath, &statbuf) == 0) return false; 16.5108 + 16.5109 + return true; 16.5110 +} 16.5111 + 16.5112 +// Get the default path to the core file 16.5113 +// Returns the length of the string 16.5114 +int os::get_core_path(char* buffer, size_t bufferSize) { 16.5115 + const char* p = get_current_directory(buffer, bufferSize); 16.5116 + 16.5117 + if (p == NULL) { 16.5118 + assert(p != NULL, "failed to get current directory"); 16.5119 + return 0; 16.5120 + } 16.5121 + 16.5122 + return strlen(buffer); 16.5123 +} 16.5124 + 16.5125 +#ifndef PRODUCT 16.5126 +void TestReserveMemorySpecial_test() { 16.5127 + // No tests available for this platform 16.5128 +} 16.5129 +#endif
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/os/aix/vm/os_aix.hpp Fri Sep 06 20:16:09 2013 +0200 17.3 @@ -0,0 +1,385 @@ 17.4 +/* 17.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright 2013 SAP AG. All rights reserved. 17.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 + * 17.9 + * This code is free software; you can redistribute it and/or modify it 17.10 + * under the terms of the GNU General Public License version 2 only, as 17.11 + * published by the Free Software Foundation. 17.12 + * 17.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 17.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17.16 + * version 2 for more details (a copy is included in the LICENSE file that 17.17 + * accompanied this code). 17.18 + * 17.19 + * You should have received a copy of the GNU General Public License version 17.20 + * 2 along with this work; if not, write to the Free Software Foundation, 17.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17.22 + * 17.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 17.24 + * or visit www.oracle.com if you need additional information or have any 17.25 + * questions. 17.26 + * 17.27 + */ 17.28 + 17.29 +#ifndef OS_AIX_VM_OS_AIX_HPP 17.30 +#define OS_AIX_VM_OS_AIX_HPP 17.31 + 17.32 +// Information about the protection of the page at address '0' on this os. 17.33 +static bool zero_page_read_protected() { return false; } 17.34 + 17.35 +// Class Aix defines the interface to the Aix operating systems. 17.36 + 17.37 +class Aix { 17.38 + friend class os; 17.39 + 17.40 + // For signal-chaining 17.41 + // highest so far (AIX 5.2) is SIGSAK (63) 17.42 +#define MAXSIGNUM 63 17.43 + // length of strings included in the libperfstat structures 17.44 +#define IDENTIFIER_LENGTH 64 17.45 + 17.46 + static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions 17.47 + static unsigned int sigs; // mask of signals that have 17.48 + // preinstalled signal handlers 17.49 + static bool libjsig_is_loaded; // libjsig that interposes sigaction(), 17.50 + // __sigaction(), signal() is loaded 17.51 + static struct sigaction *(*get_signal_action)(int); 17.52 + static struct sigaction *get_preinstalled_handler(int); 17.53 + static void save_preinstalled_handler(int, struct sigaction&); 17.54 + 17.55 + static void check_signal_handler(int sig); 17.56 + 17.57 + // For signal flags diagnostics 17.58 + static int sigflags[MAXSIGNUM]; 17.59 + 17.60 + protected: 17.61 + 17.62 + static julong _physical_memory; 17.63 + static pthread_t _main_thread; 17.64 + static Mutex* _createThread_lock; 17.65 + static int _page_size; 17.66 + static int _logical_cpus; 17.67 + 17.68 + // -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE) 17.69 + static int _on_pase; 17.70 + 17.71 + // -1 = uninitialized, otherwise 16 bit number: 17.72 + // lower 8 bit - minor version 17.73 + // higher 8 bit - major version 17.74 + // For AIX, e.g. 0x0601 for AIX 6.1 17.75 + // for OS/400 e.g. 0x0504 for OS/400 V5R4 17.76 + static int _os_version; 17.77 + 17.78 + // -1 = uninitialized, 17.79 + // 0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set) 17.80 + // 1 - SPEC1170 requested (XPG_SUS_ENV is ON) 17.81 + static int _xpg_sus_mode; 17.82 + 17.83 + // -1 = uninitialized, 17.84 + // 0 - EXTSHM=OFF or not set 17.85 + // 1 - EXTSHM=ON 17.86 + static int _extshm; 17.87 + 17.88 + // page sizes on AIX. 17.89 + // 17.90 + // AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The latter two 17.91 + // (16M "large" resp. 16G "huge" pages) require special setup and are normally 17.92 + // not available. 17.93 + // 17.94 + // AIX supports multiple page sizes per process, for: 17.95 + // - Stack (of the primordial thread, so not relevant for us) 17.96 + // - Data - data, bss, heap, for us also pthread stacks 17.97 + // - Text - text code 17.98 + // - shared memory 17.99 + // 17.100 + // Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...) 17.101 + // and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...) 17.102 + // 17.103 + // For shared memory, page size can be set dynamically via shmctl(). Different shared memory 17.104 + // regions can have different page sizes. 17.105 + // 17.106 + // More information can be found at AIBM info center: 17.107 + // http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm 17.108 + // 17.109 + // ----- 17.110 + // We want to support 4K and 64K and, if the machine is set up correctly, 16MB pages. 17.111 + // 17.112 + 17.113 + // page size of the stack of newly created pthreads 17.114 + // (should be LDR_CNTRL DATAPSIZE because stack is allocated on heap by pthread lib) 17.115 + static int _stack_page_size; 17.116 + 17.117 + // Default shm page size. Read: what page size shared memory will be backed 17.118 + // with if no page size was set explicitly using shmctl(SHM_PAGESIZE). 17.119 + // Should be LDR_CNTRL SHMPSIZE. 17.120 + static size_t _shm_default_page_size; 17.121 + 17.122 + // True if sys V shm can be used with 64K pages dynamically. 17.123 + // (via shmctl(.. SHM_PAGESIZE..). Should be true for AIX 53 and 17.124 + // newer / PASE V6R1 and newer. (0 or 1, -1 if not initialized) 17.125 + static int _can_use_64K_pages; 17.126 + 17.127 + // True if sys V shm can be used with 16M pages dynamically. 17.128 + // (via shmctl(.. SHM_PAGESIZE..). Only true on AIX 5.3 and 17.129 + // newer, if the system was set up to use 16M pages and the 17.130 + // jvm has enough user rights. (0 or 1, -1 if not initialized) 17.131 + static int _can_use_16M_pages; 17.132 + 17.133 + static julong available_memory(); 17.134 + static julong physical_memory() { return _physical_memory; } 17.135 + static void initialize_system_info(); 17.136 + 17.137 + // OS recognitions (PASE/AIX, OS level) call this before calling any 17.138 + // one of Aix::on_pase(), Aix::os_version(). 17.139 + static void initialize_os_info(); 17.140 + 17.141 + static int commit_memory_impl(char* addr, size_t bytes, bool exec); 17.142 + static int commit_memory_impl(char* addr, size_t bytes, 17.143 + size_t alignment_hint, bool exec); 17.144 + 17.145 + // Scan environment for important settings which might effect the 17.146 + // VM. Trace out settings. Warn about invalid settings and/or 17.147 + // correct them. 17.148 + // 17.149 + // Must run after os::Aix::initialue_os_info(). 17.150 + static void scan_environment(); 17.151 + 17.152 + // Retrieve information about multipage size support. Will initialize 17.153 + // _page_size, _stack_page_size, _can_use_64K_pages/_can_use_16M_pages 17.154 + static void query_multipage_support(); 17.155 + 17.156 + // Initialize libo4 (on PASE) and libperfstat (on AIX). Call this 17.157 + // before relying on functions from either lib, e.g. Aix::get_meminfo(). 17.158 + static void initialize_libo4(); 17.159 + static void initialize_libperfstat(); 17.160 + 17.161 + static bool supports_variable_stack_size(); 17.162 + 17.163 + public: 17.164 + static void init_thread_fpu_state(); 17.165 + static pthread_t main_thread(void) { return _main_thread; } 17.166 + // returns kernel thread id (similar to LWP id on Solaris), which can be 17.167 + // used to access /proc 17.168 + static pid_t gettid(); 17.169 + static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; } 17.170 + static Mutex* createThread_lock(void) { return _createThread_lock; } 17.171 + static void hotspot_sigmask(Thread* thread); 17.172 + 17.173 + // Given an address, returns the size of the page backing that address 17.174 + static size_t query_pagesize(void* p); 17.175 + 17.176 + // Return `true' if the calling thread is the primordial thread. The 17.177 + // primordial thread is the thread which contains the main function, 17.178 + // *not* necessarily the thread which initialized the VM by calling 17.179 + // JNI_CreateJavaVM. 17.180 + static bool is_primordial_thread(void); 17.181 + 17.182 + static int page_size(void) { 17.183 + assert(_page_size != -1, "not initialized"); 17.184 + return _page_size; 17.185 + } 17.186 + 17.187 + // Accessor methods for stack page size which may be different from usual page size. 17.188 + static int stack_page_size(void) { 17.189 + assert(_stack_page_size != -1, "not initialized"); 17.190 + return _stack_page_size; 17.191 + } 17.192 + 17.193 + // default shm page size. Read: what page size shared memory 17.194 + // will be backed with if no page size was set explicitly using shmctl(SHM_PAGESIZE). 17.195 + // Should be LDR_CNTRL SHMPSIZE. 17.196 + static int shm_default_page_size(void) { 17.197 + assert(_shm_default_page_size != -1, "not initialized"); 17.198 + return _shm_default_page_size; 17.199 + } 17.200 + 17.201 + // Return true if sys V shm can be used with 64K pages dynamically 17.202 + // (via shmctl(.. SHM_PAGESIZE..). 17.203 + static bool can_use_64K_pages () { 17.204 + assert(_can_use_64K_pages != -1, "not initialized"); 17.205 + return _can_use_64K_pages == 1 ? true : false; 17.206 + } 17.207 + 17.208 + // Return true if sys V shm can be used with 16M pages dynamically. 17.209 + // (via shmctl(.. SHM_PAGESIZE..). 17.210 + static bool can_use_16M_pages () { 17.211 + assert(_can_use_16M_pages != -1, "not initialized"); 17.212 + return _can_use_16M_pages == 1 ? true : false; 17.213 + } 17.214 + 17.215 + static address ucontext_get_pc(ucontext_t* uc); 17.216 + static intptr_t* ucontext_get_sp(ucontext_t* uc); 17.217 + static intptr_t* ucontext_get_fp(ucontext_t* uc); 17.218 + // Set PC into context. Needed for continuation after signal. 17.219 + static void ucontext_set_pc(ucontext_t* uc, address pc); 17.220 + 17.221 + // This boolean allows users to forward their own non-matching signals 17.222 + // to JVM_handle_aix_signal, harmlessly. 17.223 + static bool signal_handlers_are_installed; 17.224 + 17.225 + static int get_our_sigflags(int); 17.226 + static void set_our_sigflags(int, int); 17.227 + static void signal_sets_init(); 17.228 + static void install_signal_handlers(); 17.229 + static void set_signal_handler(int, bool); 17.230 + static bool is_sig_ignored(int sig); 17.231 + 17.232 + static sigset_t* unblocked_signals(); 17.233 + static sigset_t* vm_signals(); 17.234 + static sigset_t* allowdebug_blocked_signals(); 17.235 + 17.236 + // For signal-chaining 17.237 + static struct sigaction *get_chained_signal_action(int sig); 17.238 + static bool chained_handler(int sig, siginfo_t* siginfo, void* context); 17.239 + 17.240 + // libpthread version string 17.241 + static void libpthread_init(); 17.242 + 17.243 + // Minimum stack size a thread can be created with (allowing 17.244 + // the VM to completely create the thread and enter user code) 17.245 + static size_t min_stack_allowed; 17.246 + 17.247 + // Return default stack size or guard size for the specified thread type 17.248 + static size_t default_stack_size(os::ThreadType thr_type); 17.249 + static size_t default_guard_size(os::ThreadType thr_type); 17.250 + 17.251 + // Function returns true if we run on OS/400 (pase), false if we run 17.252 + // on AIX. 17.253 + static bool on_pase() { 17.254 + assert(_on_pase != -1, "not initialized"); 17.255 + return _on_pase ? true : false; 17.256 + } 17.257 + 17.258 + // Function returns true if we run on AIX, false if we run on OS/400 17.259 + // (pase). 17.260 + static bool on_aix() { 17.261 + assert(_on_pase != -1, "not initialized"); 17.262 + return _on_pase ? false : true; 17.263 + } 17.264 + 17.265 + // -1 = uninitialized, otherwise 16 bit number: 17.266 + // lower 8 bit - minor version 17.267 + // higher 8 bit - major version 17.268 + // For AIX, e.g. 0x0601 for AIX 6.1 17.269 + // for OS/400 e.g. 0x0504 for OS/400 V5R4 17.270 + static int os_version () { 17.271 + assert(_os_version != -1, "not initialized"); 17.272 + return _os_version; 17.273 + } 17.274 + 17.275 + // Convenience method: returns true if running on AIX 5.3 or older. 17.276 + static bool on_aix_53_or_older() { 17.277 + return on_aix() && os_version() <= 0x0503; 17.278 + } 17.279 + 17.280 + // Returns true if we run in SPEC1170 compliant mode (XPG_SUS_ENV=ON). 17.281 + static bool xpg_sus_mode() { 17.282 + assert(_xpg_sus_mode != -1, "not initialized"); 17.283 + return _xpg_sus_mode; 17.284 + } 17.285 + 17.286 + // Returns true if EXTSHM=ON. 17.287 + static bool extshm() { 17.288 + assert(_extshm != -1, "not initialized"); 17.289 + return _extshm; 17.290 + } 17.291 + 17.292 + // result struct for get_meminfo() 17.293 + struct meminfo_t { 17.294 + 17.295 + // Amount of virtual memory (in units of 4 KB pages) 17.296 + unsigned long long virt_total; 17.297 + 17.298 + // Amount of real memory, in bytes 17.299 + unsigned long long real_total; 17.300 + 17.301 + // Amount of free real memory, in bytes 17.302 + unsigned long long real_free; 17.303 + 17.304 + // Total amount of paging space, in bytes 17.305 + unsigned long long pgsp_total; 17.306 + 17.307 + // Amount of free paging space, in bytes 17.308 + unsigned long long pgsp_free; 17.309 + 17.310 + }; 17.311 + 17.312 + // Result struct for get_cpuinfo(). 17.313 + struct cpuinfo_t { 17.314 + char description[IDENTIFIER_LENGTH]; // processor description (type/official name) 17.315 + u_longlong_t processorHZ; // processor speed in Hz 17.316 + int ncpus; // number of active logical processors 17.317 + double loadavg[3]; // (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes. 17.318 + // To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>. 17.319 + char version[20]; // processor version from _system_configuration (sys/systemcfg.h) 17.320 + }; 17.321 + 17.322 + // Functions to retrieve memory information on AIX, PASE. 17.323 + // (on AIX, using libperfstat, on PASE with libo4.so). 17.324 + // Returns true if ok, false if error. 17.325 + static bool get_meminfo(meminfo_t* pmi); 17.326 + 17.327 + // Function to retrieve cpu information on AIX 17.328 + // (on AIX, using libperfstat) 17.329 + // Returns true if ok, false if error. 17.330 + static bool get_cpuinfo(cpuinfo_t* pci); 17.331 + 17.332 +}; // os::Aix class 17.333 + 17.334 + 17.335 +class PlatformEvent : public CHeapObj<mtInternal> { 17.336 + private: 17.337 + double CachePad [4]; // increase odds that _mutex is sole occupant of cache line 17.338 + volatile int _Event; 17.339 + volatile int _nParked; 17.340 + pthread_mutex_t _mutex [1]; 17.341 + pthread_cond_t _cond [1]; 17.342 + double PostPad [2]; 17.343 + Thread * _Assoc; 17.344 + 17.345 + public: // TODO-FIXME: make dtor private 17.346 + ~PlatformEvent() { guarantee (0, "invariant"); } 17.347 + 17.348 + public: 17.349 + PlatformEvent() { 17.350 + int status; 17.351 + status = pthread_cond_init (_cond, NULL); 17.352 + assert_status(status == 0, status, "cond_init"); 17.353 + status = pthread_mutex_init (_mutex, NULL); 17.354 + assert_status(status == 0, status, "mutex_init"); 17.355 + _Event = 0; 17.356 + _nParked = 0; 17.357 + _Assoc = NULL; 17.358 + } 17.359 + 17.360 + // Use caution with reset() and fired() -- they may require MEMBARs 17.361 + void reset() { _Event = 0; } 17.362 + int fired() { return _Event; } 17.363 + void park (); 17.364 + void unpark (); 17.365 + int TryPark (); 17.366 + int park (jlong millis); 17.367 + void SetAssociation (Thread * a) { _Assoc = a; } 17.368 +}; 17.369 + 17.370 +class PlatformParker : public CHeapObj<mtInternal> { 17.371 + protected: 17.372 + pthread_mutex_t _mutex [1]; 17.373 + pthread_cond_t _cond [1]; 17.374 + 17.375 + public: // TODO-FIXME: make dtor private 17.376 + ~PlatformParker() { guarantee (0, "invariant"); } 17.377 + 17.378 + public: 17.379 + PlatformParker() { 17.380 + int status; 17.381 + status = pthread_cond_init (_cond, NULL); 17.382 + assert_status(status == 0, status, "cond_init"); 17.383 + status = pthread_mutex_init (_mutex, NULL); 17.384 + assert_status(status == 0, status, "mutex_init"); 17.385 + } 17.386 +}; 17.387 + 17.388 +#endif // OS_AIX_VM_OS_AIX_HPP
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/os/aix/vm/os_aix.inline.hpp Fri Sep 06 20:16:09 2013 +0200 18.3 @@ -0,0 +1,286 @@ 18.4 +/* 18.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 18.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 + * 18.9 + * This code is free software; you can redistribute it and/or modify it 18.10 + * under the terms of the GNU General Public License version 2 only, as 18.11 + * published by the Free Software Foundation. 18.12 + * 18.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 18.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18.16 + * version 2 for more details (a copy is included in the LICENSE file that 18.17 + * accompanied this code). 18.18 + * 18.19 + * You should have received a copy of the GNU General Public License version 18.20 + * 2 along with this work; if not, write to the Free Software Foundation, 18.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18.22 + * 18.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 18.24 + * or visit www.oracle.com if you need additional information or have any 18.25 + * questions. 18.26 + * 18.27 + */ 18.28 + 18.29 +#ifndef OS_AIX_VM_OS_AIX_INLINE_HPP 18.30 +#define OS_AIX_VM_OS_AIX_INLINE_HPP 18.31 + 18.32 +#include "runtime/atomic.hpp" 18.33 +#include "runtime/os.hpp" 18.34 +#ifdef TARGET_OS_ARCH_aix_ppc 18.35 +# include "atomic_aix_ppc.inline.hpp" 18.36 +# include "orderAccess_aix_ppc.inline.hpp" 18.37 +#endif 18.38 + 18.39 +// System includes 18.40 + 18.41 +#include <unistd.h> 18.42 +#include <sys/socket.h> 18.43 +#include <sys/poll.h> 18.44 +#include <sys/ioctl.h> 18.45 +#include <netdb.h> 18.46 + 18.47 +// Defined in the system headers included above. 18.48 +#undef rem_size 18.49 + 18.50 +inline void* os::thread_local_storage_at(int index) { 18.51 + return pthread_getspecific((pthread_key_t)index); 18.52 +} 18.53 + 18.54 +inline const char* os::file_separator() { 18.55 + return "/"; 18.56 +} 18.57 + 18.58 +inline const char* os::line_separator() { 18.59 + return "\n"; 18.60 +} 18.61 + 18.62 +inline const char* os::path_separator() { 18.63 + return ":"; 18.64 +} 18.65 + 18.66 +// File names are case-sensitive on windows only 18.67 +inline int os::file_name_strcmp(const char* s1, const char* s2) { 18.68 + return strcmp(s1, s2); 18.69 +} 18.70 + 18.71 +inline bool os::obsolete_option(const JavaVMOption *option) { 18.72 + return false; 18.73 +} 18.74 + 18.75 +inline bool os::uses_stack_guard_pages() { 18.76 + return true; 18.77 +} 18.78 + 18.79 +inline bool os::allocate_stack_guard_pages() { 18.80 + assert(uses_stack_guard_pages(), "sanity check"); 18.81 + return true; 18.82 +} 18.83 + 18.84 + 18.85 +// On Aix, reservations are made on a page by page basis, nothing to do. 18.86 +inline void os::pd_split_reserved_memory(char *base, size_t size, 18.87 + size_t split, bool realloc) { 18.88 +} 18.89 + 18.90 + 18.91 +// Bang the shadow pages if they need to be touched to be mapped. 18.92 +inline void os::bang_stack_shadow_pages() { 18.93 +} 18.94 + 18.95 +inline void os::dll_unload(void *lib) { 18.96 + ::dlclose(lib); 18.97 +} 18.98 + 18.99 +inline const int os::default_file_open_flags() { return 0;} 18.100 + 18.101 +inline DIR* os::opendir(const char* dirname) 18.102 +{ 18.103 + assert(dirname != NULL, "just checking"); 18.104 + return ::opendir(dirname); 18.105 +} 18.106 + 18.107 +inline int os::readdir_buf_size(const char *path) 18.108 +{ 18.109 + // according to aix sys/limits, NAME_MAX must be retrieved at runtime. */ 18.110 + const long my_NAME_MAX = pathconf(path, _PC_NAME_MAX); 18.111 + return my_NAME_MAX + sizeof(dirent) + 1; 18.112 +} 18.113 + 18.114 +inline jlong os::lseek(int fd, jlong offset, int whence) { 18.115 + return (jlong) ::lseek64(fd, offset, whence); 18.116 +} 18.117 + 18.118 +inline int os::fsync(int fd) { 18.119 + return ::fsync(fd); 18.120 +} 18.121 + 18.122 +inline char* os::native_path(char *path) { 18.123 + return path; 18.124 +} 18.125 + 18.126 +inline int os::ftruncate(int fd, jlong length) { 18.127 + return ::ftruncate64(fd, length); 18.128 +} 18.129 + 18.130 +inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf) 18.131 +{ 18.132 + dirent* p; 18.133 + int status; 18.134 + assert(dirp != NULL, "just checking"); 18.135 + 18.136 + // NOTE: Linux readdir_r (on RH 6.2 and 7.2 at least) is NOT like the POSIX 18.137 + // version. Here is the doc for this function: 18.138 + // http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_262.html 18.139 + 18.140 + if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { 18.141 + errno = status; 18.142 + return NULL; 18.143 + } else 18.144 + return p; 18.145 +} 18.146 + 18.147 +inline int os::closedir(DIR *dirp) { 18.148 + assert(dirp != NULL, "argument is NULL"); 18.149 + return ::closedir(dirp); 18.150 +} 18.151 + 18.152 +// macros for restartable system calls 18.153 + 18.154 +#define RESTARTABLE(_cmd, _result) do { \ 18.155 + _result = _cmd; \ 18.156 + } while(((int)_result == OS_ERR) && (errno == EINTR)) 18.157 + 18.158 +#define RESTARTABLE_RETURN_INT(_cmd) do { \ 18.159 + int _result; \ 18.160 + RESTARTABLE(_cmd, _result); \ 18.161 + return _result; \ 18.162 +} while(false) 18.163 + 18.164 +// We don't have NUMA support on Aix, but we need this for compilation. 18.165 +inline bool os::numa_has_static_binding() { ShouldNotReachHere(); return true; } 18.166 +inline bool os::numa_has_group_homing() { ShouldNotReachHere(); return false; } 18.167 + 18.168 +inline size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { 18.169 + size_t res; 18.170 + RESTARTABLE( (size_t) ::read(fd, buf, (size_t) nBytes), res); 18.171 + return res; 18.172 +} 18.173 + 18.174 +inline size_t os::write(int fd, const void *buf, unsigned int nBytes) { 18.175 + size_t res; 18.176 + RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); 18.177 + return res; 18.178 +} 18.179 + 18.180 +inline int os::close(int fd) { 18.181 + return ::close(fd); 18.182 +} 18.183 + 18.184 +inline int os::socket_close(int fd) { 18.185 + return ::close(fd); 18.186 +} 18.187 + 18.188 +inline int os::socket(int domain, int type, int protocol) { 18.189 + return ::socket(domain, type, protocol); 18.190 +} 18.191 + 18.192 +inline int os::recv(int fd, char* buf, size_t nBytes, uint flags) { 18.193 + RESTARTABLE_RETURN_INT(::recv(fd, buf, nBytes, flags)); 18.194 +} 18.195 + 18.196 +inline int os::send(int fd, char* buf, size_t nBytes, uint flags) { 18.197 + RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags)); 18.198 +} 18.199 + 18.200 +inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { 18.201 + return os::send(fd, buf, nBytes, flags); 18.202 +} 18.203 + 18.204 +inline int os::timeout(int fd, long timeout) { 18.205 + julong prevtime,newtime; 18.206 + struct timeval t; 18.207 + 18.208 + gettimeofday(&t, NULL); 18.209 + prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; 18.210 + 18.211 + for(;;) { 18.212 + struct pollfd pfd; 18.213 + 18.214 + pfd.fd = fd; 18.215 + pfd.events = POLLIN | POLLERR; 18.216 + 18.217 + int res = ::poll(&pfd, 1, timeout); 18.218 + 18.219 + if (res == OS_ERR && errno == EINTR) { 18.220 + 18.221 + // On Linux any value < 0 means "forever" 18.222 + 18.223 + if(timeout >= 0) { 18.224 + gettimeofday(&t, NULL); 18.225 + newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; 18.226 + timeout -= newtime - prevtime; 18.227 + if(timeout <= 0) 18.228 + return OS_OK; 18.229 + prevtime = newtime; 18.230 + } 18.231 + } else 18.232 + return res; 18.233 + } 18.234 +} 18.235 + 18.236 +inline int os::listen(int fd, int count) { 18.237 + return ::listen(fd, count); 18.238 +} 18.239 + 18.240 +inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { 18.241 + RESTARTABLE_RETURN_INT(::connect(fd, him, len)); 18.242 +} 18.243 + 18.244 +inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { 18.245 + // Linux doc says this can't return EINTR, unlike accept() on Solaris. 18.246 + // But see attachListener_linux.cpp, LinuxAttachListener::dequeue(). 18.247 + return (int)::accept(fd, him, len); 18.248 +} 18.249 + 18.250 +inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, 18.251 + sockaddr* from, socklen_t* fromlen) { 18.252 + RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); 18.253 +} 18.254 + 18.255 +inline int os::sendto(int fd, char* buf, size_t len, uint flags, 18.256 + struct sockaddr* to, socklen_t tolen) { 18.257 + RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); 18.258 +} 18.259 + 18.260 +inline int os::socket_shutdown(int fd, int howto) { 18.261 + return ::shutdown(fd, howto); 18.262 +} 18.263 + 18.264 +inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { 18.265 + return ::bind(fd, him, len); 18.266 +} 18.267 + 18.268 +inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { 18.269 + return ::getsockname(fd, him, len); 18.270 +} 18.271 + 18.272 +inline int os::get_host_name(char* name, int namelen) { 18.273 + return ::gethostname(name, namelen); 18.274 +} 18.275 + 18.276 +inline struct hostent* os::get_host_by_name(char* name) { 18.277 + return ::gethostbyname(name); 18.278 +} 18.279 + 18.280 +inline int os::get_sock_opt(int fd, int level, int optname, 18.281 + char* optval, socklen_t* optlen) { 18.282 + return ::getsockopt(fd, level, optname, optval, optlen); 18.283 +} 18.284 + 18.285 +inline int os::set_sock_opt(int fd, int level, int optname, 18.286 + const char* optval, socklen_t optlen) { 18.287 + return ::setsockopt(fd, level, optname, optval, optlen); 18.288 +} 18.289 +#endif // OS_AIX_VM_OS_AIX_INLINE_HPP
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/os/aix/vm/os_share_aix.hpp Fri Sep 06 20:16:09 2013 +0200 19.3 @@ -0,0 +1,37 @@ 19.4 +/* 19.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.7 + * 19.8 + * This code is free software; you can redistribute it and/or modify it 19.9 + * under the terms of the GNU General Public License version 2 only, as 19.10 + * published by the Free Software Foundation. 19.11 + * 19.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19.15 + * version 2 for more details (a copy is included in the LICENSE file that 19.16 + * accompanied this code). 19.17 + * 19.18 + * You should have received a copy of the GNU General Public License version 19.19 + * 2 along with this work; if not, write to the Free Software Foundation, 19.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19.21 + * 19.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19.23 + * or visit www.oracle.com if you need additional information or have any 19.24 + * questions. 19.25 + * 19.26 + */ 19.27 + 19.28 +#ifndef OS_AIX_VM_OS_SHARE_AIX_HPP 19.29 +#define OS_AIX_VM_OS_SHARE_AIX_HPP 19.30 + 19.31 +// misc 19.32 +void signalHandler(int, siginfo_t*, ucontext_t*); 19.33 +void handle_unexpected_exception(Thread* thread, int sig, siginfo_t* info, address pc, address adjusted_pc); 19.34 +#ifndef PRODUCT 19.35 +void continue_with_dump(void); 19.36 +#endif 19.37 + 19.38 +#define PROCFILE_LENGTH 128 19.39 + 19.40 +#endif // OS_AIX_VM_OS_SHARE_AIX_HPP
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/os/aix/vm/perfMemory_aix.cpp Fri Sep 06 20:16:09 2013 +0200 20.3 @@ -0,0 +1,1026 @@ 20.4 +/* 20.5 + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 20.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 20.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 + * 20.9 + * This code is free software; you can redistribute it and/or modify it 20.10 + * under the terms of the GNU General Public License version 2 only, as 20.11 + * published by the Free Software Foundation. 20.12 + * 20.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.16 + * version 2 for more details (a copy is included in the LICENSE file that 20.17 + * accompanied this code). 20.18 + * 20.19 + * You should have received a copy of the GNU General Public License version 20.20 + * 2 along with this work; if not, write to the Free Software Foundation, 20.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.22 + * 20.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.24 + * or visit www.oracle.com if you need additional information or have any 20.25 + * questions. 20.26 + * 20.27 + */ 20.28 + 20.29 +#include "precompiled.hpp" 20.30 +#include "classfile/vmSymbols.hpp" 20.31 +#include "memory/allocation.inline.hpp" 20.32 +#include "memory/resourceArea.hpp" 20.33 +#include "oops/oop.inline.hpp" 20.34 +#include "os_aix.inline.hpp" 20.35 +#include "runtime/handles.inline.hpp" 20.36 +#include "runtime/perfMemory.hpp" 20.37 +#include "utilities/exceptions.hpp" 20.38 + 20.39 +// put OS-includes here 20.40 +# include <sys/types.h> 20.41 +# include <sys/mman.h> 20.42 +# include <errno.h> 20.43 +# include <stdio.h> 20.44 +# include <unistd.h> 20.45 +# include <sys/stat.h> 20.46 +# include <signal.h> 20.47 +# include <pwd.h> 20.48 + 20.49 +static char* backing_store_file_name = NULL; // name of the backing store 20.50 + // file, if successfully created. 20.51 + 20.52 +// Standard Memory Implementation Details 20.53 + 20.54 +// create the PerfData memory region in standard memory. 20.55 +// 20.56 +static char* create_standard_memory(size_t size) { 20.57 + 20.58 + // allocate an aligned chuck of memory 20.59 + char* mapAddress = os::reserve_memory(size); 20.60 + 20.61 + if (mapAddress == NULL) { 20.62 + return NULL; 20.63 + } 20.64 + 20.65 + // commit memory 20.66 + if (!os::commit_memory(mapAddress, size, !ExecMem)) { 20.67 + if (PrintMiscellaneous && Verbose) { 20.68 + warning("Could not commit PerfData memory\n"); 20.69 + } 20.70 + os::release_memory(mapAddress, size); 20.71 + return NULL; 20.72 + } 20.73 + 20.74 + return mapAddress; 20.75 +} 20.76 + 20.77 +// delete the PerfData memory region 20.78 +// 20.79 +static void delete_standard_memory(char* addr, size_t size) { 20.80 + 20.81 + // there are no persistent external resources to cleanup for standard 20.82 + // memory. since DestroyJavaVM does not support unloading of the JVM, 20.83 + // cleanup of the memory resource is not performed. The memory will be 20.84 + // reclaimed by the OS upon termination of the process. 20.85 + // 20.86 + return; 20.87 +} 20.88 + 20.89 +// save the specified memory region to the given file 20.90 +// 20.91 +// Note: this function might be called from signal handler (by os::abort()), 20.92 +// don't allocate heap memory. 20.93 +// 20.94 +static void save_memory_to_file(char* addr, size_t size) { 20.95 + 20.96 + const char* destfile = PerfMemory::get_perfdata_file_path(); 20.97 + assert(destfile[0] != '\0', "invalid PerfData file path"); 20.98 + 20.99 + int result; 20.100 + 20.101 + RESTARTABLE(::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE), 20.102 + result);; 20.103 + if (result == OS_ERR) { 20.104 + if (PrintMiscellaneous && Verbose) { 20.105 + warning("Could not create Perfdata save file: %s: %s\n", 20.106 + destfile, strerror(errno)); 20.107 + } 20.108 + } else { 20.109 + int fd = result; 20.110 + 20.111 + for (size_t remaining = size; remaining > 0;) { 20.112 + 20.113 + RESTARTABLE(::write(fd, addr, remaining), result); 20.114 + if (result == OS_ERR) { 20.115 + if (PrintMiscellaneous && Verbose) { 20.116 + warning("Could not write Perfdata save file: %s: %s\n", 20.117 + destfile, strerror(errno)); 20.118 + } 20.119 + break; 20.120 + } 20.121 + 20.122 + remaining -= (size_t)result; 20.123 + addr += result; 20.124 + } 20.125 + 20.126 + RESTARTABLE(::close(fd), result); 20.127 + if (PrintMiscellaneous && Verbose) { 20.128 + if (result == OS_ERR) { 20.129 + warning("Could not close %s: %s\n", destfile, strerror(errno)); 20.130 + } 20.131 + } 20.132 + } 20.133 + FREE_C_HEAP_ARRAY(char, destfile, mtInternal); 20.134 +} 20.135 + 20.136 + 20.137 +// Shared Memory Implementation Details 20.138 + 20.139 +// Note: the solaris and linux shared memory implementation uses the mmap 20.140 +// interface with a backing store file to implement named shared memory. 20.141 +// Using the file system as the name space for shared memory allows a 20.142 +// common name space to be supported across a variety of platforms. It 20.143 +// also provides a name space that Java applications can deal with through 20.144 +// simple file apis. 20.145 +// 20.146 +// The solaris and linux implementations store the backing store file in 20.147 +// a user specific temporary directory located in the /tmp file system, 20.148 +// which is always a local file system and is sometimes a RAM based file 20.149 +// system. 20.150 + 20.151 +// return the user specific temporary directory name. 20.152 +// 20.153 +// the caller is expected to free the allocated memory. 20.154 +// 20.155 +static char* get_user_tmp_dir(const char* user) { 20.156 + 20.157 + const char* tmpdir = os::get_temp_directory(); 20.158 + const char* perfdir = PERFDATA_NAME; 20.159 + size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; 20.160 + char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); 20.161 + 20.162 + // construct the path name to user specific tmp directory 20.163 + snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); 20.164 + 20.165 + return dirname; 20.166 +} 20.167 + 20.168 +// convert the given file name into a process id. if the file 20.169 +// does not meet the file naming constraints, return 0. 20.170 +// 20.171 +static pid_t filename_to_pid(const char* filename) { 20.172 + 20.173 + // a filename that doesn't begin with a digit is not a 20.174 + // candidate for conversion. 20.175 + // 20.176 + if (!isdigit(*filename)) { 20.177 + return 0; 20.178 + } 20.179 + 20.180 + // check if file name can be converted to an integer without 20.181 + // any leftover characters. 20.182 + // 20.183 + char* remainder = NULL; 20.184 + errno = 0; 20.185 + pid_t pid = (pid_t)strtol(filename, &remainder, 10); 20.186 + 20.187 + if (errno != 0) { 20.188 + return 0; 20.189 + } 20.190 + 20.191 + // check for left over characters. If any, then the filename is 20.192 + // not a candidate for conversion. 20.193 + // 20.194 + if (remainder != NULL && *remainder != '\0') { 20.195 + return 0; 20.196 + } 20.197 + 20.198 + // successful conversion, return the pid 20.199 + return pid; 20.200 +} 20.201 + 20.202 + 20.203 +// check if the given path is considered a secure directory for 20.204 +// the backing store files. Returns true if the directory exists 20.205 +// and is considered a secure location. Returns false if the path 20.206 +// is a symbolic link or if an error occurred. 20.207 +// 20.208 +static bool is_directory_secure(const char* path) { 20.209 + struct stat statbuf; 20.210 + int result = 0; 20.211 + 20.212 + RESTARTABLE(::lstat(path, &statbuf), result); 20.213 + if (result == OS_ERR) { 20.214 + return false; 20.215 + } 20.216 + 20.217 + // the path exists, now check it's mode 20.218 + if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) { 20.219 + // the path represents a link or some non-directory file type, 20.220 + // which is not what we expected. declare it insecure. 20.221 + // 20.222 + return false; 20.223 + } 20.224 + else { 20.225 + // we have an existing directory, check if the permissions are safe. 20.226 + // 20.227 + if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) { 20.228 + // the directory is open for writing and could be subjected 20.229 + // to a symlnk attack. declare it insecure. 20.230 + // 20.231 + return false; 20.232 + } 20.233 + } 20.234 + return true; 20.235 +} 20.236 + 20.237 + 20.238 +// return the user name for the given user id 20.239 +// 20.240 +// the caller is expected to free the allocated memory. 20.241 +// 20.242 +static char* get_user_name(uid_t uid) { 20.243 + 20.244 + struct passwd pwent; 20.245 + 20.246 + // determine the max pwbuf size from sysconf, and hardcode 20.247 + // a default if this not available through sysconf. 20.248 + // 20.249 + long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); 20.250 + if (bufsize == -1) 20.251 + bufsize = 1024; 20.252 + 20.253 + char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); 20.254 + 20.255 + // POSIX interface to getpwuid_r is used on LINUX 20.256 + struct passwd* p; 20.257 + int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); 20.258 + 20.259 + if (result != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') { 20.260 + if (PrintMiscellaneous && Verbose) { 20.261 + if (result != 0) { 20.262 + warning("Could not retrieve passwd entry: %s\n", 20.263 + strerror(result)); 20.264 + } 20.265 + else if (p == NULL) { 20.266 + // this check is added to protect against an observed problem 20.267 + // with getpwuid_r() on RedHat 9 where getpwuid_r returns 0, 20.268 + // indicating success, but has p == NULL. This was observed when 20.269 + // inserting a file descriptor exhaustion fault prior to the call 20.270 + // getpwuid_r() call. In this case, error is set to the appropriate 20.271 + // error condition, but this is undocumented behavior. This check 20.272 + // is safe under any condition, but the use of errno in the output 20.273 + // message may result in an erroneous message. 20.274 + // Bug Id 89052 was opened with RedHat. 20.275 + // 20.276 + warning("Could not retrieve passwd entry: %s\n", 20.277 + strerror(errno)); 20.278 + } 20.279 + else { 20.280 + warning("Could not determine user name: %s\n", 20.281 + p->pw_name == NULL ? "pw_name = NULL" : 20.282 + "pw_name zero length"); 20.283 + } 20.284 + } 20.285 + FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); 20.286 + return NULL; 20.287 + } 20.288 + 20.289 + char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal); 20.290 + strcpy(user_name, p->pw_name); 20.291 + 20.292 + FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); 20.293 + return user_name; 20.294 +} 20.295 + 20.296 +// return the name of the user that owns the process identified by vmid. 20.297 +// 20.298 +// This method uses a slow directory search algorithm to find the backing 20.299 +// store file for the specified vmid and returns the user name, as determined 20.300 +// by the user name suffix of the hsperfdata_<username> directory name. 20.301 +// 20.302 +// the caller is expected to free the allocated memory. 20.303 +// 20.304 +static char* get_user_name_slow(int vmid, TRAPS) { 20.305 + 20.306 + // short circuit the directory search if the process doesn't even exist. 20.307 + if (kill(vmid, 0) == OS_ERR) { 20.308 + if (errno == ESRCH) { 20.309 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 20.310 + "Process not found"); 20.311 + } 20.312 + else /* EPERM */ { 20.313 + THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno)); 20.314 + } 20.315 + } 20.316 + 20.317 + // directory search 20.318 + char* oldest_user = NULL; 20.319 + time_t oldest_ctime = 0; 20.320 + 20.321 + const char* tmpdirname = os::get_temp_directory(); 20.322 + 20.323 + DIR* tmpdirp = os::opendir(tmpdirname); 20.324 + 20.325 + if (tmpdirp == NULL) { 20.326 + return NULL; 20.327 + } 20.328 + 20.329 + // for each entry in the directory that matches the pattern hsperfdata_*, 20.330 + // open the directory and check if the file for the given vmid exists. 20.331 + // The file with the expected name and the latest creation date is used 20.332 + // to determine the user name for the process id. 20.333 + // 20.334 + struct dirent* dentry; 20.335 + char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); 20.336 + errno = 0; 20.337 + while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { 20.338 + 20.339 + // check if the directory entry is a hsperfdata file 20.340 + if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { 20.341 + continue; 20.342 + } 20.343 + 20.344 + char* usrdir_name = NEW_C_HEAP_ARRAY(char, 20.345 + strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal); 20.346 + strcpy(usrdir_name, tmpdirname); 20.347 + strcat(usrdir_name, "/"); 20.348 + strcat(usrdir_name, dentry->d_name); 20.349 + 20.350 + DIR* subdirp = os::opendir(usrdir_name); 20.351 + 20.352 + if (subdirp == NULL) { 20.353 + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); 20.354 + continue; 20.355 + } 20.356 + 20.357 + // Since we don't create the backing store files in directories 20.358 + // pointed to by symbolic links, we also don't follow them when 20.359 + // looking for the files. We check for a symbolic link after the 20.360 + // call to opendir in order to eliminate a small window where the 20.361 + // symlink can be exploited. 20.362 + // 20.363 + if (!is_directory_secure(usrdir_name)) { 20.364 + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); 20.365 + os::closedir(subdirp); 20.366 + continue; 20.367 + } 20.368 + 20.369 + struct dirent* udentry; 20.370 + char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); 20.371 + errno = 0; 20.372 + while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { 20.373 + 20.374 + if (filename_to_pid(udentry->d_name) == vmid) { 20.375 + struct stat statbuf; 20.376 + int result; 20.377 + 20.378 + char* filename = NEW_C_HEAP_ARRAY(char, 20.379 + strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal); 20.380 + 20.381 + strcpy(filename, usrdir_name); 20.382 + strcat(filename, "/"); 20.383 + strcat(filename, udentry->d_name); 20.384 + 20.385 + // don't follow symbolic links for the file 20.386 + RESTARTABLE(::lstat(filename, &statbuf), result); 20.387 + if (result == OS_ERR) { 20.388 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.389 + continue; 20.390 + } 20.391 + 20.392 + // skip over files that are not regular files. 20.393 + if (!S_ISREG(statbuf.st_mode)) { 20.394 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.395 + continue; 20.396 + } 20.397 + 20.398 + // compare and save filename with latest creation time 20.399 + if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { 20.400 + 20.401 + if (statbuf.st_ctime > oldest_ctime) { 20.402 + char* user = strchr(dentry->d_name, '_') + 1; 20.403 + 20.404 + if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal); 20.405 + oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal); 20.406 + 20.407 + strcpy(oldest_user, user); 20.408 + oldest_ctime = statbuf.st_ctime; 20.409 + } 20.410 + } 20.411 + 20.412 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.413 + } 20.414 + } 20.415 + os::closedir(subdirp); 20.416 + FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); 20.417 + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); 20.418 + } 20.419 + os::closedir(tmpdirp); 20.420 + FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); 20.421 + 20.422 + return(oldest_user); 20.423 +} 20.424 + 20.425 +// return the name of the user that owns the JVM indicated by the given vmid. 20.426 +// 20.427 +static char* get_user_name(int vmid, TRAPS) { 20.428 + return get_user_name_slow(vmid, CHECK_NULL); 20.429 +} 20.430 + 20.431 +// return the file name of the backing store file for the named 20.432 +// shared memory region for the given user name and vmid. 20.433 +// 20.434 +// the caller is expected to free the allocated memory. 20.435 +// 20.436 +static char* get_sharedmem_filename(const char* dirname, int vmid) { 20.437 + 20.438 + // add 2 for the file separator and a null terminator. 20.439 + size_t nbytes = strlen(dirname) + UINT_CHARS + 2; 20.440 + 20.441 + char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); 20.442 + snprintf(name, nbytes, "%s/%d", dirname, vmid); 20.443 + 20.444 + return name; 20.445 +} 20.446 + 20.447 + 20.448 +// remove file 20.449 +// 20.450 +// this method removes the file specified by the given path 20.451 +// 20.452 +static void remove_file(const char* path) { 20.453 + 20.454 + int result; 20.455 + 20.456 + // if the file is a directory, the following unlink will fail. since 20.457 + // we don't expect to find directories in the user temp directory, we 20.458 + // won't try to handle this situation. even if accidentially or 20.459 + // maliciously planted, the directory's presence won't hurt anything. 20.460 + // 20.461 + RESTARTABLE(::unlink(path), result); 20.462 + if (PrintMiscellaneous && Verbose && result == OS_ERR) { 20.463 + if (errno != ENOENT) { 20.464 + warning("Could not unlink shared memory backing" 20.465 + " store file %s : %s\n", path, strerror(errno)); 20.466 + } 20.467 + } 20.468 +} 20.469 + 20.470 + 20.471 +// remove file 20.472 +// 20.473 +// this method removes the file with the given file name in the 20.474 +// named directory. 20.475 +// 20.476 +static void remove_file(const char* dirname, const char* filename) { 20.477 + 20.478 + size_t nbytes = strlen(dirname) + strlen(filename) + 2; 20.479 + char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); 20.480 + 20.481 + strcpy(path, dirname); 20.482 + strcat(path, "/"); 20.483 + strcat(path, filename); 20.484 + 20.485 + remove_file(path); 20.486 + 20.487 + FREE_C_HEAP_ARRAY(char, path, mtInternal); 20.488 +} 20.489 + 20.490 + 20.491 +// cleanup stale shared memory resources 20.492 +// 20.493 +// This method attempts to remove all stale shared memory files in 20.494 +// the named user temporary directory. It scans the named directory 20.495 +// for files matching the pattern ^$[0-9]*$. For each file found, the 20.496 +// process id is extracted from the file name and a test is run to 20.497 +// determine if the process is alive. If the process is not alive, 20.498 +// any stale file resources are removed. 20.499 +// 20.500 +static void cleanup_sharedmem_resources(const char* dirname) { 20.501 + 20.502 + // open the user temp directory 20.503 + DIR* dirp = os::opendir(dirname); 20.504 + 20.505 + if (dirp == NULL) { 20.506 + // directory doesn't exist, so there is nothing to cleanup 20.507 + return; 20.508 + } 20.509 + 20.510 + if (!is_directory_secure(dirname)) { 20.511 + // the directory is not a secure directory 20.512 + return; 20.513 + } 20.514 + 20.515 + // for each entry in the directory that matches the expected file 20.516 + // name pattern, determine if the file resources are stale and if 20.517 + // so, remove the file resources. Note, instrumented HotSpot processes 20.518 + // for this user may start and/or terminate during this search and 20.519 + // remove or create new files in this directory. The behavior of this 20.520 + // loop under these conditions is dependent upon the implementation of 20.521 + // opendir/readdir. 20.522 + // 20.523 + struct dirent* entry; 20.524 + char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); 20.525 + errno = 0; 20.526 + while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { 20.527 + 20.528 + pid_t pid = filename_to_pid(entry->d_name); 20.529 + 20.530 + if (pid == 0) { 20.531 + 20.532 + if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 20.533 + 20.534 + // attempt to remove all unexpected files, except "." and ".." 20.535 + remove_file(dirname, entry->d_name); 20.536 + } 20.537 + 20.538 + errno = 0; 20.539 + continue; 20.540 + } 20.541 + 20.542 + // we now have a file name that converts to a valid integer 20.543 + // that could represent a process id . if this process id 20.544 + // matches the current process id or the process is not running, 20.545 + // then remove the stale file resources. 20.546 + // 20.547 + // process liveness is detected by sending signal number 0 to 20.548 + // the process id (see kill(2)). if kill determines that the 20.549 + // process does not exist, then the file resources are removed. 20.550 + // if kill determines that that we don't have permission to 20.551 + // signal the process, then the file resources are assumed to 20.552 + // be stale and are removed because the resources for such a 20.553 + // process should be in a different user specific directory. 20.554 + // 20.555 + if ((pid == os::current_process_id()) || 20.556 + (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) { 20.557 + 20.558 + remove_file(dirname, entry->d_name); 20.559 + } 20.560 + errno = 0; 20.561 + } 20.562 + os::closedir(dirp); 20.563 + FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); 20.564 +} 20.565 + 20.566 +// make the user specific temporary directory. Returns true if 20.567 +// the directory exists and is secure upon return. Returns false 20.568 +// if the directory exists but is either a symlink, is otherwise 20.569 +// insecure, or if an error occurred. 20.570 +// 20.571 +static bool make_user_tmp_dir(const char* dirname) { 20.572 + 20.573 + // create the directory with 0755 permissions. note that the directory 20.574 + // will be owned by euid::egid, which may not be the same as uid::gid. 20.575 + // 20.576 + if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) { 20.577 + if (errno == EEXIST) { 20.578 + // The directory already exists and was probably created by another 20.579 + // JVM instance. However, this could also be the result of a 20.580 + // deliberate symlink. Verify that the existing directory is safe. 20.581 + // 20.582 + if (!is_directory_secure(dirname)) { 20.583 + // directory is not secure 20.584 + if (PrintMiscellaneous && Verbose) { 20.585 + warning("%s directory is insecure\n", dirname); 20.586 + } 20.587 + return false; 20.588 + } 20.589 + } 20.590 + else { 20.591 + // we encountered some other failure while attempting 20.592 + // to create the directory 20.593 + // 20.594 + if (PrintMiscellaneous && Verbose) { 20.595 + warning("could not create directory %s: %s\n", 20.596 + dirname, strerror(errno)); 20.597 + } 20.598 + return false; 20.599 + } 20.600 + } 20.601 + return true; 20.602 +} 20.603 + 20.604 +// create the shared memory file resources 20.605 +// 20.606 +// This method creates the shared memory file with the given size 20.607 +// This method also creates the user specific temporary directory, if 20.608 +// it does not yet exist. 20.609 +// 20.610 +static int create_sharedmem_resources(const char* dirname, const char* filename, size_t size) { 20.611 + 20.612 + // make the user temporary directory 20.613 + if (!make_user_tmp_dir(dirname)) { 20.614 + // could not make/find the directory or the found directory 20.615 + // was not secure 20.616 + return -1; 20.617 + } 20.618 + 20.619 + int result; 20.620 + 20.621 + RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result); 20.622 + if (result == OS_ERR) { 20.623 + if (PrintMiscellaneous && Verbose) { 20.624 + warning("could not create file %s: %s\n", filename, strerror(errno)); 20.625 + } 20.626 + return -1; 20.627 + } 20.628 + 20.629 + // save the file descriptor 20.630 + int fd = result; 20.631 + 20.632 + // set the file size 20.633 + RESTARTABLE(::ftruncate(fd, (off_t)size), result); 20.634 + if (result == OS_ERR) { 20.635 + if (PrintMiscellaneous && Verbose) { 20.636 + warning("could not set shared memory file size: %s\n", strerror(errno)); 20.637 + } 20.638 + RESTARTABLE(::close(fd), result); 20.639 + return -1; 20.640 + } 20.641 + 20.642 + return fd; 20.643 +} 20.644 + 20.645 +// open the shared memory file for the given user and vmid. returns 20.646 +// the file descriptor for the open file or -1 if the file could not 20.647 +// be opened. 20.648 +// 20.649 +static int open_sharedmem_file(const char* filename, int oflags, TRAPS) { 20.650 + 20.651 + // open the file 20.652 + int result; 20.653 + RESTARTABLE(::open(filename, oflags), result); 20.654 + if (result == OS_ERR) { 20.655 + if (errno == ENOENT) { 20.656 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 20.657 + "Process not found"); 20.658 + } 20.659 + else if (errno == EACCES) { 20.660 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 20.661 + "Permission denied"); 20.662 + } 20.663 + else { 20.664 + THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno)); 20.665 + } 20.666 + } 20.667 + 20.668 + return result; 20.669 +} 20.670 + 20.671 +// create a named shared memory region. returns the address of the 20.672 +// memory region on success or NULL on failure. A return value of 20.673 +// NULL will ultimately disable the shared memory feature. 20.674 +// 20.675 +// On Solaris and Linux, the name space for shared memory objects 20.676 +// is the file system name space. 20.677 +// 20.678 +// A monitoring application attaching to a JVM does not need to know 20.679 +// the file system name of the shared memory object. However, it may 20.680 +// be convenient for applications to discover the existence of newly 20.681 +// created and terminating JVMs by watching the file system name space 20.682 +// for files being created or removed. 20.683 +// 20.684 +static char* mmap_create_shared(size_t size) { 20.685 + 20.686 + int result; 20.687 + int fd; 20.688 + char* mapAddress; 20.689 + 20.690 + int vmid = os::current_process_id(); 20.691 + 20.692 + char* user_name = get_user_name(geteuid()); 20.693 + 20.694 + if (user_name == NULL) 20.695 + return NULL; 20.696 + 20.697 + char* dirname = get_user_tmp_dir(user_name); 20.698 + char* filename = get_sharedmem_filename(dirname, vmid); 20.699 + 20.700 + // cleanup any stale shared memory files 20.701 + cleanup_sharedmem_resources(dirname); 20.702 + 20.703 + assert(((size > 0) && (size % os::vm_page_size() == 0)), 20.704 + "unexpected PerfMemory region size"); 20.705 + 20.706 + fd = create_sharedmem_resources(dirname, filename, size); 20.707 + 20.708 + FREE_C_HEAP_ARRAY(char, user_name, mtInternal); 20.709 + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); 20.710 + 20.711 + if (fd == -1) { 20.712 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.713 + return NULL; 20.714 + } 20.715 + 20.716 + mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 20.717 + 20.718 + // attempt to close the file - restart it if it was interrupted, 20.719 + // but ignore other failures 20.720 + RESTARTABLE(::close(fd), result); 20.721 + assert(result != OS_ERR, "could not close file"); 20.722 + 20.723 + if (mapAddress == MAP_FAILED) { 20.724 + if (PrintMiscellaneous && Verbose) { 20.725 + warning("mmap failed - %s\n", strerror(errno)); 20.726 + } 20.727 + remove_file(filename); 20.728 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.729 + return NULL; 20.730 + } 20.731 + 20.732 + // save the file name for use in delete_shared_memory() 20.733 + backing_store_file_name = filename; 20.734 + 20.735 + // clear the shared memory region 20.736 + (void)::memset((void*) mapAddress, 0, size); 20.737 + 20.738 + return mapAddress; 20.739 +} 20.740 + 20.741 +// release a named shared memory region 20.742 +// 20.743 +static void unmap_shared(char* addr, size_t bytes) { 20.744 + // Do not rely on os::reserve_memory/os::release_memory to use mmap. 20.745 + // Use os::reserve_memory/os::release_memory for PerfDisableSharedMem=1, mmap/munmap for PerfDisableSharedMem=0 20.746 + if (::munmap(addr, bytes) == -1) { 20.747 + warning("perfmemory: munmap failed (%d)\n", errno); 20.748 + } 20.749 +} 20.750 + 20.751 +// create the PerfData memory region in shared memory. 20.752 +// 20.753 +static char* create_shared_memory(size_t size) { 20.754 + 20.755 + // create the shared memory region. 20.756 + return mmap_create_shared(size); 20.757 +} 20.758 + 20.759 +// delete the shared PerfData memory region 20.760 +// 20.761 +static void delete_shared_memory(char* addr, size_t size) { 20.762 + 20.763 + // cleanup the persistent shared memory resources. since DestroyJavaVM does 20.764 + // not support unloading of the JVM, unmapping of the memory resource is 20.765 + // not performed. The memory will be reclaimed by the OS upon termination of 20.766 + // the process. The backing store file is deleted from the file system. 20.767 + 20.768 + assert(!PerfDisableSharedMem, "shouldn't be here"); 20.769 + 20.770 + if (backing_store_file_name != NULL) { 20.771 + remove_file(backing_store_file_name); 20.772 + // Don't.. Free heap memory could deadlock os::abort() if it is called 20.773 + // from signal handler. OS will reclaim the heap memory. 20.774 + // FREE_C_HEAP_ARRAY(char, backing_store_file_name, mtInternal); 20.775 + backing_store_file_name = NULL; 20.776 + } 20.777 +} 20.778 + 20.779 +// return the size of the file for the given file descriptor 20.780 +// or 0 if it is not a valid size for a shared memory file 20.781 +// 20.782 +static size_t sharedmem_filesize(int fd, TRAPS) { 20.783 + 20.784 + struct stat statbuf; 20.785 + int result; 20.786 + 20.787 + RESTARTABLE(::fstat(fd, &statbuf), result); 20.788 + if (result == OS_ERR) { 20.789 + if (PrintMiscellaneous && Verbose) { 20.790 + warning("fstat failed: %s\n", strerror(errno)); 20.791 + } 20.792 + THROW_MSG_0(vmSymbols::java_io_IOException(), 20.793 + "Could not determine PerfMemory size"); 20.794 + } 20.795 + 20.796 + if ((statbuf.st_size == 0) || 20.797 + ((size_t)statbuf.st_size % os::vm_page_size() != 0)) { 20.798 + THROW_MSG_0(vmSymbols::java_lang_Exception(), 20.799 + "Invalid PerfMemory size"); 20.800 + } 20.801 + 20.802 + return (size_t)statbuf.st_size; 20.803 +} 20.804 + 20.805 +// attach to a named shared memory region. 20.806 +// 20.807 +static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemoryMode mode, char** addr, size_t* sizep, TRAPS) { 20.808 + 20.809 + char* mapAddress; 20.810 + int result; 20.811 + int fd; 20.812 + size_t size; 20.813 + const char* luser = NULL; 20.814 + 20.815 + int mmap_prot; 20.816 + int file_flags; 20.817 + 20.818 + ResourceMark rm; 20.819 + 20.820 + // map the high level access mode to the appropriate permission 20.821 + // constructs for the file and the shared memory mapping. 20.822 + if (mode == PerfMemory::PERF_MODE_RO) { 20.823 + mmap_prot = PROT_READ; 20.824 + file_flags = O_RDONLY; 20.825 + } 20.826 + else if (mode == PerfMemory::PERF_MODE_RW) { 20.827 +#ifdef LATER 20.828 + mmap_prot = PROT_READ | PROT_WRITE; 20.829 + file_flags = O_RDWR; 20.830 +#else 20.831 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 20.832 + "Unsupported access mode"); 20.833 +#endif 20.834 + } 20.835 + else { 20.836 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 20.837 + "Illegal access mode"); 20.838 + } 20.839 + 20.840 + if (user == NULL || strlen(user) == 0) { 20.841 + luser = get_user_name(vmid, CHECK); 20.842 + } 20.843 + else { 20.844 + luser = user; 20.845 + } 20.846 + 20.847 + if (luser == NULL) { 20.848 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 20.849 + "Could not map vmid to user Name"); 20.850 + } 20.851 + 20.852 + char* dirname = get_user_tmp_dir(luser); 20.853 + 20.854 + // since we don't follow symbolic links when creating the backing 20.855 + // store file, we don't follow them when attaching either. 20.856 + // 20.857 + if (!is_directory_secure(dirname)) { 20.858 + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); 20.859 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 20.860 + "Process not found"); 20.861 + } 20.862 + 20.863 + char* filename = get_sharedmem_filename(dirname, vmid); 20.864 + 20.865 + // copy heap memory to resource memory. the open_sharedmem_file 20.866 + // method below need to use the filename, but could throw an 20.867 + // exception. using a resource array prevents the leak that 20.868 + // would otherwise occur. 20.869 + char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); 20.870 + strcpy(rfilename, filename); 20.871 + 20.872 + // free the c heap resources that are no longer needed 20.873 + if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal); 20.874 + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); 20.875 + FREE_C_HEAP_ARRAY(char, filename, mtInternal); 20.876 + 20.877 + // open the shared memory file for the give vmid 20.878 + fd = open_sharedmem_file(rfilename, file_flags, CHECK); 20.879 + assert(fd != OS_ERR, "unexpected value"); 20.880 + 20.881 + if (*sizep == 0) { 20.882 + size = sharedmem_filesize(fd, CHECK); 20.883 + assert(size != 0, "unexpected size"); 20.884 + } else { 20.885 + size = *sizep; 20.886 + } 20.887 + 20.888 + mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0); 20.889 + 20.890 + // attempt to close the file - restart if it gets interrupted, 20.891 + // but ignore other failures 20.892 + RESTARTABLE(::close(fd), result); 20.893 + assert(result != OS_ERR, "could not close file"); 20.894 + 20.895 + if (mapAddress == MAP_FAILED) { 20.896 + if (PrintMiscellaneous && Verbose) { 20.897 + warning("mmap failed: %s\n", strerror(errno)); 20.898 + } 20.899 + THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), 20.900 + "Could not map PerfMemory"); 20.901 + } 20.902 + 20.903 + *addr = mapAddress; 20.904 + *sizep = size; 20.905 + 20.906 + if (PerfTraceMemOps) { 20.907 + tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " 20.908 + INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress); 20.909 + } 20.910 +} 20.911 + 20.912 + 20.913 + 20.914 + 20.915 +// create the PerfData memory region 20.916 +// 20.917 +// This method creates the memory region used to store performance 20.918 +// data for the JVM. The memory may be created in standard or 20.919 +// shared memory. 20.920 +// 20.921 +void PerfMemory::create_memory_region(size_t size) { 20.922 + 20.923 + if (PerfDisableSharedMem) { 20.924 + // do not share the memory for the performance data. 20.925 + _start = create_standard_memory(size); 20.926 + } 20.927 + else { 20.928 + _start = create_shared_memory(size); 20.929 + if (_start == NULL) { 20.930 + 20.931 + // creation of the shared memory region failed, attempt 20.932 + // to create a contiguous, non-shared memory region instead. 20.933 + // 20.934 + if (PrintMiscellaneous && Verbose) { 20.935 + warning("Reverting to non-shared PerfMemory region.\n"); 20.936 + } 20.937 + PerfDisableSharedMem = true; 20.938 + _start = create_standard_memory(size); 20.939 + } 20.940 + } 20.941 + 20.942 + if (_start != NULL) _capacity = size; 20.943 + 20.944 +} 20.945 + 20.946 +// delete the PerfData memory region 20.947 +// 20.948 +// This method deletes the memory region used to store performance 20.949 +// data for the JVM. The memory region indicated by the <address, size> 20.950 +// tuple will be inaccessible after a call to this method. 20.951 +// 20.952 +void PerfMemory::delete_memory_region() { 20.953 + 20.954 + assert((start() != NULL && capacity() > 0), "verify proper state"); 20.955 + 20.956 + // If user specifies PerfDataSaveFile, it will save the performance data 20.957 + // to the specified file name no matter whether PerfDataSaveToFile is specified 20.958 + // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag 20.959 + // -XX:+PerfDataSaveToFile. 20.960 + if (PerfDataSaveToFile || PerfDataSaveFile != NULL) { 20.961 + save_memory_to_file(start(), capacity()); 20.962 + } 20.963 + 20.964 + if (PerfDisableSharedMem) { 20.965 + delete_standard_memory(start(), capacity()); 20.966 + } 20.967 + else { 20.968 + delete_shared_memory(start(), capacity()); 20.969 + } 20.970 +} 20.971 + 20.972 +// attach to the PerfData memory region for another JVM 20.973 +// 20.974 +// This method returns an <address, size> tuple that points to 20.975 +// a memory buffer that is kept reasonably synchronized with 20.976 +// the PerfData memory region for the indicated JVM. This 20.977 +// buffer may be kept in synchronization via shared memory 20.978 +// or some other mechanism that keeps the buffer updated. 20.979 +// 20.980 +// If the JVM chooses not to support the attachability feature, 20.981 +// this method should throw an UnsupportedOperation exception. 20.982 +// 20.983 +// This implementation utilizes named shared memory to map 20.984 +// the indicated process's PerfData memory region into this JVMs 20.985 +// address space. 20.986 +// 20.987 +void PerfMemory::attach(const char* user, int vmid, PerfMemoryMode mode, char** addrp, size_t* sizep, TRAPS) { 20.988 + 20.989 + if (vmid == 0 || vmid == os::current_process_id()) { 20.990 + *addrp = start(); 20.991 + *sizep = capacity(); 20.992 + return; 20.993 + } 20.994 + 20.995 + mmap_attach_shared(user, vmid, mode, addrp, sizep, CHECK); 20.996 +} 20.997 + 20.998 +// detach from the PerfData memory region of another JVM 20.999 +// 20.1000 +// This method detaches the PerfData memory region of another 20.1001 +// JVM, specified as an <address, size> tuple of a buffer 20.1002 +// in this process's address space. This method may perform 20.1003 +// arbitrary actions to accomplish the detachment. The memory 20.1004 +// region specified by <address, size> will be inaccessible after 20.1005 +// a call to this method. 20.1006 +// 20.1007 +// If the JVM chooses not to support the attachability feature, 20.1008 +// this method should throw an UnsupportedOperation exception. 20.1009 +// 20.1010 +// This implementation utilizes named shared memory to detach 20.1011 +// the indicated process's PerfData memory region from this 20.1012 +// process's address space. 20.1013 +// 20.1014 +void PerfMemory::detach(char* addr, size_t bytes, TRAPS) { 20.1015 + 20.1016 + assert(addr != 0, "address sanity check"); 20.1017 + assert(bytes > 0, "capacity sanity check"); 20.1018 + 20.1019 + if (PerfMemory::contains(addr) || PerfMemory::contains(addr + bytes - 1)) { 20.1020 + // prevent accidental detachment of this process's PerfMemory region 20.1021 + return; 20.1022 + } 20.1023 + 20.1024 + unmap_shared(addr, bytes); 20.1025 +} 20.1026 + 20.1027 +char* PerfMemory::backing_store_filename() { 20.1028 + return backing_store_file_name; 20.1029 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/os/aix/vm/porting_aix.cpp Fri Sep 06 20:16:09 2013 +0200 21.3 @@ -0,0 +1,367 @@ 21.4 +/* 21.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 + * or visit www.oracle.com if you need additional information or have any 21.24 + * questions. 21.25 + * 21.26 + */ 21.27 + 21.28 +#include "asm/assembler.hpp" 21.29 +#include "loadlib_aix.hpp" 21.30 +#include "porting_aix.hpp" 21.31 +#include "utilities/debug.hpp" 21.32 + 21.33 +#include <demangle.h> 21.34 +#include <sys/debug.h> 21.35 + 21.36 +////////////////////////////////// 21.37 +// Provide implementation for dladdr based on LoadedLibraries pool and 21.38 +// traceback table scan (see getFuncName). 21.39 + 21.40 +// Search traceback table in stack, 21.41 +// return procedure name from trace back table. 21.42 +#define MAX_FUNC_SEARCH_LEN 0x10000 21.43 +// Any PC below this value is considered toast. 21.44 +#define MINIMUM_VALUE_FOR_PC ((unsigned int*)0x1024) 21.45 + 21.46 +#define PTRDIFF_BYTES(p1,p2) (((ptrdiff_t)p1) - ((ptrdiff_t)p2)) 21.47 + 21.48 +// Align a pointer without having to cast. 21.49 +inline char* align_ptr_up(char* ptr, intptr_t alignment) { 21.50 + return (char*) align_size_up((intptr_t)ptr, alignment); 21.51 +} 21.52 + 21.53 +// Trace if verbose to tty. 21.54 +// I use these now instead of the Xtrace system because the latter is 21.55 +// not available at init time, hence worthless. Until we fix this, all 21.56 +// tracing here is done with -XX:+Verbose. 21.57 +#define trcVerbose(fmt, ...) { \ 21.58 + if (Verbose) { \ 21.59 + fprintf(stderr, fmt, ##__VA_ARGS__); \ 21.60 + fputc('\n', stderr); fflush(stderr); \ 21.61 + } \ 21.62 +} 21.63 +#define ERRBYE(s) { trcVerbose(s); return -1; } 21.64 + 21.65 +// Unfortunately, the interface of dladdr makes the implementator 21.66 +// responsible for maintaining memory for function name/library 21.67 +// name. I guess this is because most OS's keep those values as part 21.68 +// of the mapped executable image ready to use. On AIX, this doesn't 21.69 +// work, so I have to keep the returned strings. For now, I do this in 21.70 +// a primitive string map. Should this turn out to be a performance 21.71 +// problem, a better hashmap has to be used. 21.72 +class fixed_strings { 21.73 + struct node { 21.74 + char* v; 21.75 + node* next; 21.76 + }; 21.77 + 21.78 + node* first; 21.79 + 21.80 + public: 21.81 + 21.82 + fixed_strings() : first(0) {} 21.83 + ~fixed_strings() { 21.84 + node* n = first; 21.85 + while (n) { 21.86 + node* p = n; 21.87 + n = n->next; 21.88 + free(p->v); 21.89 + delete p; 21.90 + } 21.91 + } 21.92 + 21.93 + char* intern(const char* s) { 21.94 + for (node* n = first; n; n = n->next) { 21.95 + if (strcmp(n->v, s) == 0) { 21.96 + return n->v; 21.97 + } 21.98 + } 21.99 + node* p = new node; 21.100 + p->v = strdup(s); 21.101 + p->next = first; 21.102 + first = p; 21.103 + return p->v; 21.104 + } 21.105 +}; 21.106 + 21.107 +static fixed_strings dladdr_fixed_strings; 21.108 + 21.109 +// Given a code pointer, returns the function name and the displacement. 21.110 +// Function looks for the traceback table at the end of the function. 21.111 +extern "C" int getFuncName( 21.112 + codeptr_t pc, // [in] program counter 21.113 + char* p_name, size_t namelen, // [out] optional: function name ("" if not available) 21.114 + int* p_displacement, // [out] optional: displacement (-1 if not available) 21.115 + const struct tbtable** p_tb, // [out] optional: ptr to traceback table to get further 21.116 + // information (NULL if not available) 21.117 + char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages 21.118 + ) { 21.119 + struct tbtable* tb = 0; 21.120 + unsigned int searchcount = 0; 21.121 + 21.122 + // initialize output parameters 21.123 + if (p_name && namelen > 0) { 21.124 + *p_name = '\0'; 21.125 + } 21.126 + if (p_errmsg && errmsglen > 0) { 21.127 + *p_errmsg = '\0'; 21.128 + } 21.129 + if (p_displacement) { 21.130 + *p_displacement = -1; 21.131 + } 21.132 + if (p_tb) { 21.133 + *p_tb = NULL; 21.134 + } 21.135 + 21.136 + // weed out obvious bogus states 21.137 + if (pc < MINIMUM_VALUE_FOR_PC) { 21.138 + ERRBYE("invalid program counter"); 21.139 + } 21.140 + 21.141 + codeptr_t pc2 = pc; 21.142 + 21.143 + // make sure the pointer is word aligned. 21.144 + pc2 = (codeptr_t) align_ptr_up((char*)pc2, 4); 21.145 + 21.146 + // Find start of traceback table. 21.147 + // (starts after code, is marked by word-aligned (32bit) zeros) 21.148 + while ((*pc2 != NULL) && (searchcount++ < MAX_FUNC_SEARCH_LEN)) { 21.149 + pc2++; 21.150 + } 21.151 + if (*pc2 != 0) { 21.152 + ERRBYE("could not find traceback table within 5000 bytes of program counter"); 21.153 + } 21.154 + // 21.155 + // Set up addressability to the traceback table 21.156 + // 21.157 + tb = (struct tbtable*) (pc2 + 1); 21.158 + 21.159 + // Is this really a traceback table? No way to be sure but 21.160 + // some indicators we can check. 21.161 + if (tb->tb.lang >= 0xf && tb->tb.lang <= 0xfb) { 21.162 + // Language specifiers, go from 0 (C) to 14 (Objective C). 21.163 + // According to spec, 0xf-0xfa reserved, 0xfb-0xff reserved for ibm. 21.164 + ERRBYE("not a traceback table"); 21.165 + } 21.166 + 21.167 + // Existence of fields in the tbtable extension are contingent upon 21.168 + // specific fields in the base table. Check for their existence so 21.169 + // that we can address the function name if it exists. 21.170 + pc2 = (codeptr_t) tb + 21.171 + sizeof(struct tbtable_short)/sizeof(int); 21.172 + if (tb->tb.fixedparms != 0 || tb->tb.floatparms != 0) 21.173 + pc2++; 21.174 + 21.175 + if (tb->tb.has_tboff == TRUE) { 21.176 + 21.177 + // I want to know the displacement 21.178 + const unsigned int tb_offset = *pc2; 21.179 + codeptr_t start_of_procedure = 21.180 + (codeptr_t)(((char*)tb) - 4 - tb_offset); // (-4 to omit leading 0000) 21.181 + 21.182 + // Weed out the cases where we did find the wrong traceback table. 21.183 + if (pc < start_of_procedure) { 21.184 + ERRBYE("could not find (the real) traceback table within 5000 bytes of program counter"); 21.185 + } 21.186 + 21.187 + // return the displacement 21.188 + if (p_displacement) { 21.189 + (*p_displacement) = (int) PTRDIFF_BYTES(pc, start_of_procedure); 21.190 + } 21.191 + 21.192 + pc2++; 21.193 + } else { 21.194 + // return -1 for displacement 21.195 + if (p_displacement) { 21.196 + (*p_displacement) = -1; 21.197 + } 21.198 + } 21.199 + 21.200 + if (tb->tb.int_hndl == TRUE) 21.201 + pc2++; 21.202 + 21.203 + if (tb->tb.has_ctl == TRUE) 21.204 + pc2 += (*pc2) + 1; // don't care 21.205 + 21.206 + // 21.207 + // return function name if it exists. 21.208 + // 21.209 + if (p_name && namelen > 0) { 21.210 + if (tb->tb.name_present) { 21.211 + char buf[256]; 21.212 + const short l = MIN2<short>(*((short*)pc2), sizeof(buf) - 1); 21.213 + memcpy(buf, (char*)pc2 + sizeof(short), l); 21.214 + buf[l] = '\0'; 21.215 + 21.216 + p_name[0] = '\0'; 21.217 + 21.218 + // If it is a C++ name, try and demangle it using the Demangle interface (see demangle.h). 21.219 + char* rest; 21.220 + Name* const name = Demangle(buf, rest); 21.221 + if (name) { 21.222 + const char* const demangled_name = name->Text(); 21.223 + if (demangled_name) { 21.224 + strncpy(p_name, demangled_name, namelen-1); 21.225 + p_name[namelen-1] = '\0'; 21.226 + } 21.227 + delete name; 21.228 + } 21.229 + 21.230 + // Fallback: if demangling did not work, just provide the unmangled name. 21.231 + if (p_name[0] == '\0') { 21.232 + strncpy(p_name, buf, namelen-1); 21.233 + p_name[namelen-1] = '\0'; 21.234 + } 21.235 + 21.236 + } else { 21.237 + strncpy(p_name, "<nameless function>", namelen-1); 21.238 + p_name[namelen-1] = '\0'; 21.239 + } 21.240 + } 21.241 + // Return traceback table, if user wants it. 21.242 + if (p_tb) { 21.243 + (*p_tb) = tb; 21.244 + } 21.245 + 21.246 + return 0; 21.247 +} 21.248 + 21.249 +// Special implementation of dladdr for Aix based on LoadedLibraries 21.250 +// Note: dladdr returns non-zero for ok, 0 for error! 21.251 +// Note: dladdr is not posix, but a non-standard GNU extension. So this tries to 21.252 +// fulfill the contract of dladdr on Linux (see http://linux.die.net/man/3/dladdr) 21.253 +// Note: addr may be both an AIX function descriptor or a real code pointer 21.254 +// to the entry of a function. 21.255 +extern "C" 21.256 +int dladdr(void* addr, Dl_info* info) { 21.257 + 21.258 + if (!addr) { 21.259 + return 0; 21.260 + } 21.261 + 21.262 + assert(info, ""); 21.263 + 21.264 + int rc = 0; 21.265 + 21.266 + const char* const ZEROSTRING = ""; 21.267 + 21.268 + // Always return a string, even if a "" one. Linux dladdr manpage 21.269 + // does not say anything about returning NULL 21.270 + info->dli_fname = ZEROSTRING; 21.271 + info->dli_sname = ZEROSTRING; 21.272 + info->dli_saddr = NULL; 21.273 + 21.274 + address p = (address) addr; 21.275 + const LoadedLibraryModule* lib = NULL; 21.276 + 21.277 + enum { noclue, code, data } type = noclue; 21.278 + 21.279 + trcVerbose("dladdr(%p)...", p); 21.280 + 21.281 + // Note: input address may be a function. I accept both a pointer to 21.282 + // the entry of a function and a pointer to the function decriptor. 21.283 + // (see ppc64 ABI) 21.284 + lib = LoadedLibraries::find_for_text_address(p); 21.285 + if (lib) { 21.286 + type = code; 21.287 + } 21.288 + 21.289 + if (!lib) { 21.290 + // Not a pointer into any text segment. Is it a function descriptor? 21.291 + const FunctionDescriptor* const pfd = (const FunctionDescriptor*) p; 21.292 + p = pfd->entry(); 21.293 + if (p) { 21.294 + lib = LoadedLibraries::find_for_text_address(p); 21.295 + if (lib) { 21.296 + type = code; 21.297 + } 21.298 + } 21.299 + } 21.300 + 21.301 + if (!lib) { 21.302 + // Neither direct code pointer nor function descriptor. A data ptr? 21.303 + p = (address)addr; 21.304 + lib = LoadedLibraries::find_for_data_address(p); 21.305 + if (lib) { 21.306 + type = data; 21.307 + } 21.308 + } 21.309 + 21.310 + // If we did find the shared library this address belongs to (either 21.311 + // code or data segment) resolve library path and, if possible, the 21.312 + // symbol name. 21.313 + if (lib) { 21.314 + const char* const interned_libpath = 21.315 + dladdr_fixed_strings.intern(lib->get_fullpath()); 21.316 + if (interned_libpath) { 21.317 + info->dli_fname = interned_libpath; 21.318 + } 21.319 + 21.320 + if (type == code) { 21.321 + 21.322 + // For code symbols resolve function name and displacement. Use 21.323 + // displacement to calc start of function. 21.324 + char funcname[256] = ""; 21.325 + int displacement = 0; 21.326 + 21.327 + if (getFuncName((codeptr_t) p, funcname, sizeof(funcname), &displacement, 21.328 + NULL, NULL, 0) == 0) { 21.329 + if (funcname[0] != '\0') { 21.330 + const char* const interned = dladdr_fixed_strings.intern(funcname); 21.331 + info->dli_sname = interned; 21.332 + trcVerbose("... function name: %s ...", interned); 21.333 + } 21.334 + 21.335 + // From the displacement calculate the start of the function. 21.336 + if (displacement != -1) { 21.337 + info->dli_saddr = p - displacement; 21.338 + } else { 21.339 + info->dli_saddr = p; 21.340 + } 21.341 + } else { 21.342 + 21.343 + // No traceback table found. Just assume the pointer is it. 21.344 + info->dli_saddr = p; 21.345 + 21.346 + } 21.347 + 21.348 + } else if (type == data) { 21.349 + 21.350 + // For data symbols. 21.351 + info->dli_saddr = p; 21.352 + 21.353 + } else { 21.354 + ShouldNotReachHere(); 21.355 + } 21.356 + 21.357 + rc = 1; // success: return 1 [sic] 21.358 + 21.359 + } 21.360 + 21.361 + // sanity checks. 21.362 + if (rc) { 21.363 + assert(info->dli_fname, ""); 21.364 + assert(info->dli_sname, ""); 21.365 + assert(info->dli_saddr, ""); 21.366 + } 21.367 + 21.368 + return rc; // error: return 0 [sic] 21.369 + 21.370 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/src/os/aix/vm/porting_aix.hpp Fri Sep 06 20:16:09 2013 +0200 22.3 @@ -0,0 +1,81 @@ 22.4 +/* 22.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. 22.11 + * 22.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.15 + * version 2 for more details (a copy is included in the LICENSE file that 22.16 + * accompanied this code). 22.17 + * 22.18 + * You should have received a copy of the GNU General Public License version 22.19 + * 2 along with this work; if not, write to the Free Software Foundation, 22.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.21 + * 22.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.23 + * or visit www.oracle.com if you need additional information or have any 22.24 + * questions. 22.25 + * 22.26 + */ 22.27 + 22.28 +#include <stddef.h> 22.29 + 22.30 +// Header file to contain porting-relevant code which does not have a 22.31 +// home anywhere else and which can not go into os_<platform>.h because 22.32 +// that header is included inside the os class definition, hence all 22.33 +// its content is part of the os class. 22.34 + 22.35 +// Aix' own version of dladdr(). 22.36 +// This function tries to mimick dladdr(3) on Linux 22.37 +// (see http://linux.die.net/man/3/dladdr) 22.38 +// dladdr(3) is not POSIX but a GNU extension, and is not available on AIX. 22.39 +// 22.40 +// Differences between AIX dladdr and Linux dladdr: 22.41 +// 22.42 +// 1) Dl_info.dli_fbase: can never work, is disabled. 22.43 +// A loaded image on AIX is divided in multiple segments, at least two 22.44 +// (text and data) but potentially also far more. This is because the loader may 22.45 +// load each member into an own segment, as for instance happens with the libC.a 22.46 +// 2) Dl_info.dli_sname: This only works for code symbols (functions); for data, a 22.47 +// zero-length string is returned (""). 22.48 +// 3) Dl_info.dli_saddr: For code, this will return the entry point of the function, 22.49 +// not the function descriptor. 22.50 + 22.51 +typedef struct { 22.52 + const char *dli_fname; // file path of loaded library 22.53 + // void *dli_fbase; 22.54 + const char *dli_sname; // symbol name; "" if not known 22.55 + void *dli_saddr; // address of *entry* of function; not function descriptor; 22.56 +} Dl_info; 22.57 + 22.58 +// Note: we export this to use it inside J2se too 22.59 +#ifdef __cplusplus 22.60 +extern "C" 22.61 +#endif 22.62 +int dladdr(void *addr, Dl_info *info); 22.63 + 22.64 + 22.65 +// The semantics in this file are thus that codeptr_t is a *real code ptr*. 22.66 +// This means that any function taking codeptr_t as arguments will assume 22.67 +// a real codeptr and won't handle function descriptors (eg getFuncName), 22.68 +// whereas functions taking address as args will deal with function 22.69 +// descriptors (eg os::dll_address_to_library_name). 22.70 +typedef unsigned int* codeptr_t; 22.71 + 22.72 +// helper function - given a program counter, tries to locate the traceback table and 22.73 +// returns info from it (like, most importantly, function name, displacement of the 22.74 +// pc inside the function, and the traceback table itself. 22.75 +#ifdef __cplusplus 22.76 +extern "C" 22.77 +#endif 22.78 +int getFuncName( 22.79 + codeptr_t pc, // [in] program counter 22.80 + char* p_name, size_t namelen, // [out] optional: user provided buffer for the function name 22.81 + int* p_displacement, // [out] optional: displacement 22.82 + const struct tbtable** p_tb, // [out] optional: ptr to traceback table to get further information 22.83 + char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages 22.84 + );
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/src/os/aix/vm/threadCritical_aix.cpp Fri Sep 06 20:16:09 2013 +0200 23.3 @@ -0,0 +1,68 @@ 23.4 +/* 23.5 + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 23.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 23.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 + * 23.9 + * This code is free software; you can redistribute it and/or modify it 23.10 + * under the terms of the GNU General Public License version 2 only, as 23.11 + * published by the Free Software Foundation. 23.12 + * 23.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.16 + * version 2 for more details (a copy is included in the LICENSE file that 23.17 + * accompanied this code). 23.18 + * 23.19 + * You should have received a copy of the GNU General Public License version 23.20 + * 2 along with this work; if not, write to the Free Software Foundation, 23.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.22 + * 23.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.24 + * or visit www.oracle.com if you need additional information or have any 23.25 + * questions. 23.26 + * 23.27 + */ 23.28 + 23.29 +#include "precompiled.hpp" 23.30 +#include "runtime/threadCritical.hpp" 23.31 +#include "thread_aix.inline.hpp" 23.32 + 23.33 +// put OS-includes here 23.34 +# include <pthread.h> 23.35 + 23.36 +// 23.37 +// See threadCritical.hpp for details of this class. 23.38 +// 23.39 + 23.40 +static pthread_t tc_owner = 0; 23.41 +static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER; 23.42 +static int tc_count = 0; 23.43 + 23.44 +void ThreadCritical::initialize() { 23.45 +} 23.46 + 23.47 +void ThreadCritical::release() { 23.48 +} 23.49 + 23.50 +ThreadCritical::ThreadCritical() { 23.51 + pthread_t self = pthread_self(); 23.52 + if (self != tc_owner) { 23.53 + int ret = pthread_mutex_lock(&tc_mutex); 23.54 + guarantee(ret == 0, "fatal error with pthread_mutex_lock()"); 23.55 + assert(tc_count == 0, "Lock acquired with illegal reentry count."); 23.56 + tc_owner = self; 23.57 + } 23.58 + tc_count++; 23.59 +} 23.60 + 23.61 +ThreadCritical::~ThreadCritical() { 23.62 + assert(tc_owner == pthread_self(), "must have correct owner"); 23.63 + assert(tc_count > 0, "must have correct count"); 23.64 + 23.65 + tc_count--; 23.66 + if (tc_count == 0) { 23.67 + tc_owner = 0; 23.68 + int ret = pthread_mutex_unlock(&tc_mutex); 23.69 + guarantee(ret == 0, "fatal error with pthread_mutex_unlock()"); 23.70 + } 23.71 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/src/os/aix/vm/thread_aix.inline.hpp Fri Sep 06 20:16:09 2013 +0200 24.3 @@ -0,0 +1,42 @@ 24.4 +/* 24.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 24.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 + * 24.9 + * This code is free software; you can redistribute it and/or modify it 24.10 + * under the terms of the GNU General Public License version 2 only, as 24.11 + * published by the Free Software Foundation. 24.12 + * 24.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 24.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.16 + * version 2 for more details (a copy is included in the LICENSE file that 24.17 + * accompanied this code). 24.18 + * 24.19 + * You should have received a copy of the GNU General Public License version 24.20 + * 2 along with this work; if not, write to the Free Software Foundation, 24.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.22 + * 24.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24.24 + * or visit www.oracle.com if you need additional information or have any 24.25 + * questions. 24.26 + * 24.27 + */ 24.28 + 24.29 +#ifndef OS_AIX_VM_THREAD_AIX_INLINE_HPP 24.30 +#define OS_AIX_VM_THREAD_AIX_INLINE_HPP 24.31 + 24.32 +#include "runtime/atomic.hpp" 24.33 +#include "runtime/prefetch.hpp" 24.34 +#include "runtime/thread.hpp" 24.35 +#include "runtime/threadLocalStorage.hpp" 24.36 + 24.37 +#include "atomic_aix_ppc.inline.hpp" 24.38 +#include "orderAccess_aix_ppc.inline.hpp" 24.39 +#include "prefetch_aix_ppc.inline.hpp" 24.40 + 24.41 +// Contains inlined functions for class Thread and ThreadLocalStorage 24.42 + 24.43 +inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do 24.44 + 24.45 +#endif // OS_AIX_VM_THREAD_AIX_INLINE_HPP
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/src/os/aix/vm/vmError_aix.cpp Fri Sep 06 20:16:09 2013 +0200 25.3 @@ -0,0 +1,122 @@ 25.4 +/* 25.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.7 + * 25.8 + * This code is free software; you can redistribute it and/or modify it 25.9 + * under the terms of the GNU General Public License version 2 only, as 25.10 + * published by the Free Software Foundation. 25.11 + * 25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25.15 + * version 2 for more details (a copy is included in the LICENSE file that 25.16 + * accompanied this code). 25.17 + * 25.18 + * You should have received a copy of the GNU General Public License version 25.19 + * 2 along with this work; if not, write to the Free Software Foundation, 25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 25.21 + * 25.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 25.23 + * or visit www.oracle.com if you need additional information or have any 25.24 + * questions. 25.25 + * 25.26 + */ 25.27 + 25.28 +#include "precompiled.hpp" 25.29 +#include "runtime/arguments.hpp" 25.30 +#include "runtime/os.hpp" 25.31 +#include "runtime/thread.hpp" 25.32 +#include "utilities/vmError.hpp" 25.33 + 25.34 +#include <sys/types.h> 25.35 +#include <sys/wait.h> 25.36 +#include <unistd.h> 25.37 +#include <signal.h> 25.38 + 25.39 +void VMError::show_message_box(char *buf, int buflen) { 25.40 + bool yes; 25.41 + do { 25.42 + error_string(buf, buflen); 25.43 + int len = (int)strlen(buf); 25.44 + char *p = &buf[len]; 25.45 + 25.46 + jio_snprintf(p, buflen - len, 25.47 + "\n\n" 25.48 + "Do you want to debug the problem?\n\n" 25.49 + "To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n" 25.50 + "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n" 25.51 + "Otherwise, press RETURN to abort...", 25.52 + os::current_process_id(), 25.53 + os::current_thread_id(), thread_self()); 25.54 + 25.55 + yes = os::message_box("Unexpected Error", buf); 25.56 + 25.57 + if (yes) { 25.58 + // yes, user asked VM to launch debugger 25.59 + jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id()); 25.60 + 25.61 + os::fork_and_exec(buf); 25.62 + yes = false; 25.63 + } 25.64 + } while (yes); 25.65 +} 25.66 + 25.67 +// Handle all synchronous signals which may happen during signal handling, 25.68 +// not just SIGSEGV and SIGBUS. 25.69 +static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed 25.70 +static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int); 25.71 + 25.72 +// Space for our "saved" signal flags and handlers 25.73 +static int resettedSigflags[NUM_SIGNALS]; 25.74 +static address resettedSighandler[NUM_SIGNALS]; 25.75 + 25.76 +static void save_signal(int idx, int sig) { 25.77 + struct sigaction sa; 25.78 + sigaction(sig, NULL, &sa); 25.79 + resettedSigflags[idx] = sa.sa_flags; 25.80 + resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO) 25.81 + ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) 25.82 + : CAST_FROM_FN_PTR(address, sa.sa_handler); 25.83 +} 25.84 + 25.85 +int VMError::get_resetted_sigflags(int sig) { 25.86 + // Handle all program errors. 25.87 + for (int i = 0; i < NUM_SIGNALS; i++) { 25.88 + if (SIGNALS[i] == sig) { 25.89 + return resettedSigflags[i]; 25.90 + } 25.91 + } 25.92 + return -1; 25.93 +} 25.94 + 25.95 +address VMError::get_resetted_sighandler(int sig) { 25.96 + // Handle all program errors. 25.97 + for (int i = 0; i < NUM_SIGNALS; i++) { 25.98 + if (SIGNALS[i] == sig) { 25.99 + return resettedSighandler[i]; 25.100 + } 25.101 + } 25.102 + return NULL; 25.103 +} 25.104 + 25.105 +static void crash_handler(int sig, siginfo_t* info, void* ucVoid) { 25.106 + // Unmask current signal. 25.107 + sigset_t newset; 25.108 + sigemptyset(&newset); 25.109 + sigaddset(&newset, sig); 25.110 + 25.111 + Unimplemented(); 25.112 +} 25.113 + 25.114 +void VMError::reset_signal_handlers() { 25.115 + sigset_t newset; 25.116 + sigemptyset(&newset); 25.117 + 25.118 + for (int i = 0; i < NUM_SIGNALS; i++) { 25.119 + save_signal(i, SIGNALS[i]); 25.120 + os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler)); 25.121 + sigaddset(&newset, SIGNALS[i]); 25.122 + } 25.123 + 25.124 + sigthreadmask(SIG_UNBLOCK, &newset, NULL); 25.125 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp Fri Sep 06 20:16:09 2013 +0200 26.3 @@ -0,0 +1,401 @@ 26.4 +/* 26.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 26.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 26.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.8 + * 26.9 + * This code is free software; you can redistribute it and/or modify it 26.10 + * under the terms of the GNU General Public License version 2 only, as 26.11 + * published by the Free Software Foundation. 26.12 + * 26.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 26.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 26.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26.16 + * version 2 for more details (a copy is included in the LICENSE file that 26.17 + * accompanied this code). 26.18 + * 26.19 + * You should have received a copy of the GNU General Public License version 26.20 + * 2 along with this work; if not, write to the Free Software Foundation, 26.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26.22 + * 26.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 26.24 + * or visit www.oracle.com if you need additional information or have any 26.25 + * questions. 26.26 + * 26.27 + */ 26.28 + 26.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP 26.30 +#define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP 26.31 + 26.32 +#include "orderAccess_aix_ppc.inline.hpp" 26.33 +#include "runtime/atomic.hpp" 26.34 +#include "runtime/os.hpp" 26.35 +#include "vm_version_ppc.hpp" 26.36 + 26.37 +#ifndef _LP64 26.38 +#error "Atomic currently only impleneted for PPC64" 26.39 +#endif 26.40 + 26.41 +// Implementation of class atomic 26.42 + 26.43 +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } 26.44 +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } 26.45 +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } 26.46 +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } 26.47 +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } 26.48 +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } 26.49 + 26.50 +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } 26.51 +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } 26.52 +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } 26.53 +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } 26.54 +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } 26.55 +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } 26.56 + 26.57 +inline jlong Atomic::load(volatile jlong* src) { return *src; } 26.58 + 26.59 +/* 26.60 + machine barrier instructions: 26.61 + 26.62 + - ppc_sync two-way memory barrier, aka fence 26.63 + - ppc_lwsync orders Store|Store, 26.64 + Load|Store, 26.65 + Load|Load, 26.66 + but not Store|Load 26.67 + - ppc_eieio orders memory accesses for device memory (only) 26.68 + - ppc_isync invalidates speculatively executed instructions 26.69 + From the POWER ISA 2.06 documentation: 26.70 + "[...] an isync instruction prevents the execution of 26.71 + instructions following the isync until instructions 26.72 + preceding the isync have completed, [...]" 26.73 + From IBM's AIX assembler reference: 26.74 + "The isync [...] instructions causes the processor to 26.75 + refetch any instructions that might have been fetched 26.76 + prior to the isync instruction. The instruction isync 26.77 + causes the processor to wait for all previous instructions 26.78 + to complete. Then any instructions already fetched are 26.79 + discarded and instruction processing continues in the 26.80 + environment established by the previous instructions." 26.81 + 26.82 + semantic barrier instructions: 26.83 + (as defined in orderAccess.hpp) 26.84 + 26.85 + - ppc_release orders Store|Store, (maps to ppc_lwsync) 26.86 + Load|Store 26.87 + - ppc_acquire orders Load|Store, (maps to ppc_lwsync) 26.88 + Load|Load 26.89 + - ppc_fence orders Store|Store, (maps to ppc_sync) 26.90 + Load|Store, 26.91 + Load|Load, 26.92 + Store|Load 26.93 +*/ 26.94 + 26.95 +#define strasm_ppc_sync "\n sync \n" 26.96 +#define strasm_ppc_lwsync "\n lwsync \n" 26.97 +#define strasm_ppc_isync "\n isync \n" 26.98 +#define strasm_ppc_release strasm_ppc_lwsync 26.99 +#define strasm_ppc_acquire strasm_ppc_lwsync 26.100 +#define strasm_ppc_fence strasm_ppc_sync 26.101 +#define strasm_ppc_nobarrier "" 26.102 +#define strasm_ppc_nobarrier_clobber_memory "" 26.103 + 26.104 +inline jint Atomic::add (jint add_value, volatile jint* dest) { 26.105 + 26.106 + unsigned int result; 26.107 + 26.108 + __asm__ __volatile__ ( 26.109 + strasm_ppc_lwsync 26.110 + "1: lwarx %0, 0, %2 \n" 26.111 + " add %0, %0, %1 \n" 26.112 + " stwcx. %0, 0, %2 \n" 26.113 + " bne- 1b \n" 26.114 + strasm_ppc_isync 26.115 + : /*%0*/"=&r" (result) 26.116 + : /*%1*/"r" (add_value), /*%2*/"r" (dest) 26.117 + : "cc", "memory" ); 26.118 + 26.119 + return (jint) result; 26.120 +} 26.121 + 26.122 + 26.123 +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { 26.124 + 26.125 + long result; 26.126 + 26.127 + __asm__ __volatile__ ( 26.128 + strasm_ppc_lwsync 26.129 + "1: ldarx %0, 0, %2 \n" 26.130 + " add %0, %0, %1 \n" 26.131 + " stdcx. %0, 0, %2 \n" 26.132 + " bne- 1b \n" 26.133 + strasm_ppc_isync 26.134 + : /*%0*/"=&r" (result) 26.135 + : /*%1*/"r" (add_value), /*%2*/"r" (dest) 26.136 + : "cc", "memory" ); 26.137 + 26.138 + return (intptr_t) result; 26.139 +} 26.140 + 26.141 +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { 26.142 + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); 26.143 +} 26.144 + 26.145 + 26.146 +inline void Atomic::inc (volatile jint* dest) { 26.147 + 26.148 + unsigned int temp; 26.149 + 26.150 + __asm__ __volatile__ ( 26.151 + strasm_ppc_nobarrier 26.152 + "1: lwarx %0, 0, %2 \n" 26.153 + " addic %0, %0, 1 \n" 26.154 + " stwcx. %0, 0, %2 \n" 26.155 + " bne- 1b \n" 26.156 + strasm_ppc_nobarrier 26.157 + : /*%0*/"=&r" (temp), "=m" (*dest) 26.158 + : /*%2*/"r" (dest), "m" (*dest) 26.159 + : "cc" strasm_ppc_nobarrier_clobber_memory); 26.160 + 26.161 +} 26.162 + 26.163 +inline void Atomic::inc_ptr(volatile intptr_t* dest) { 26.164 + 26.165 + long temp; 26.166 + 26.167 + __asm__ __volatile__ ( 26.168 + strasm_ppc_nobarrier 26.169 + "1: ldarx %0, 0, %2 \n" 26.170 + " addic %0, %0, 1 \n" 26.171 + " stdcx. %0, 0, %2 \n" 26.172 + " bne- 1b \n" 26.173 + strasm_ppc_nobarrier 26.174 + : /*%0*/"=&r" (temp), "=m" (*dest) 26.175 + : /*%2*/"r" (dest), "m" (*dest) 26.176 + : "cc" strasm_ppc_nobarrier_clobber_memory); 26.177 + 26.178 +} 26.179 + 26.180 +inline void Atomic::inc_ptr(volatile void* dest) { 26.181 + inc_ptr((volatile intptr_t*)dest); 26.182 +} 26.183 + 26.184 + 26.185 +inline void Atomic::dec (volatile jint* dest) { 26.186 + 26.187 + unsigned int temp; 26.188 + 26.189 + __asm__ __volatile__ ( 26.190 + strasm_ppc_nobarrier 26.191 + "1: lwarx %0, 0, %2 \n" 26.192 + " addic %0, %0, -1 \n" 26.193 + " stwcx. %0, 0, %2 \n" 26.194 + " bne- 1b \n" 26.195 + strasm_ppc_nobarrier 26.196 + : /*%0*/"=&r" (temp), "=m" (*dest) 26.197 + : /*%2*/"r" (dest), "m" (*dest) 26.198 + : "cc" strasm_ppc_nobarrier_clobber_memory); 26.199 + 26.200 +} 26.201 + 26.202 +inline void Atomic::dec_ptr(volatile intptr_t* dest) { 26.203 + 26.204 + long temp; 26.205 + 26.206 + __asm__ __volatile__ ( 26.207 + strasm_ppc_nobarrier 26.208 + "1: ldarx %0, 0, %2 \n" 26.209 + " addic %0, %0, -1 \n" 26.210 + " stdcx. %0, 0, %2 \n" 26.211 + " bne- 1b \n" 26.212 + strasm_ppc_nobarrier 26.213 + : /*%0*/"=&r" (temp), "=m" (*dest) 26.214 + : /*%2*/"r" (dest), "m" (*dest) 26.215 + : "cc" strasm_ppc_nobarrier_clobber_memory); 26.216 + 26.217 +} 26.218 + 26.219 +inline void Atomic::dec_ptr(volatile void* dest) { 26.220 + dec_ptr((volatile intptr_t*)dest); 26.221 +} 26.222 + 26.223 +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { 26.224 + 26.225 + // Note that xchg_ptr doesn't necessarily do an acquire 26.226 + // (see synchronizer.cpp). 26.227 + 26.228 + unsigned int old_value; 26.229 + const uint64_t zero = 0; 26.230 + 26.231 + __asm__ __volatile__ ( 26.232 + /* lwsync */ 26.233 + strasm_ppc_lwsync 26.234 + /* atomic loop */ 26.235 + "1: \n" 26.236 + " lwarx %[old_value], %[dest], %[zero] \n" 26.237 + " stwcx. %[exchange_value], %[dest], %[zero] \n" 26.238 + " bne- 1b \n" 26.239 + /* isync */ 26.240 + strasm_ppc_sync 26.241 + /* exit */ 26.242 + "2: \n" 26.243 + /* out */ 26.244 + : [old_value] "=&r" (old_value), 26.245 + "=m" (*dest) 26.246 + /* in */ 26.247 + : [dest] "b" (dest), 26.248 + [zero] "r" (zero), 26.249 + [exchange_value] "r" (exchange_value), 26.250 + "m" (*dest) 26.251 + /* clobber */ 26.252 + : "cc", 26.253 + "memory" 26.254 + ); 26.255 + 26.256 + return (jint) old_value; 26.257 +} 26.258 + 26.259 +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { 26.260 + 26.261 + // Note that xchg_ptr doesn't necessarily do an acquire 26.262 + // (see synchronizer.cpp). 26.263 + 26.264 + long old_value; 26.265 + const uint64_t zero = 0; 26.266 + 26.267 + __asm__ __volatile__ ( 26.268 + /* lwsync */ 26.269 + strasm_ppc_lwsync 26.270 + /* atomic loop */ 26.271 + "1: \n" 26.272 + " ldarx %[old_value], %[dest], %[zero] \n" 26.273 + " stdcx. %[exchange_value], %[dest], %[zero] \n" 26.274 + " bne- 1b \n" 26.275 + /* isync */ 26.276 + strasm_ppc_sync 26.277 + /* exit */ 26.278 + "2: \n" 26.279 + /* out */ 26.280 + : [old_value] "=&r" (old_value), 26.281 + "=m" (*dest) 26.282 + /* in */ 26.283 + : [dest] "b" (dest), 26.284 + [zero] "r" (zero), 26.285 + [exchange_value] "r" (exchange_value), 26.286 + "m" (*dest) 26.287 + /* clobber */ 26.288 + : "cc", 26.289 + "memory" 26.290 + ); 26.291 + 26.292 + return (intptr_t) old_value; 26.293 +} 26.294 + 26.295 +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { 26.296 + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); 26.297 +} 26.298 + 26.299 +inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) { 26.300 + 26.301 + // Note that cmpxchg guarantees a two-way memory barrier across 26.302 + // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire' 26.303 + // (see atomic.hpp). 26.304 + 26.305 + unsigned int old_value; 26.306 + const uint64_t zero = 0; 26.307 + 26.308 + __asm__ __volatile__ ( 26.309 + /* fence */ 26.310 + strasm_ppc_sync 26.311 + /* simple guard */ 26.312 + " lwz %[old_value], 0(%[dest]) \n" 26.313 + " cmpw %[compare_value], %[old_value] \n" 26.314 + " bne- 2f \n" 26.315 + /* atomic loop */ 26.316 + "1: \n" 26.317 + " lwarx %[old_value], %[dest], %[zero] \n" 26.318 + " cmpw %[compare_value], %[old_value] \n" 26.319 + " bne- 2f \n" 26.320 + " stwcx. %[exchange_value], %[dest], %[zero] \n" 26.321 + " bne- 1b \n" 26.322 + /* acquire */ 26.323 + strasm_ppc_sync 26.324 + /* exit */ 26.325 + "2: \n" 26.326 + /* out */ 26.327 + : [old_value] "=&r" (old_value), 26.328 + "=m" (*dest) 26.329 + /* in */ 26.330 + : [dest] "b" (dest), 26.331 + [zero] "r" (zero), 26.332 + [compare_value] "r" (compare_value), 26.333 + [exchange_value] "r" (exchange_value), 26.334 + "m" (*dest) 26.335 + /* clobber */ 26.336 + : "cc", 26.337 + "memory" 26.338 + ); 26.339 + 26.340 + return (jint) old_value; 26.341 +} 26.342 + 26.343 +inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value) { 26.344 + 26.345 + // Note that cmpxchg guarantees a two-way memory barrier across 26.346 + // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire' 26.347 + // (see atomic.hpp). 26.348 + 26.349 + long old_value; 26.350 + const uint64_t zero = 0; 26.351 + 26.352 + __asm__ __volatile__ ( 26.353 + /* fence */ 26.354 + strasm_ppc_sync 26.355 + /* simple guard */ 26.356 + " ld %[old_value], 0(%[dest]) \n" 26.357 + " cmpd %[compare_value], %[old_value] \n" 26.358 + " bne- 2f \n" 26.359 + /* atomic loop */ 26.360 + "1: \n" 26.361 + " ldarx %[old_value], %[dest], %[zero] \n" 26.362 + " cmpd %[compare_value], %[old_value] \n" 26.363 + " bne- 2f \n" 26.364 + " stdcx. %[exchange_value], %[dest], %[zero] \n" 26.365 + " bne- 1b \n" 26.366 + /* acquire */ 26.367 + strasm_ppc_sync 26.368 + /* exit */ 26.369 + "2: \n" 26.370 + /* out */ 26.371 + : [old_value] "=&r" (old_value), 26.372 + "=m" (*dest) 26.373 + /* in */ 26.374 + : [dest] "b" (dest), 26.375 + [zero] "r" (zero), 26.376 + [compare_value] "r" (compare_value), 26.377 + [exchange_value] "r" (exchange_value), 26.378 + "m" (*dest) 26.379 + /* clobber */ 26.380 + : "cc", 26.381 + "memory" 26.382 + ); 26.383 + 26.384 + return (jlong) old_value; 26.385 +} 26.386 + 26.387 +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { 26.388 + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); 26.389 +} 26.390 + 26.391 +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { 26.392 + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); 26.393 +} 26.394 + 26.395 +#undef strasm_ppc_sync 26.396 +#undef strasm_ppc_lwsync 26.397 +#undef strasm_ppc_isync 26.398 +#undef strasm_ppc_release 26.399 +#undef strasm_ppc_acquire 26.400 +#undef strasm_ppc_fence 26.401 +#undef strasm_ppc_nobarrier 26.402 +#undef strasm_ppc_nobarrier_clobber_memory 26.403 + 26.404 +#endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp Fri Sep 06 20:16:09 2013 +0200 27.3 @@ -0,0 +1,54 @@ 27.4 +/* 27.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 27.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 27.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.8 + * 27.9 + * This code is free software; you can redistribute it and/or modify it 27.10 + * under the terms of the GNU General Public License version 2 only, as 27.11 + * published by the Free Software Foundation. 27.12 + * 27.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.16 + * version 2 for more details (a copy is included in the LICENSE file that 27.17 + * accompanied this code). 27.18 + * 27.19 + * You should have received a copy of the GNU General Public License version 27.20 + * 2 along with this work; if not, write to the Free Software Foundation, 27.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.22 + * 27.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.24 + * or visit www.oracle.com if you need additional information or have any 27.25 + * questions. 27.26 + * 27.27 + */ 27.28 + 27.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_GLOBALS_AIX_PPC_HPP 27.30 +#define OS_CPU_AIX_OJDKPPC_VM_GLOBALS_AIX_PPC_HPP 27.31 + 27.32 +// Sets the default values for platform dependent flags used by the runtime system. 27.33 +// (see globals.hpp) 27.34 + 27.35 +define_pd_global(bool, DontYieldALot, false); 27.36 +define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default 27.37 +define_pd_global(intx, VMThreadStackSize, 2048); 27.38 + 27.39 +// if we set CompilerThreadStackSize to a value different than 0, it will 27.40 +// be used in os::create_thread(). Otherwise, due the strange logic in os::create_thread(), 27.41 +// the stack size for compiler threads will default to VMThreadStackSize, although it 27.42 +// is defined to 4M in os::Aix::default_stack_size()! 27.43 +define_pd_global(intx, CompilerThreadStackSize, 4096); 27.44 + 27.45 +// Allow extra space in DEBUG builds for asserts. 27.46 +define_pd_global(uintx,JVMInvokeMethodSlack, 8192); 27.47 + 27.48 +define_pd_global(intx, StackYellowPages, 6); 27.49 +define_pd_global(intx, StackRedPages, 1); 27.50 +define_pd_global(intx, StackShadowPages, 6 DEBUG_ONLY(+2)); 27.51 + 27.52 +// Only used on 64 bit platforms 27.53 +define_pd_global(uintx,HeapBaseMinAddress, 2*G); 27.54 +// Only used on 64 bit Windows platforms 27.55 +define_pd_global(bool, UseVectoredExceptions, false); 27.56 + 27.57 +#endif // OS_CPU_AIX_OJDKPPC_VM_GLOBALS_AIX_PPC_HPP
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/src/os_cpu/aix_ppc/vm/orderAccess_aix_ppc.inline.hpp Fri Sep 06 20:16:09 2013 +0200 28.3 @@ -0,0 +1,147 @@ 28.4 +/* 28.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 28.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 28.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 + * 28.9 + * This code is free software; you can redistribute it and/or modify it 28.10 + * under the terms of the GNU General Public License version 2 only, as 28.11 + * published by the Free Software Foundation. 28.12 + * 28.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.16 + * version 2 for more details (a copy is included in the LICENSE file that 28.17 + * accompanied this code). 28.18 + * 28.19 + * You should have received a copy of the GNU General Public License version 28.20 + * 2 along with this work; if not, write to the Free Software Foundation, 28.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.22 + * 28.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28.24 + * or visit www.oracle.com if you need additional information or have any 28.25 + * questions. 28.26 + * 28.27 + */ 28.28 + 28.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_ORDERACCESS_AIX_PPC_INLINE_HPP 28.30 +#define OS_CPU_AIX_OJDKPPC_VM_ORDERACCESS_AIX_PPC_INLINE_HPP 28.31 + 28.32 +#include "runtime/orderAccess.hpp" 28.33 +#include "vm_version_ppc.hpp" 28.34 + 28.35 +// Implementation of class OrderAccess. 28.36 + 28.37 +// 28.38 +// Machine barrier instructions: 28.39 +// 28.40 +// - ppc_sync Two-way memory barrier, aka fence. 28.41 +// - ppc_lwsync orders Store|Store, 28.42 +// Load|Store, 28.43 +// Load|Load, 28.44 +// but not Store|Load 28.45 +// - ppc_eieio orders Store|Store 28.46 +// - ppc_isync Invalidates speculatively executed instructions, 28.47 +// but isync may complete before storage accesses 28.48 +// associated with instructions preceding isync have 28.49 +// been performed. 28.50 +// 28.51 +// Semantic barrier instructions: 28.52 +// (as defined in orderAccess.hpp) 28.53 +// 28.54 +// - ppc_release orders Store|Store, (maps to ppc_lwsync) 28.55 +// Load|Store 28.56 +// - ppc_acquire orders Load|Store, (maps to ppc_lwsync) 28.57 +// Load|Load 28.58 +// - ppc_fence orders Store|Store, (maps to ppc_sync) 28.59 +// Load|Store, 28.60 +// Load|Load, 28.61 +// Store|Load 28.62 +// 28.63 + 28.64 +#define inlasm_ppc_sync() __asm__ __volatile__ ("sync" : : : "memory"); 28.65 +#define inlasm_ppc_lwsync() __asm__ __volatile__ ("lwsync" : : : "memory"); 28.66 +#define inlasm_ppc_eieio() __asm__ __volatile__ ("eieio" : : : "memory"); 28.67 +#define inlasm_ppc_isync() __asm__ __volatile__ ("isync" : : : "memory"); 28.68 +#define inlasm_ppc_release() inlasm_ppc_lwsync(); 28.69 +#define inlasm_ppc_acquire() inlasm_ppc_lwsync(); 28.70 +// Use twi-isync for load_acquire (faster than lwsync). 28.71 +// ATTENTION: seems like xlC 10.1 has problems with this inline assembler macro (VerifyMethodHandles found "bad vminfo in AMH.conv"): 28.72 +// #define inlasm_ppc_acquire_reg(X) __asm__ __volatile__ ("twi 0,%0,0\n isync\n" : : "r" (X) : "memory"); 28.73 +#define inlasm_ppc_acquire_reg(X) inlasm_ppc_lwsync(); 28.74 +#define inlasm_ppc_fence() inlasm_ppc_sync(); 28.75 + 28.76 +inline void OrderAccess::loadload() { inlasm_ppc_lwsync(); } 28.77 +inline void OrderAccess::storestore() { inlasm_ppc_lwsync(); } 28.78 +inline void OrderAccess::loadstore() { inlasm_ppc_lwsync(); } 28.79 +inline void OrderAccess::storeload() { inlasm_ppc_fence(); } 28.80 + 28.81 +inline void OrderAccess::acquire() { inlasm_ppc_acquire(); } 28.82 +inline void OrderAccess::release() { inlasm_ppc_release(); } 28.83 +inline void OrderAccess::fence() { inlasm_ppc_fence(); } 28.84 + 28.85 +inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { register jbyte t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.86 +inline jshort OrderAccess::load_acquire(volatile jshort* p) { register jshort t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.87 +inline jint OrderAccess::load_acquire(volatile jint* p) { register jint t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.88 +inline jlong OrderAccess::load_acquire(volatile jlong* p) { register jlong t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.89 +inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { register jubyte t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.90 +inline jushort OrderAccess::load_acquire(volatile jushort* p) { register jushort t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.91 +inline juint OrderAccess::load_acquire(volatile juint* p) { register juint t = *p; inlasm_ppc_acquire_reg(t); return t; } 28.92 +inline julong OrderAccess::load_acquire(volatile julong* p) { return (julong)load_acquire((volatile jlong*)p); } 28.93 +inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { register jfloat t = *p; inlasm_ppc_acquire(); return t; } 28.94 +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { register jdouble t = *p; inlasm_ppc_acquire(); return t; } 28.95 + 28.96 +inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return (intptr_t)load_acquire((volatile jlong*)p); } 28.97 +inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return (void*) load_acquire((volatile jlong*)p); } 28.98 +inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { return (void*) load_acquire((volatile jlong*)p); } 28.99 + 28.100 +inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { inlasm_ppc_release(); *p = v; } 28.101 +inline void OrderAccess::release_store(volatile jshort* p, jshort v) { inlasm_ppc_release(); *p = v; } 28.102 +inline void OrderAccess::release_store(volatile jint* p, jint v) { inlasm_ppc_release(); *p = v; } 28.103 +inline void OrderAccess::release_store(volatile jlong* p, jlong v) { inlasm_ppc_release(); *p = v; } 28.104 +inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { inlasm_ppc_release(); *p = v; } 28.105 +inline void OrderAccess::release_store(volatile jushort* p, jushort v) { inlasm_ppc_release(); *p = v; } 28.106 +inline void OrderAccess::release_store(volatile juint* p, juint v) { inlasm_ppc_release(); *p = v; } 28.107 +inline void OrderAccess::release_store(volatile julong* p, julong v) { inlasm_ppc_release(); *p = v; } 28.108 +inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { inlasm_ppc_release(); *p = v; } 28.109 +inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { inlasm_ppc_release(); *p = v; } 28.110 + 28.111 +inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { inlasm_ppc_release(); *p = v; } 28.112 +inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { inlasm_ppc_release(); *(void* volatile *)p = v; } 28.113 + 28.114 +inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; inlasm_ppc_fence(); } 28.115 +inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; inlasm_ppc_fence(); } 28.116 +inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; inlasm_ppc_fence(); } 28.117 +inline void OrderAccess::store_fence(jlong* p, jlong v) { *p = v; inlasm_ppc_fence(); } 28.118 +inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; inlasm_ppc_fence(); } 28.119 +inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; inlasm_ppc_fence(); } 28.120 +inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; inlasm_ppc_fence(); } 28.121 +inline void OrderAccess::store_fence(julong* p, julong v) { *p = v; inlasm_ppc_fence(); } 28.122 +inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; inlasm_ppc_fence(); } 28.123 +inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; inlasm_ppc_fence(); } 28.124 + 28.125 +inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; inlasm_ppc_fence(); } 28.126 +inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; inlasm_ppc_fence(); } 28.127 + 28.128 +inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.129 +inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.130 +inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.131 +inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.132 +inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.133 +inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.134 +inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.135 +inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.136 +inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.137 +inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.138 + 28.139 +inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { inlasm_ppc_release(); *p = v; inlasm_ppc_fence(); } 28.140 +inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { inlasm_ppc_release(); *(void* volatile *)p = v; inlasm_ppc_fence(); } 28.141 + 28.142 +#undef inlasm_ppc_sync 28.143 +#undef inlasm_ppc_lwsync 28.144 +#undef inlasm_ppc_eieio 28.145 +#undef inlasm_ppc_isync 28.146 +#undef inlasm_ppc_release 28.147 +#undef inlasm_ppc_acquire 28.148 +#undef inlasm_ppc_fence 28.149 + 28.150 +#endif // OS_CPU_AIX_OJDKPPC_VM_ORDERACCESS_AIX_PPC_INLINE_HPP
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Fri Sep 06 20:16:09 2013 +0200 29.3 @@ -0,0 +1,560 @@ 29.4 +/* 29.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 29.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 + * 29.9 + * This code is free software; you can redistribute it and/or modify it 29.10 + * under the terms of the GNU General Public License version 2 only, as 29.11 + * published by the Free Software Foundation. 29.12 + * 29.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.16 + * version 2 for more details (a copy is included in the LICENSE file that 29.17 + * accompanied this code). 29.18 + * 29.19 + * You should have received a copy of the GNU General Public License version 29.20 + * 2 along with this work; if not, write to the Free Software Foundation, 29.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.22 + * 29.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.24 + * or visit www.oracle.com if you need additional information or have any 29.25 + * questions. 29.26 + * 29.27 + */ 29.28 + 29.29 +// no precompiled headers 29.30 +#include "assembler_ppc.inline.hpp" 29.31 +#include "classfile/classLoader.hpp" 29.32 +#include "classfile/systemDictionary.hpp" 29.33 +#include "classfile/vmSymbols.hpp" 29.34 +#include "code/icBuffer.hpp" 29.35 +#include "code/vtableStubs.hpp" 29.36 +#include "interpreter/interpreter.hpp" 29.37 +#include "jvm_aix.h" 29.38 +#include "memory/allocation.inline.hpp" 29.39 +#include "mutex_aix.inline.hpp" 29.40 +#include "nativeInst_ppc.hpp" 29.41 +#include "os_share_aix.hpp" 29.42 +#include "prims/jniFastGetField.hpp" 29.43 +#include "prims/jvm.h" 29.44 +#include "prims/jvm_misc.hpp" 29.45 +#include "runtime/arguments.hpp" 29.46 +#include "runtime/extendedPC.hpp" 29.47 +#include "runtime/frame.inline.hpp" 29.48 +#include "runtime/interfaceSupport.hpp" 29.49 +#include "runtime/java.hpp" 29.50 +#include "runtime/javaCalls.hpp" 29.51 +#include "runtime/mutexLocker.hpp" 29.52 +#include "runtime/osThread.hpp" 29.53 +#include "runtime/sharedRuntime.hpp" 29.54 +#include "runtime/stubRoutines.hpp" 29.55 +#include "runtime/timer.hpp" 29.56 +#include "thread_aix.inline.hpp" 29.57 +#include "utilities/events.hpp" 29.58 +#include "utilities/vmError.hpp" 29.59 +#ifdef COMPILER1 29.60 +#include "c1/c1_Runtime1.hpp" 29.61 +#endif 29.62 +#ifdef COMPILER2 29.63 +#include "opto/runtime.hpp" 29.64 +#endif 29.65 + 29.66 +// put OS-includes here 29.67 +# include <ucontext.h> 29.68 + 29.69 +address os::current_stack_pointer() { 29.70 + address csp; 29.71 + 29.72 +#if !defined(USE_XLC_BUILTINS) 29.73 + // inline assembly for `ppc_mr regno(csp), PPC_SP': 29.74 + __asm__ __volatile__ ("mr %0, 1":"=r"(csp):); 29.75 +#else 29.76 + csp = (address) __builtin_frame_address(0); 29.77 +#endif 29.78 + 29.79 + return csp; 29.80 +} 29.81 + 29.82 +char* os::non_memory_address_word() { 29.83 + // Must never look like an address returned by reserve_memory, 29.84 + // even in its subfields (as defined by the CPU immediate fields, 29.85 + // if the CPU splits constants across multiple instructions). 29.86 + 29.87 + return (char*) -1; 29.88 +} 29.89 + 29.90 +// OS specific thread initialization 29.91 +// 29.92 +// Calculate and store the limits of the memory stack. 29.93 +void os::initialize_thread(Thread *thread) { } 29.94 + 29.95 +// Frame information (pc, sp, fp) retrieved via ucontext 29.96 +// always looks like a C-frame according to the frame 29.97 +// conventions in frame_ppc64.hpp. 29.98 +address os::Aix::ucontext_get_pc(ucontext_t * uc) { 29.99 + return (address)uc->uc_mcontext.jmp_context.iar; 29.100 +} 29.101 + 29.102 +intptr_t* os::Aix::ucontext_get_sp(ucontext_t * uc) { 29.103 + // gpr1 holds the stack pointer on aix 29.104 + return (intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/]; 29.105 +} 29.106 + 29.107 +intptr_t* os::Aix::ucontext_get_fp(ucontext_t * uc) { 29.108 + return NULL; 29.109 +} 29.110 + 29.111 +void os::Aix::ucontext_set_pc(ucontext_t* uc, address new_pc) { 29.112 + uc->uc_mcontext.jmp_context.iar = (uint64_t) new_pc; 29.113 +} 29.114 + 29.115 +ExtendedPC os::fetch_frame_from_context(void* ucVoid, 29.116 + intptr_t** ret_sp, intptr_t** ret_fp) { 29.117 + 29.118 + ExtendedPC epc; 29.119 + ucontext_t* uc = (ucontext_t*)ucVoid; 29.120 + 29.121 + if (uc != NULL) { 29.122 + epc = ExtendedPC(os::Aix::ucontext_get_pc(uc)); 29.123 + if (ret_sp) *ret_sp = os::Aix::ucontext_get_sp(uc); 29.124 + if (ret_fp) *ret_fp = os::Aix::ucontext_get_fp(uc); 29.125 + } else { 29.126 + // construct empty ExtendedPC for return value checking 29.127 + epc = ExtendedPC(NULL); 29.128 + if (ret_sp) *ret_sp = (intptr_t *)NULL; 29.129 + if (ret_fp) *ret_fp = (intptr_t *)NULL; 29.130 + } 29.131 + 29.132 + return epc; 29.133 +} 29.134 + 29.135 +frame os::fetch_frame_from_context(void* ucVoid) { 29.136 + intptr_t* sp; 29.137 + intptr_t* fp; 29.138 + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 29.139 + // Avoid crash during crash if pc broken. 29.140 + if (epc.pc()) { 29.141 + frame fr(sp, epc.pc()); 29.142 + return fr; 29.143 + } 29.144 + frame fr(sp); 29.145 + return fr; 29.146 +} 29.147 + 29.148 +frame os::get_sender_for_C_frame(frame* fr) { 29.149 + if (*fr->sp() == NULL) { 29.150 + // fr is the last C frame 29.151 + return frame(NULL, NULL); 29.152 + } 29.153 + return frame(fr->sender_sp(), fr->sender_pc()); 29.154 +} 29.155 + 29.156 + 29.157 +frame os::current_frame() { 29.158 + intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer()); 29.159 + // hack. 29.160 + frame topframe(csp, (address)0x8); 29.161 + // return sender of current topframe which hopefully has pc != NULL. 29.162 + return os::get_sender_for_C_frame(&topframe); 29.163 +} 29.164 + 29.165 +// Utility functions 29.166 + 29.167 +extern "C" JNIEXPORT int 29.168 +JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { 29.169 + 29.170 + ucontext_t* uc = (ucontext_t*) ucVoid; 29.171 + 29.172 + Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady 29.173 + 29.174 + SignalHandlerMark shm(t); 29.175 + 29.176 + // Note: it's not uncommon that JNI code uses signal/sigset to install 29.177 + // then restore certain signal handler (e.g. to temporarily block SIGPIPE, 29.178 + // or have a SIGILL handler when detecting CPU type). When that happens, 29.179 + // JVM_handle_aix_signal() might be invoked with junk info/ucVoid. To 29.180 + // avoid unnecessary crash when libjsig is not preloaded, try handle signals 29.181 + // that do not require siginfo/ucontext first. 29.182 + 29.183 + if (sig == SIGPIPE) { 29.184 + if (os::Aix::chained_handler(sig, info, ucVoid)) { 29.185 + return 1; 29.186 + } else { 29.187 + if (PrintMiscellaneous && (WizardMode || Verbose)) { 29.188 + warning("Ignoring SIGPIPE - see bug 4229104"); 29.189 + } 29.190 + return 1; 29.191 + } 29.192 + } 29.193 + 29.194 + JavaThread* thread = NULL; 29.195 + VMThread* vmthread = NULL; 29.196 + if (os::Aix::signal_handlers_are_installed) { 29.197 + if (t != NULL) { 29.198 + if(t->is_Java_thread()) { 29.199 + thread = (JavaThread*)t; 29.200 + } 29.201 + else if(t->is_VM_thread()) { 29.202 + vmthread = (VMThread *)t; 29.203 + } 29.204 + } 29.205 + } 29.206 + 29.207 + // Decide if this trap can be handled by a stub. 29.208 + address stub = NULL; 29.209 + 29.210 + // retrieve program counter 29.211 + address const pc = uc ? os::Aix::ucontext_get_pc(uc) : NULL; 29.212 + 29.213 + // retrieve crash address 29.214 + address const addr = info ? (const address) info->si_addr : NULL; 29.215 + 29.216 + // SafeFetch 32 handling: 29.217 + // - make it work if _thread is null 29.218 + // - make it use the standard os::...::ucontext_get/set_pc APIs 29.219 + if (uc) { 29.220 + address const pc = os::Aix::ucontext_get_pc(uc); 29.221 + if (pc && StubRoutines::is_safefetch_fault(pc)) { 29.222 + os::Aix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); 29.223 + return true; 29.224 + } 29.225 + } 29.226 + 29.227 + // Handle SIGDANGER right away. AIX would raise SIGDANGER whenever available swap 29.228 + // space falls below 30%. This is only a chance for the process to gracefully abort. 29.229 + // We can't hope to proceed after SIGDANGER since SIGKILL tailgates. 29.230 + if (sig == SIGDANGER) { 29.231 + goto report_and_die; 29.232 + } 29.233 + 29.234 + if (info == NULL || uc == NULL || thread == NULL && vmthread == NULL) { 29.235 + goto run_chained_handler; 29.236 + } 29.237 + 29.238 + // If we are a java thread... 29.239 + if (thread != NULL) { 29.240 + 29.241 + // Handle ALL stack overflow variations here 29.242 + if (sig == SIGSEGV && (addr < thread->stack_base() && 29.243 + addr >= thread->stack_base() - thread->stack_size())) { 29.244 + // stack overflow 29.245 + // 29.246 + // If we are in a yellow zone and we are inside java, we disable the yellow zone and 29.247 + // throw a stack overflow exception. 29.248 + // If we are in native code or VM C code, we report-and-die. The original coding tried 29.249 + // to continue with yellow zone disabled, but that doesn't buy us much and prevents 29.250 + // hs_err_pid files. 29.251 + if (thread->in_stack_yellow_zone(addr)) { 29.252 + thread->disable_stack_yellow_zone(); 29.253 + if (thread->thread_state() == _thread_in_Java) { 29.254 + // Throw a stack overflow exception. 29.255 + // Guard pages will be reenabled while unwinding the stack. 29.256 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); 29.257 + goto run_stub; 29.258 + } else { 29.259 + // Thread was in the vm or native code. Return and try to finish. 29.260 + return 1; 29.261 + } 29.262 + } else if (thread->in_stack_red_zone(addr)) { 29.263 + // Fatal red zone violation. Disable the guard pages and fall through 29.264 + // to handle_unexpected_exception way down below. 29.265 + thread->disable_stack_red_zone(); 29.266 + tty->print_raw_cr("An irrecoverable stack overflow has occurred."); 29.267 + goto report_and_die; 29.268 + } else { 29.269 + // this means a segv happened inside our stack, but not in 29.270 + // the guarded zone. I'd like to know when this happens, 29.271 + tty->print_raw_cr("SIGSEGV happened inside stack but outside yellow and red zone."); 29.272 + goto report_and_die; 29.273 + } 29.274 + 29.275 + } // end handle SIGSEGV inside stack boundaries 29.276 + 29.277 + if (thread->thread_state() == _thread_in_Java) { 29.278 + // Java thread running in Java code 29.279 + 29.280 + // The following signals are used for communicating VM events: 29.281 + // 29.282 + // SIGILL: the compiler generates illegal opcodes 29.283 + // at places where it wishes to interrupt the VM: 29.284 + // Safepoints, Unreachable Code, Entry points of Zombie methods, 29.285 + // This results in a SIGILL with (*pc) == inserted illegal instruction. 29.286 + // 29.287 + // (so, SIGILLs with a pc inside the zero page are real errors) 29.288 + // 29.289 + // SIGTRAP: 29.290 + // The ppc trap instruction raises a SIGTRAP and is very efficient if it 29.291 + // does not trap. It is used for conditional branches that are expected 29.292 + // to be never taken. These are: 29.293 + // - zombie methods 29.294 + // - IC (inline cache) misses. 29.295 + // - null checks leading to UncommonTraps. 29.296 + // - range checks leading to Uncommon Traps. 29.297 + // On Aix, these are especially null checks, as the ImplicitNullCheck 29.298 + // optimization works only in rare cases, as the page at address 0 is only 29.299 + // write protected. // 29.300 + // Note: !UseSIGTRAP is used to prevent SIGTRAPS altogether, to facilitate debugging. 29.301 + // 29.302 + // SIGSEGV: 29.303 + // used for safe point polling: 29.304 + // To notify all threads that they have to reach a safe point, safe point polling is used: 29.305 + // All threads poll a certain mapped memory page. Normally, this page has read access. 29.306 + // If the VM wants to inform the threads about impending safe points, it puts this 29.307 + // page to read only ("poisens" the page), and the threads then reach a safe point. 29.308 + // used for null checks: 29.309 + // If the compiler finds a store it uses it for a null check. Unfortunately this 29.310 + // happens rarely. In heap based and disjoint base compressd oop modes also loads 29.311 + // are used for null checks. 29.312 + 29.313 + // A VM-related SIGILL may only occur if we are not in the zero page. 29.314 + // On AIX, we get a SIGILL if we jump to 0x0 or to somewhere else 29.315 + // in the zero page, because it is filled with 0x0. We ignore 29.316 + // explicit SIGILLs in the zero page. 29.317 + if (sig == SIGILL && (pc < (address) 0x200)) { 29.318 + if (TraceTraps) 29.319 + tty->print_raw_cr("SIGILL happened inside zero page."); 29.320 + goto report_and_die; 29.321 + } 29.322 + 29.323 + // Handle signal from NativeJump::patch_verified_entry(). 29.324 + if (( TrapBasedNotEntrantChecks && sig == SIGTRAP && nativeInstruction_at(pc)->is_sigtrap_zombie_not_entrant()) || 29.325 + (!TrapBasedNotEntrantChecks && sig == SIGILL && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant())) { 29.326 + if (TraceTraps) 29.327 + tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL"); 29.328 + stub = SharedRuntime::get_handle_wrong_method_stub(); 29.329 + goto run_stub; 29.330 + } 29.331 + 29.332 + else if (sig == SIGSEGV && os::is_poll_address(addr)) { 29.333 + if (TraceTraps) 29.334 + tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", pc); 29.335 + stub = SharedRuntime::get_poll_stub(pc); 29.336 + goto run_stub; 29.337 + } 29.338 + 29.339 + // SIGTRAP-based ic miss check in compiled code 29.340 + else if (sig == SIGTRAP && TrapBasedICMissChecks && 29.341 + nativeInstruction_at(pc)->is_sigtrap_ic_miss_check()) { 29.342 + if (TraceTraps) 29.343 + tty->print_cr("trap: ic_miss_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 29.344 + stub = SharedRuntime::get_ic_miss_stub(); 29.345 + goto run_stub; 29.346 + } 29.347 + 29.348 +#ifdef COMPILER2 29.349 + // SIGTRAP-based implicit null check in compiled code. 29.350 + else if (sig == SIGTRAP && TrapBasedNullChecks && 29.351 + nativeInstruction_at(pc)->is_sigtrap_null_check()) { 29.352 + if (TraceTraps) 29.353 + tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 29.354 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 29.355 + goto run_stub; 29.356 + } 29.357 +#endif 29.358 + 29.359 + // SIGSEGV-based implicit null check in compiled code. 29.360 + else if (sig == SIGSEGV && ImplicitNullChecks && 29.361 + CodeCache::contains((void*) pc) && 29.362 + !MacroAssembler::needs_explicit_null_check((intptr_t) info->si_addr)) { 29.363 + if (TraceTraps) 29.364 + tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc); 29.365 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 29.366 + } 29.367 + 29.368 +#ifdef COMPILER2 29.369 + // SIGTRAP-based implicit range check in compiled code. 29.370 + else if (sig == SIGTRAP && TrapBasedRangeChecks && 29.371 + nativeInstruction_at(pc)->is_sigtrap_range_check()) { 29.372 + if (TraceTraps) 29.373 + tty->print_cr("trap: range_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 29.374 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 29.375 + goto run_stub; 29.376 + } 29.377 +#endif 29.378 + 29.379 + else if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) { 29.380 + if (TraceTraps) { 29.381 + tty->print_raw_cr("Fix SIGFPE handler, trying divide by zero handler."); 29.382 + } 29.383 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 29.384 + goto run_stub; 29.385 + } 29.386 + 29.387 + else if (sig == SIGBUS) { 29.388 + // BugId 4454115: A read from a MappedByteBuffer can fault here if the 29.389 + // underlying file has been truncated. Do not crash the VM in such a case. 29.390 + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 29.391 + nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 29.392 + if (nm != NULL && nm->has_unsafe_access()) { 29.393 + // We don't really need a stub here! Just set the pending exeption and 29.394 + // continue at the next instruction after the faulting read. Returning 29.395 + // garbage from this read is ok. 29.396 + thread->set_pending_unsafe_access_error(); 29.397 + uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4; 29.398 + return 1; 29.399 + } 29.400 + } 29.401 + } 29.402 + 29.403 + else { // thread->thread_state() != _thread_in_Java 29.404 + // Detect CPU features. This is only done at the very start of the VM. Later, the 29.405 + // VM_Version::is_determine_features_test_running() flag should be false. 29.406 + 29.407 + if (sig == SIGILL && VM_Version::is_determine_features_test_running()) { 29.408 + // SIGILL must be caused by VM_Version::determine_features(). 29.409 + *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, 29.410 + // flushing of icache is not necessary. 29.411 + stub = pc + 4; // continue with next instruction. 29.412 + goto run_stub; 29.413 + } 29.414 + else if (thread->thread_state() == _thread_in_vm && 29.415 + sig == SIGBUS && thread->doing_unsafe_access()) { 29.416 + // We don't really need a stub here! Just set the pending exeption and 29.417 + // continue at the next instruction after the faulting read. Returning 29.418 + // garbage from this read is ok. 29.419 + thread->set_pending_unsafe_access_error(); 29.420 + uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4; 29.421 + return 1; 29.422 + } 29.423 + } 29.424 + 29.425 + // Check to see if we caught the safepoint code in the 29.426 + // process of write protecting the memory serialization page. 29.427 + // It write enables the page immediately after protecting it 29.428 + // so we can just return to retry the write. 29.429 + if ((sig == SIGSEGV) && 29.430 + os::is_memory_serialize_page(thread, addr)) { 29.431 + // Synchronization problem in the pseudo memory barrier code (bug id 6546278) 29.432 + // Block current thread until the memory serialize page permission restored. 29.433 + os::block_on_serialize_page_trap(); 29.434 + return true; 29.435 + } 29.436 + } 29.437 + 29.438 +run_stub: 29.439 + 29.440 + // One of the above code blocks ininitalized the stub, so we want to 29.441 + // delegate control to that stub. 29.442 + if (stub != NULL) { 29.443 + // Save all thread context in case we need to restore it. 29.444 + if (thread != NULL) thread->set_saved_exception_pc(pc); 29.445 + uc->uc_mcontext.jmp_context.iar = (unsigned long)stub; 29.446 + return 1; 29.447 + } 29.448 + 29.449 +run_chained_handler: 29.450 + 29.451 + // signal-chaining 29.452 + if (os::Aix::chained_handler(sig, info, ucVoid)) { 29.453 + return 1; 29.454 + } 29.455 + if (!abort_if_unrecognized) { 29.456 + // caller wants another chance, so give it to him 29.457 + return 0; 29.458 + } 29.459 + 29.460 +report_and_die: 29.461 + 29.462 + // Use sigthreadmask instead of sigprocmask on AIX and unmask current signal. 29.463 + sigset_t newset; 29.464 + sigemptyset(&newset); 29.465 + sigaddset(&newset, sig); 29.466 + sigthreadmask(SIG_UNBLOCK, &newset, NULL); 29.467 + 29.468 + VMError err(t, sig, pc, info, ucVoid); 29.469 + err.report_and_die(); 29.470 + 29.471 + ShouldNotReachHere(); 29.472 + return 0; 29.473 +} 29.474 + 29.475 +void os::Aix::init_thread_fpu_state(void) { 29.476 +#if !defined(USE_XLC_BUILTINS) 29.477 + // Disable FP exceptions. 29.478 + __asm__ __volatile__ ("mtfsfi 6,0"); 29.479 +#else 29.480 + __mtfsfi(6, 0); 29.481 +#endif 29.482 +} 29.483 + 29.484 +//////////////////////////////////////////////////////////////////////////////// 29.485 +// thread stack 29.486 + 29.487 +size_t os::Aix::min_stack_allowed = 768*K; 29.488 + 29.489 +// Aix is always in floating stack mode. The stack size for a new 29.490 +// thread can be set via pthread_attr_setstacksize(). 29.491 +bool os::Aix::supports_variable_stack_size() { return true; } 29.492 + 29.493 +// return default stack size for thr_type 29.494 +size_t os::Aix::default_stack_size(os::ThreadType thr_type) { 29.495 + // default stack size (compiler thread needs larger stack) 29.496 + // Notice that the setting for compiler threads here have no impact 29.497 + // because of the strange 'fallback logic' in os::create_thread(). 29.498 + // Better set CompilerThreadStackSize in globals_<os_cpu>.hpp if you want to 29.499 + // specify a different stack size for compiler threads! 29.500 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K); 29.501 + return s; 29.502 +} 29.503 + 29.504 +size_t os::Aix::default_guard_size(os::ThreadType thr_type) { 29.505 + return 2 * page_size(); 29.506 +} 29.507 + 29.508 +///////////////////////////////////////////////////////////////////////////// 29.509 +// helper functions for fatal error handler 29.510 + 29.511 +void os::print_context(outputStream *st, void *context) { 29.512 + if (context == NULL) return; 29.513 + 29.514 + ucontext_t* uc = (ucontext_t*)context; 29.515 + 29.516 + st->print_cr("Registers:"); 29.517 + st->print("pc =" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.iar); 29.518 + st->print("lr =" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.lr); 29.519 + st->print("ctr=" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.ctr); 29.520 + st->cr(); 29.521 + for (int i = 0; i < 32; i++) { 29.522 + st->print("r%-2d=" INTPTR_FORMAT " ", i, uc->uc_mcontext.jmp_context.gpr[i]); 29.523 + if (i % 3 == 2) st->cr(); 29.524 + } 29.525 + st->cr(); 29.526 + st->cr(); 29.527 + 29.528 + intptr_t *sp = (intptr_t *)os::Aix::ucontext_get_sp(uc); 29.529 + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 29.530 + print_hex_dump(st, (address)sp, (address)(sp + 128), sizeof(intptr_t)); 29.531 + st->cr(); 29.532 + 29.533 + // Note: it may be unsafe to inspect memory near pc. For example, pc may 29.534 + // point to garbage if entry point in an nmethod is corrupted. Leave 29.535 + // this at the end, and hope for the best. 29.536 + address pc = os::Aix::ucontext_get_pc(uc); 29.537 + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 29.538 + print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4); 29.539 + st->cr(); 29.540 + 29.541 + // Try to decode the instructions. 29.542 + st->print_cr("Decoded instructions: (pc=" PTR_FORMAT ")", pc); 29.543 + st->print("<TODO: PPC port - print_context>"); 29.544 + // TODO: PPC port Disassembler::decode(pc, 16, 16, st); 29.545 + st->cr(); 29.546 +} 29.547 + 29.548 +void os::print_register_info(outputStream *st, void *context) { 29.549 + if (context == NULL) return; 29.550 + st->print("Not ported - print_register_info\n"); 29.551 +} 29.552 + 29.553 +extern "C" { 29.554 + int SpinPause() { 29.555 + return 0; 29.556 + } 29.557 +} 29.558 + 29.559 +#ifndef PRODUCT 29.560 +void os::verify_stack_alignment() { 29.561 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); 29.562 +} 29.563 +#endif
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp Fri Sep 06 20:16:09 2013 +0200 30.3 @@ -0,0 +1,35 @@ 30.4 +/* 30.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 30.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 30.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.8 + * 30.9 + * This code is free software; you can redistribute it and/or modify it 30.10 + * under the terms of the GNU General Public License version 2 only, as 30.11 + * published by the Free Software Foundation. 30.12 + * 30.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.16 + * version 2 for more details (a copy is included in the LICENSE file that 30.17 + * accompanied this code). 30.18 + * 30.19 + * You should have received a copy of the GNU General Public License version 30.20 + * 2 along with this work; if not, write to the Free Software Foundation, 30.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.22 + * 30.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.24 + * or visit www.oracle.com if you need additional information or have any 30.25 + * questions. 30.26 + * 30.27 + */ 30.28 + 30.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP 30.30 +#define OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP 30.31 + 30.32 + static void setup_fpu() {} 30.33 + 30.34 + // Used to register dynamic code cache area with the OS 30.35 + // Note: Currently only used in 64 bit Windows implementations 30.36 + static bool register_code_area(char *low, char *high) { return true; } 30.37 + 30.38 +#endif // OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp Fri Sep 06 20:16:09 2013 +0200 31.3 @@ -0,0 +1,58 @@ 31.4 +/* 31.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 31.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 31.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.8 + * 31.9 + * This code is free software; you can redistribute it and/or modify it 31.10 + * under the terms of the GNU General Public License version 2 only, as 31.11 + * published by the Free Software Foundation. 31.12 + * 31.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.16 + * version 2 for more details (a copy is included in the LICENSE file that 31.17 + * accompanied this code). 31.18 + * 31.19 + * You should have received a copy of the GNU General Public License version 31.20 + * 2 along with this work; if not, write to the Free Software Foundation, 31.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.22 + * 31.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.24 + * or visit www.oracle.com if you need additional information or have any 31.25 + * questions. 31.26 + * 31.27 + */ 31.28 + 31.29 +#ifndef OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP 31.30 +#define OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP 31.31 + 31.32 +#include "runtime/prefetch.hpp" 31.33 + 31.34 + 31.35 +inline void Prefetch::read(void *loc, intx interval) { 31.36 +#if !defined(USE_XLC_BUILTINS) 31.37 + __asm__ __volatile__ ( 31.38 + " dcbt 0, %0 \n" 31.39 + : 31.40 + : /*%0*/"r" ( ((address)loc) +((long)interval) ) 31.41 + //: 31.42 + ); 31.43 +#else 31.44 + __dcbt(((address)loc) +((long)interval)); 31.45 +#endif 31.46 +} 31.47 + 31.48 +inline void Prefetch::write(void *loc, intx interval) { 31.49 +#if !defined(USE_XLC_PREFETCH_WRITE_BUILTIN) 31.50 + __asm__ __volatile__ ( 31.51 + " dcbtst 0, %0 \n" 31.52 + : 31.53 + : /*%0*/"r" ( ((address)loc) +((long)interval) ) 31.54 + //: 31.55 + ); 31.56 +#else 31.57 + __dcbtst( ((address)loc) +((long)interval) ); 31.58 +#endif 31.59 +} 31.60 + 31.61 +#endif // OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.cpp Fri Sep 06 20:16:09 2013 +0200 32.3 @@ -0,0 +1,40 @@ 32.4 +/* 32.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 32.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 + * 32.9 + * This code is free software; you can redistribute it and/or modify it 32.10 + * under the terms of the GNU General Public License version 2 only, as 32.11 + * published by the Free Software Foundation. 32.12 + * 32.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.16 + * version 2 for more details (a copy is included in the LICENSE file that 32.17 + * accompanied this code). 32.18 + * 32.19 + * You should have received a copy of the GNU General Public License version 32.20 + * 2 along with this work; if not, write to the Free Software Foundation, 32.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.22 + * 32.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.24 + * or visit www.oracle.com if you need additional information or have any 32.25 + * questions. 32.26 + * 32.27 + */ 32.28 + 32.29 +#include "precompiled.hpp" 32.30 +#include "runtime/threadLocalStorage.hpp" 32.31 +#include "thread_aix.inline.hpp" 32.32 + 32.33 +void ThreadLocalStorage::generate_code_for_get_thread() { 32.34 + // nothing we can do here for user-level thread 32.35 +} 32.36 + 32.37 +void ThreadLocalStorage::pd_init() { 32.38 + // Nothing to do 32.39 +} 32.40 + 32.41 +void ThreadLocalStorage::pd_set_thread(Thread* thread) { 32.42 + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); 32.43 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp Fri Sep 06 20:16:09 2013 +0200 33.3 @@ -0,0 +1,36 @@ 33.4 +/* 33.5 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 33.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 33.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.8 + * 33.9 + * This code is free software; you can redistribute it and/or modify it 33.10 + * under the terms of the GNU General Public License version 2 only, as 33.11 + * published by the Free Software Foundation. 33.12 + * 33.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.16 + * version 2 for more details (a copy is included in the LICENSE file that 33.17 + * accompanied this code). 33.18 + * 33.19 + * You should have received a copy of the GNU General Public License version 33.20 + * 2 along with this work; if not, write to the Free Software Foundation, 33.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.22 + * 33.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.24 + * or visit www.oracle.com if you need additional information or have any 33.25 + * questions. 33.26 + * 33.27 + */ 33.28 + 33.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP 33.30 +#define OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP 33.31 + 33.32 + // Processor dependent parts of ThreadLocalStorage 33.33 + 33.34 +public: 33.35 + static Thread* thread() { 33.36 + return (Thread *) os::thread_local_storage_at(thread_index()); 33.37 + } 33.38 + 33.39 +#endif // OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/src/os_cpu/aix_ppc/vm/thread_aix_ppc.cpp Fri Sep 06 20:16:09 2013 +0200 34.3 @@ -0,0 +1,36 @@ 34.4 +/* 34.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 34.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 34.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.8 + * 34.9 + * This code is free software; you can redistribute it and/or modify it 34.10 + * under the terms of the GNU General Public License version 2 only, as 34.11 + * published by the Free Software Foundation. 34.12 + * 34.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 34.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 34.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 34.16 + * version 2 for more details (a copy is included in the LICENSE file that 34.17 + * accompanied this code). 34.18 + * 34.19 + * You should have received a copy of the GNU General Public License version 34.20 + * 2 along with this work; if not, write to the Free Software Foundation, 34.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 34.22 + * 34.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 34.24 + * or visit www.oracle.com if you need additional information or have any 34.25 + * questions. 34.26 + * 34.27 + */ 34.28 + 34.29 +#include "precompiled.hpp" 34.30 +#include "runtime/frame.inline.hpp" 34.31 +#include "thread_aix.inline.hpp" 34.32 + 34.33 +// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Aix/PPC. 34.34 +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) { 34.35 + Unimplemented(); 34.36 + return false; 34.37 +} 34.38 + 34.39 +void JavaThread::cache_global_variables() { }
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp Fri Sep 06 20:16:09 2013 +0200 35.3 @@ -0,0 +1,79 @@ 35.4 +/* 35.5 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 35.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 35.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.8 + * 35.9 + * This code is free software; you can redistribute it and/or modify it 35.10 + * under the terms of the GNU General Public License version 2 only, as 35.11 + * published by the Free Software Foundation. 35.12 + * 35.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 35.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 35.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 35.16 + * version 2 for more details (a copy is included in the LICENSE file that 35.17 + * accompanied this code). 35.18 + * 35.19 + * You should have received a copy of the GNU General Public License version 35.20 + * 2 along with this work; if not, write to the Free Software Foundation, 35.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 35.22 + * 35.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 35.24 + * or visit www.oracle.com if you need additional information or have any 35.25 + * questions. 35.26 + * 35.27 + */ 35.28 + 35.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP 35.30 +#define OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP 35.31 + 35.32 + private: 35.33 + void pd_initialize() { 35.34 + _anchor.clear(); 35.35 + _last_interpreter_fp = NULL; 35.36 + } 35.37 + 35.38 + // The `last' frame is the youngest Java frame on the thread's stack. 35.39 + frame pd_last_frame() { 35.40 + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); 35.41 + 35.42 + intptr_t* sp = last_Java_sp(); 35.43 + address pc = _anchor.last_Java_pc(); 35.44 + 35.45 + // Last_Java_pc ist not set, if we come here from compiled code. 35.46 + if (pc == NULL) 35.47 + pc = (address) *(sp + 2); 35.48 + 35.49 + return frame(sp, pc); 35.50 + } 35.51 + 35.52 + public: 35.53 + void set_base_of_stack_pointer(intptr_t* base_sp) {} 35.54 + intptr_t* base_of_stack_pointer() { return NULL; } 35.55 + void record_base_of_stack_pointer() {} 35.56 + 35.57 + // These routines are only used on cpu architectures that 35.58 + // have separate register stacks (Itanium). 35.59 + static bool register_stack_overflow() { return false; } 35.60 + static void enable_register_stack_guard() {} 35.61 + static void disable_register_stack_guard() {} 35.62 + 35.63 + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, 35.64 + bool isInJava); 35.65 + 35.66 + // -Xprof support 35.67 + // 35.68 + // In order to find the last Java fp from an async profile 35.69 + // tick, we store the current interpreter fp in the thread. 35.70 + // This value is only valid while we are in the C++ interpreter 35.71 + // and profiling. 35.72 + protected: 35.73 + intptr_t *_last_interpreter_fp; 35.74 + 35.75 + public: 35.76 + static ByteSize last_interpreter_fp_offset() { 35.77 + return byte_offset_of(JavaThread, _last_interpreter_fp); 35.78 + } 35.79 + 35.80 + intptr_t* last_interpreter_fp() { return _last_interpreter_fp; } 35.81 + 35.82 +#endif // OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/src/os_cpu/aix_ppc/vm/vmStructs_aix_ppc.hpp Fri Sep 06 20:16:09 2013 +0200 36.3 @@ -0,0 +1,55 @@ 36.4 +/* 36.5 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 36.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 36.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.8 + * 36.9 + * This code is free software; you can redistribute it and/or modify it 36.10 + * under the terms of the GNU General Public License version 2 only, as 36.11 + * published by the Free Software Foundation. 36.12 + * 36.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 36.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36.16 + * version 2 for more details (a copy is included in the LICENSE file that 36.17 + * accompanied this code). 36.18 + * 36.19 + * You should have received a copy of the GNU General Public License version 36.20 + * 2 along with this work; if not, write to the Free Software Foundation, 36.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 36.22 + * 36.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 36.24 + * or visit www.oracle.com if you need additional information or have any 36.25 + * questions. 36.26 + * 36.27 + */ 36.28 + 36.29 +#ifndef OS_CPU_AIX_OJDKPPC_VM_VMSTRUCTS_AIX_PPC_HPP 36.30 +#define OS_CPU_AIX_OJDKPPC_VM_VMSTRUCTS_AIX_PPC_HPP 36.31 + 36.32 +// These are the OS and CPU-specific fields, types and integer 36.33 +// constants required by the Serviceability Agent. This file is 36.34 +// referenced by vmStructs.cpp. 36.35 + 36.36 +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ 36.37 + \ 36.38 + /******************************/ \ 36.39 + /* Threads (NOTE: incomplete) */ \ 36.40 + /******************************/ \ 36.41 + nonstatic_field(OSThread, _thread_id, pid_t) \ 36.42 + nonstatic_field(OSThread, _pthread_id, pthread_t) 36.43 + 36.44 + 36.45 +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ 36.46 + \ 36.47 + /**********************/ \ 36.48 + /* Posix Thread IDs */ \ 36.49 + /**********************/ \ 36.50 + \ 36.51 + declare_integer_type(pid_t) \ 36.52 + declare_unsigned_integer_type(pthread_t) 36.53 + 36.54 +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) 36.55 + 36.56 +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) 36.57 + 36.58 +#endif // OS_CPU_AIX_OJDKPPC_VM_VMSTRUCTS_AIX_PPC_HPP
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/src/share/vm/utilities/globalDefinitions_xlc.hpp Fri Sep 06 20:16:09 2013 +0200 37.3 @@ -0,0 +1,202 @@ 37.4 +/* 37.5 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 37.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 37.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.8 + * 37.9 + * This code is free software; you can redistribute it and/or modify it 37.10 + * under the terms of the GNU General Public License version 2 only, as 37.11 + * published by the Free Software Foundation. 37.12 + * 37.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 37.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 37.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 37.16 + * version 2 for more details (a copy is included in the LICENSE file that 37.17 + * accompanied this code). 37.18 + * 37.19 + * You should have received a copy of the GNU General Public License version 37.20 + * 2 along with this work; if not, write to the Free Software Foundation, 37.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 37.22 + * 37.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 37.24 + * or visit www.oracle.com if you need additional information or have any 37.25 + * questions. 37.26 + * 37.27 + */ 37.28 + 37.29 +#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP 37.30 +#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP 37.31 + 37.32 +#include "prims/jni.h" 37.33 + 37.34 +// This file holds compiler-dependent includes, 37.35 +// globally used constants & types, class (forward) 37.36 +// declarations and a few frequently used utility functions. 37.37 + 37.38 +#include <ctype.h> 37.39 +#include <string.h> 37.40 +#include <stdarg.h> 37.41 +#include <stddef.h> 37.42 +#include <stdio.h> 37.43 +#include <stdlib.h> 37.44 +#include <wchar.h> 37.45 + 37.46 +#include <math.h> 37.47 +#ifndef FP_PZERO 37.48 +// Linux doesn't have positive/negative zero 37.49 +#define FP_PZERO FP_ZERO 37.50 +#endif 37.51 +#if (!defined fpclass) 37.52 +#define fpclass fpclassify 37.53 +#endif 37.54 + 37.55 +#include <time.h> 37.56 +#include <fcntl.h> 37.57 +#include <dlfcn.h> 37.58 +#include <pthread.h> 37.59 + 37.60 +#include <limits.h> 37.61 +#include <errno.h> 37.62 + 37.63 +#include <stdint.h> 37.64 + 37.65 +// Use XLC compiler builtins instead of inline assembler 37.66 +#define USE_XLC_BUILTINS 37.67 +#ifdef USE_XLC_BUILTINS 37.68 +#include <builtins.h> 37.69 + #if __IBMCPP__ < 1000 37.70 + // the funtion prototype for __dcbtst(void *) is missing in XLC V8.0 37.71 + // I could compile a little test, where I provided the prototype. 37.72 + // The generated code was correct there. This is the prototype: 37.73 + // extern "builtin" void __dcbtst (void *); 37.74 + // For now we don't make use of it when compiling with XLC V8.0 37.75 + #else 37.76 + // __IBMCPP__ >= 1000 37.77 + // XLC V10 provides the prototype for __dcbtst (void *); 37.78 + #define USE_XLC_PREFETCH_WRITE_BUILTIN 37.79 + #endif 37.80 +#endif // USE_XLC_BUILTINS 37.81 + 37.82 +// NULL vs NULL_WORD: 37.83 +// On Linux NULL is defined as a special type '__null'. Assigning __null to 37.84 +// integer variable will cause gcc warning. Use NULL_WORD in places where a 37.85 +// pointer is stored as integer value. On some platforms, sizeof(intptr_t) > 37.86 +// sizeof(void*), so here we want something which is integer type, but has the 37.87 +// same size as a pointer. 37.88 +#ifdef __GNUC__ 37.89 + #error XLC and __GNUC__? 37.90 +#else 37.91 + #define NULL_WORD NULL 37.92 +#endif 37.93 + 37.94 +// AIX also needs a 64 bit NULL to work as a null address pointer. 37.95 +// Most system includes on AIX would define it as an int 0 if not already defined with one 37.96 +// exception: /usr/include/dirent.h will unconditionally redefine NULL to int 0 again. 37.97 +// In this case you need to copy the following defines to a position after #include <dirent.h> 37.98 +// (see jmv_aix.h). 37.99 +#ifdef AIX 37.100 + #ifdef _LP64 37.101 + #undef NULL 37.102 + #define NULL 0L 37.103 + #else 37.104 + #ifndef NULL 37.105 + #define NULL 0 37.106 + #endif 37.107 + #endif 37.108 +#endif // AIX 37.109 + 37.110 +// Compiler-specific primitive types 37.111 +// All defs of int (uint16_6 etc) are defined in AIX' /usr/include/stdint.h 37.112 + 37.113 +// Additional Java basic types 37.114 + 37.115 +typedef uint8_t jubyte; 37.116 +typedef uint16_t jushort; 37.117 +typedef uint32_t juint; 37.118 +typedef uint64_t julong; 37.119 + 37.120 +//---------------------------------------------------------------------------------------------------- 37.121 +// Special (possibly not-portable) casts 37.122 +// Cast floats into same-size integers and vice-versa w/o changing bit-pattern 37.123 +// %%%%%% These seem like standard C++ to me--how about factoring them out? - Ungar 37.124 + 37.125 +inline jint jint_cast (jfloat x) { return *(jint* )&x; } 37.126 +inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; } 37.127 + 37.128 +inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; } 37.129 +inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; } 37.130 + 37.131 +//---------------------------------------------------------------------------------------------------- 37.132 +// Constant for jlong (specifying an long long canstant is C++ compiler specific) 37.133 + 37.134 +// Build a 64bit integer constant 37.135 +#define CONST64(x) (x ## LL) 37.136 +#define UCONST64(x) (x ## ULL) 37.137 + 37.138 +const jlong min_jlong = CONST64(0x8000000000000000); 37.139 +const jlong max_jlong = CONST64(0x7fffffffffffffff); 37.140 + 37.141 +//---------------------------------------------------------------------------------------------------- 37.142 +// Debugging 37.143 + 37.144 +#define DEBUG_EXCEPTION ::abort(); 37.145 + 37.146 +extern "C" void breakpoint(); 37.147 +#define BREAKPOINT ::breakpoint() 37.148 + 37.149 +// checking for nanness 37.150 +#ifdef AIX 37.151 +inline int g_isnan(float f) { return isnan(f); } 37.152 +inline int g_isnan(double f) { return isnan(f); } 37.153 +#else 37.154 +#error "missing platform-specific definition here" 37.155 +#endif 37.156 + 37.157 +// Checking for finiteness 37.158 + 37.159 +inline int g_isfinite(jfloat f) { return finite(f); } 37.160 +inline int g_isfinite(jdouble f) { return finite(f); } 37.161 + 37.162 + 37.163 +// Wide characters 37.164 + 37.165 +inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } 37.166 + 37.167 + 37.168 +// Portability macros 37.169 +#define PRAGMA_INTERFACE #pragma interface 37.170 +#define PRAGMA_IMPLEMENTATION #pragma implementation 37.171 +#define VALUE_OBJ_CLASS_SPEC 37.172 + 37.173 +// Formatting. 37.174 +#ifdef _LP64 37.175 +#define FORMAT64_MODIFIER "l" 37.176 +#else // !_LP64 37.177 +#define FORMAT64_MODIFIER "ll" 37.178 +#endif // _LP64 37.179 + 37.180 +// Cannot use xlc's offsetof as implementation of hotspot's 37.181 +// offset_of(), because xlc warns about applying offsetof() to non-POD 37.182 +// object and xlc cannot compile the expression offsetof(DataLayout, 37.183 +// _cells[index]) in DataLayout::cell_offset() . Therefore we define 37.184 +// offset_of as it is defined for gcc. 37.185 +#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16) 37.186 + 37.187 +// Some constant sizes used throughout the AIX port 37.188 +#define SIZE_1K ((uint64_t) 0x400ULL) 37.189 +#define SIZE_4K ((uint64_t) 0x1000ULL) 37.190 +#define SIZE_64K ((uint64_t) 0x10000ULL) 37.191 +#define SIZE_1M ((uint64_t) 0x100000ULL) 37.192 +#define SIZE_4M ((uint64_t) 0x400000ULL) 37.193 +#define SIZE_8M ((uint64_t) 0x800000ULL) 37.194 +#define SIZE_16M ((uint64_t) 0x1000000ULL) 37.195 +#define SIZE_256M ((uint64_t) 0x10000000ULL) 37.196 +#define SIZE_1G ((uint64_t) 0x40000000ULL) 37.197 +#define SIZE_2G ((uint64_t) 0x80000000ULL) 37.198 +#define SIZE_4G ((uint64_t) 0x100000000ULL) 37.199 +#define SIZE_16G ((uint64_t) 0x400000000ULL) 37.200 +#define SIZE_32G ((uint64_t) 0x800000000ULL) 37.201 +#define SIZE_64G ((uint64_t) 0x1000000000ULL) 37.202 +#define SIZE_1T ((uint64_t) 0x10000000000ULL) 37.203 + 37.204 + 37.205 +#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP