8023038: PPC64 (part 15): Platform files for AIX/PPC64 support

Fri, 06 Sep 2013 20:16:09 +0200

author
simonis
date
Fri, 06 Sep 2013 20:16:09 +0200
changeset 6465
666e6ce3976c
parent 6464
b83f7d608548
child 6466
6a936747b569

8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
Reviewed-by: kvn

src/os/aix/vm/attachListener_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/c2_globals_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/decoder_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/globals_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/interfaceSupport_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/jsig.c file | annotate | diff | comparison | revisions
src/os/aix/vm/jvm_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/jvm_aix.h file | annotate | diff | comparison | revisions
src/os/aix/vm/libperfstat_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/libperfstat_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/loadlib_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/loadlib_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/mutex_aix.inline.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/osThread_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/osThread_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/os_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/os_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/os_aix.inline.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/os_share_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/perfMemory_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/porting_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/porting_aix.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/threadCritical_aix.cpp file | annotate | diff | comparison | revisions
src/os/aix/vm/thread_aix.inline.hpp file | annotate | diff | comparison | revisions
src/os/aix/vm/vmError_aix.cpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/orderAccess_aix_ppc.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/thread_aix_ppc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/aix_ppc/vm/vmStructs_aix_ppc.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/globalDefinitions_xlc.hpp file | annotate | diff | comparison | revisions
     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, &param);
 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, &param);
 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

mercurial