aboutsummaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/os')
-rw-r--r--src/os/aix/vm/os_aix.cpp12
-rw-r--r--src/os/aix/vm/perfMemory_aix.cpp33
-rw-r--r--src/os/bsd/dtrace/hotspot.d6
-rw-r--r--src/os/bsd/vm/jsig.c34
-rw-r--r--src/os/bsd/vm/os_bsd.cpp22
-rw-r--r--src/os/bsd/vm/perfMemory_bsd.cpp27
-rw-r--r--src/os/linux/vm/os_linux.cpp207
-rw-r--r--src/os/linux/vm/perfMemory_linux.cpp27
-rw-r--r--src/os/solaris/vm/jvm_solaris.h4
-rw-r--r--src/os/solaris/vm/os_solaris.cpp198
-rw-r--r--src/os/solaris/vm/os_solaris.hpp2
-rw-r--r--src/os/solaris/vm/perfMemory_solaris.cpp27
-rw-r--r--src/os/solaris/vm/thread_solaris.inline.hpp19
-rw-r--r--src/os/windows/vm/os_windows.cpp32
14 files changed, 245 insertions, 405 deletions
diff --git a/src/os/aix/vm/os_aix.cpp b/src/os/aix/vm/os_aix.cpp
index 9a65f741a..4cd28b868 100644
--- a/src/os/aix/vm/os_aix.cpp
+++ b/src/os/aix/vm/os_aix.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2014 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -3727,6 +3727,11 @@ void os::Aix::check_signal_handler(int sig) {
tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
// No need to check this sig any longer
sigaddset(&check_signal_done, sig);
+ // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN
+ if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {
+ tty->print_cr("Running in non-interactive shell, %s handler is replaced by shell",
+ exception_name(sig, buf, O_BUFLEN));
+ }
} else if (os::Aix::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Aix::get_our_sigflags(sig)) {
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
tty->print("expected:" PTR32_FORMAT, os::Aix::get_our_sigflags(sig));
@@ -3987,11 +3992,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if (!guard_memory((char*)_polling_page, Aix::page_size())) {
diff --git a/src/os/aix/vm/perfMemory_aix.cpp b/src/os/aix/vm/perfMemory_aix.cpp
index 7d64b5f83..be6e855d9 100644
--- a/src/os/aix/vm/perfMemory_aix.cpp
+++ b/src/os/aix/vm/perfMemory_aix.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -201,6 +201,7 @@ static pid_t filename_to_pid(const char* filename) {
// the backing store files. Returns true if the directory is considered
// a secure location. Returns false if the statbuf is a symbolic link or
// if an error occurred.
+//
static bool is_statbuf_secure(struct stat *statp) {
if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
// The path represents a link or some non-directory file type,
@@ -209,15 +210,18 @@ static bool is_statbuf_secure(struct stat *statp) {
return false;
}
// We have an existing directory, check if the permissions are safe.
+ //
if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
// The directory is open for writing and could be subjected
// to a symlink or a hard link attack. Declare it insecure.
+ //
return false;
}
- // See if the uid of the directory matches the effective uid of the process.
- //
- if (statp->st_uid != geteuid()) {
+ // If user is not root then see if the uid of the directory matches the effective uid of the process.
+ uid_t euid = geteuid();
+ if ((euid != 0) && (statp->st_uid != euid)) {
// The directory was not created by this user, declare it insecure.
+ //
return false;
}
return true;
@@ -228,6 +232,7 @@ static bool is_statbuf_secure(struct stat *statp) {
// the backing store files. Returns true if the directory exists
// and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred.
+//
static bool is_directory_secure(const char* path) {
struct stat statbuf;
int result = 0;
@@ -454,13 +459,27 @@ static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
*saved_cwd_fd = result;
}
- // Set the current directory to dirname by using the fd of the directory.
+ // Set the current directory to dirname by using the fd of the directory and
+ // handle errors, otherwise shared memory files will be created in cwd.
result = fchdir(fd);
-
- return dirp;
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not change to directory %s", dirname);
+ }
+ if (*saved_cwd_fd != -1) {
+ ::close(*saved_cwd_fd);
+ *saved_cwd_fd = -1;
+ }
+ // Close the directory.
+ os::closedir(dirp);
+ return NULL;
+ } else {
+ return dirp;
+ }
}
// Close the directory and restore the current working directory.
+//
static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
int result;
diff --git a/src/os/bsd/dtrace/hotspot.d b/src/os/bsd/dtrace/hotspot.d
index 0e4802b51..996e1d782 100644
--- a/src/os/bsd/dtrace/hotspot.d
+++ b/src/os/bsd/dtrace/hotspot.d
@@ -47,8 +47,8 @@ provider hotspot {
probe mem__pool__gc__end(
char*, uintptr_t, char*, uintptr_t,
uintptr_t, uintptr_t, uintptr_t, uintptr_t);
- probe thread__probe__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
- probe thread__probe__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
probe thread__sleep__begin(long long);
probe thread__sleep__end(int);
probe thread__yield();
@@ -68,7 +68,7 @@ provider hotspot {
probe monitor__contended__entered(uintptr_t, uintptr_t, char*, uintptr_t);
probe monitor__contended__exit(uintptr_t, uintptr_t, char*, uintptr_t);
probe monitor__wait(uintptr_t, uintptr_t, char*, uintptr_t, uintptr_t);
- probe monitor__probe__waited(uintptr_t, uintptr_t, char*, uintptr_t);
+ probe monitor__waited(uintptr_t, uintptr_t, char*, uintptr_t);
probe monitor__notify(uintptr_t, uintptr_t, char*, uintptr_t);
probe monitor__notifyAll(uintptr_t, uintptr_t, char*, uintptr_t);
diff --git a/src/os/bsd/vm/jsig.c b/src/os/bsd/vm/jsig.c
index a8d98a084..a3ea0fdd4 100644
--- a/src/os/bsd/vm/jsig.c
+++ b/src/os/bsd/vm/jsig.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <string.h>
#define MAXSIGNUM 32
#define MASK(sig) ((unsigned int)1 << sig)
@@ -43,6 +44,9 @@
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
static unsigned int jvmsigs = 0; /* signals used by jvm */
+static pthread_key_t reentry_flag_key;
+static pthread_once_t reentry_key_init_once = PTHREAD_ONCE_INIT;
+
/* used to synchronize the installation of signal handlers */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
@@ -59,6 +63,15 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
static bool jvm_signal_installing = false;
static bool jvm_signal_installed = false;
+#define check_status(cmd) \
+ do { \
+ int status = (cmd); \
+ if (status != 0) { \
+ printf("error %s (%d) in " #cmd "\n", strerror(status), status); \
+ exit(1); \
+ } \
+ } while (0)
+
static void signal_lock() {
pthread_mutex_lock(&mutex);
/* When the jvm is installing its set of signal handlers, threads
@@ -74,8 +87,15 @@ static void signal_unlock() {
pthread_mutex_unlock(&mutex);
}
+static void reentry_tls_init() {
+ // value for reentry_flag_key will default to NULL (false)
+ check_status(pthread_key_create(&reentry_flag_key, NULL));
+}
+
static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
bool is_sigset) {
+ sa_handler_t res;
+
if (os_signal == NULL) {
if (!is_sigset) {
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
@@ -87,7 +107,12 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
exit(0);
}
}
- return (*os_signal)(sig, disp);
+ check_status(pthread_once(&reentry_key_init_once, reentry_tls_init));
+ // set reentry_flag_key to non-NULL to show reentry
+ check_status(pthread_setspecific(reentry_flag_key, &res));
+ res = (*os_signal)(sig, disp);
+ check_status(pthread_setspecific(reentry_flag_key, NULL));
+ return res;
}
static void save_signal_handler(int sig, sa_handler_t disp) {
@@ -161,6 +186,11 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
bool sigused;
struct sigaction oldAct;
+ check_status(pthread_once(&reentry_key_init_once, reentry_tls_init));
+ if (pthread_getspecific(reentry_flag_key) != NULL) {
+ return call_os_sigaction(sig, act, oact);
+ }
+
signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0;
diff --git a/src/os/bsd/vm/os_bsd.cpp b/src/os/bsd/vm/os_bsd.cpp
index e1c53c5b4..58b58967c 100644
--- a/src/os/bsd/vm/os_bsd.cpp
+++ b/src/os/bsd/vm/os_bsd.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1197,12 +1197,18 @@ pid_t os::Bsd::gettid() {
guarantee(retval != 0, "just checking");
return retval;
-#elif __FreeBSD__
+#else
+ #ifdef __FreeBSD__
retval = syscall(SYS_thr_self);
-#elif __OpenBSD__
+ #else
+ #ifdef __OpenBSD__
retval = syscall(SYS_getthrid);
-#elif __NetBSD__
+ #else
+ #ifdef __NetBSD__
retval = (pid_t) syscall(SYS__lwp_self);
+ #endif
+ #endif
+ #endif
#endif
if (retval == -1) {
@@ -3545,6 +3551,11 @@ void os::Bsd::check_signal_handler(int sig) {
tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
// No need to check this sig any longer
sigaddset(&check_signal_done, sig);
+ // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN
+ if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {
+ tty->print_cr("Running in non-interactive shell, %s handler is replaced by shell",
+ exception_name(sig, buf, O_BUFLEN));
+ }
} else if(os::Bsd::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Bsd::get_our_sigflags(sig)) {
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
tty->print("expected:" PTR32_FORMAT, os::Bsd::get_our_sigflags(sig));
@@ -3745,9 +3756,6 @@ jint os::init_2(void)
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) { }
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if( !guard_memory((char*)_polling_page, Bsd::page_size()) )
diff --git a/src/os/bsd/vm/perfMemory_bsd.cpp b/src/os/bsd/vm/perfMemory_bsd.cpp
index 5ee992ec0..f25c39d9e 100644
--- a/src/os/bsd/vm/perfMemory_bsd.cpp
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -217,9 +217,9 @@ static bool is_statbuf_secure(struct stat *statp) {
//
return false;
}
- // See if the uid of the directory matches the effective uid of the process.
- //
- if (statp->st_uid != geteuid()) {
+ // If user is not root then see if the uid of the directory matches the effective uid of the process.
+ uid_t euid = geteuid();
+ if ((euid != 0) && (statp->st_uid != euid)) {
// The directory was not created by this user, declare it insecure.
//
return false;
@@ -375,10 +375,23 @@ static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
*saved_cwd_fd = result;
}
- // Set the current directory to dirname by using the fd of the directory.
+ // Set the current directory to dirname by using the fd of the directory and
+ // handle errors, otherwise shared memory files will be created in cwd.
result = fchdir(fd);
-
- return dirp;
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not change to directory %s", dirname);
+ }
+ if (*saved_cwd_fd != -1) {
+ ::close(*saved_cwd_fd);
+ *saved_cwd_fd = -1;
+ }
+ // Close the directory.
+ os::closedir(dirp);
+ return NULL;
+ } else {
+ return dirp;
+ }
}
// Close the directory and restore the current working directory.
diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
index 3a24939a1..4f7c38ab3 100644
--- a/src/os/linux/vm/os_linux.cpp
+++ b/src/os/linux/vm/os_linux.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -160,35 +160,6 @@ static pthread_mutex_t dl_mutex;
// Declarations
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
-#ifdef JAVASE_EMBEDDED
-class MemNotifyThread: public Thread {
- friend class VMStructs;
- public:
- virtual void run();
-
- private:
- static MemNotifyThread* _memnotify_thread;
- int _fd;
-
- public:
-
- // Constructor
- MemNotifyThread(int fd);
-
- // Tester
- bool is_memnotify_thread() const { return true; }
-
- // Printing
- char* name() const { return (char*)"Linux MemNotify Thread"; }
-
- // Returns the single instance of the MemNotifyThread
- static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
-
- // Create and start the single instance of MemNotifyThread
- static void start();
-};
-#endif // JAVASE_EMBEDDED
-
// utility functions
static int SR_initialize();
@@ -238,44 +209,27 @@ bool os::have_special_privileges() {
#ifndef SYS_gettid
// i386: 224, ia64: 1105, amd64: 186, sparc 143
-#ifdef __ia64__
-#define SYS_gettid 1105
-#elif __i386__
-#define SYS_gettid 224
-#elif __amd64__
-#define SYS_gettid 186
-#elif __sparc__
-#define SYS_gettid 143
-#else
-#error define gettid for the arch
-#endif
+ #ifdef __ia64__
+ #define SYS_gettid 1105
+ #else
+ #ifdef __i386__
+ #define SYS_gettid 224
+ #else
+ #ifdef __amd64__
+ #define SYS_gettid 186
+ #else
+ #ifdef __sparc__
+ #define SYS_gettid 143
+ #else
+ #error define gettid for the arch
+ #endif
+ #endif
+ #endif
+ #endif
#endif
// Cpu architecture string
-#if defined(ZERO)
-static char cpu_arch[] = ZERO_LIBARCH;
-#elif defined(IA64)
-static char cpu_arch[] = "ia64";
-#elif defined(IA32)
-static char cpu_arch[] = "i386";
-#elif defined(AMD64)
-static char cpu_arch[] = "amd64";
-#elif defined(ARM)
-static char cpu_arch[] = "arm";
-#elif defined(PPC32)
-static char cpu_arch[] = "ppc";
-#elif defined(PPC64)
-static char cpu_arch[] = "ppc64";
-#elif defined(SPARC)
-# ifdef _LP64
-static char cpu_arch[] = "sparcv9";
-# else
-static char cpu_arch[] = "sparc";
-# endif
-#else
-#error Add appropriate cpu_arch setting
-#endif
-
+static char cpu_arch[] = HOTSPOT_LIB_ARCH;
// pid_t gettid()
//
@@ -4681,6 +4635,11 @@ void os::Linux::check_signal_handler(int sig) {
tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
// No need to check this sig any longer
sigaddset(&check_signal_done, sig);
+ // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN
+ if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {
+ tty->print_cr("Running in non-interactive shell, %s handler is replaced by shell",
+ exception_name(sig, buf, O_BUFLEN));
+ }
} else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) {
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
@@ -4936,17 +4895,6 @@ jint os::init_2(void)
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) {
-#ifdef JAVASE_EMBEDDED
- // Start the MemNotifyThread
- if (LowMemoryProtection) {
- MemNotifyThread::start();
- }
- return;
-#endif
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if( !guard_memory((char*)_polling_page, Linux::page_size()) )
@@ -5974,9 +5922,11 @@ void Parker::unpark() {
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant");
} else {
+ // must capture correct index before unlocking
+ int index = _cur_index;
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant");
- status = pthread_cond_signal (&_cond[_cur_index]);
+ status = pthread_cond_signal (&_cond[index]);
assert (status == 0, "invariant");
}
} else {
@@ -5992,14 +5942,6 @@ void Parker::unpark() {
extern char** environ;
-#ifndef __NR_fork
-#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
-#endif
-
-#ifndef __NR_execve
-#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
-#endif
-
// Run the specified command in a separate process. Return its exit value,
// or -1 on failure (e.g. can't fork a new process).
// Unlike system(), this function can be called from signal handler. It
@@ -6007,13 +5949,7 @@ extern char** environ;
int os::fork_and_exec(char* cmd) {
const char * argv[4] = {"sh", "-c", cmd, NULL};
- // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
- // pthread_atfork handlers and reset pthread library. All we need is a
- // separate process to execve. Make a direct syscall to fork process.
- // On IA64 there's no fork syscall, we have to use fork() and hope for
- // the best...
- pid_t pid = NOT_IA64(syscall(__NR_fork);)
- IA64_ONLY(fork();)
+ pid_t pid = fork();
if (pid < 0) {
// fork failed
@@ -6022,15 +5958,7 @@ int os::fork_and_exec(char* cmd) {
} else if (pid == 0) {
// child process
- // execve() in LinuxThreads will call pthread_kill_other_threads_np()
- // first to kill every thread on the thread list. Because this list is
- // not reset by fork() (see notes above), execve() will instead kill
- // every thread in the parent process. We know this is the only thread
- // in the new process, so make a system call directly.
- // IA64 should use normal execve() from glibc to match the glibc fork()
- // above.
- NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
- IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
+ execve("/bin/sh", (char* const*)argv, environ);
// execve failed
_exit(-1);
@@ -6123,83 +6051,6 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
return strlen(buffer);
}
-#ifdef JAVASE_EMBEDDED
-//
-// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
-//
-MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
-
-// ctor
-//
-MemNotifyThread::MemNotifyThread(int fd): Thread() {
- assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
- _fd = fd;
-
- if (os::create_thread(this, os::os_thread)) {
- _memnotify_thread = this;
- os::set_priority(this, NearMaxPriority);
- os::start_thread(this);
- }
-}
-
-// Where all the work gets done
-//
-void MemNotifyThread::run() {
- assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
-
- // Set up the select arguments
- fd_set rfds;
- if (_fd != -1) {
- FD_ZERO(&rfds);
- FD_SET(_fd, &rfds);
- }
-
- // Now wait for the mem_notify device to wake up
- while (1) {
- // Wait for the mem_notify device to signal us..
- int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
- if (rc == -1) {
- perror("select!\n");
- break;
- } else if (rc) {
- //ssize_t free_before = os::available_memory();
- //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
-
- // The kernel is telling us there is not much memory left...
- // try to do something about that
-
- // If we are not already in a GC, try one.
- if (!Universe::heap()->is_gc_active()) {
- Universe::heap()->collect(GCCause::_allocation_failure);
-
- //ssize_t free_after = os::available_memory();
- //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
- //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
- }
- // We might want to do something like the following if we find the GC's are not helping...
- // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
- }
- }
-}
-
-//
-// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
-//
-void MemNotifyThread::start() {
- int fd;
- fd = open ("/dev/mem_notify", O_RDONLY, 0);
- if (fd < 0) {
- return;
- }
-
- if (memnotify_thread() == NULL) {
- new MemNotifyThread(fd);
- }
-}
-
-#endif // JAVASE_EMBEDDED
-
-
/////////////// Unit tests ///////////////
#ifndef PRODUCT
diff --git a/src/os/linux/vm/perfMemory_linux.cpp b/src/os/linux/vm/perfMemory_linux.cpp
index 9beb1113e..8510abbac 100644
--- a/src/os/linux/vm/perfMemory_linux.cpp
+++ b/src/os/linux/vm/perfMemory_linux.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -217,9 +217,9 @@ static bool is_statbuf_secure(struct stat *statp) {
//
return false;
}
- // See if the uid of the directory matches the effective uid of the process.
- //
- if (statp->st_uid != geteuid()) {
+ // If user is not root then see if the uid of the directory matches the effective uid of the process.
+ uid_t euid = geteuid();
+ if ((euid != 0) && (statp->st_uid != euid)) {
// The directory was not created by this user, declare it insecure.
//
return false;
@@ -374,10 +374,23 @@ static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
*saved_cwd_fd = result;
}
- // Set the current directory to dirname by using the fd of the directory.
+ // Set the current directory to dirname by using the fd of the directory and
+ // handle errors, otherwise shared memory files will be created in cwd.
result = fchdir(fd);
-
- return dirp;
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not change to directory %s", dirname);
+ }
+ if (*saved_cwd_fd != -1) {
+ ::close(*saved_cwd_fd);
+ *saved_cwd_fd = -1;
+ }
+ // Close the directory.
+ os::closedir(dirp);
+ return NULL;
+ } else {
+ return dirp;
+ }
}
// Close the directory and restore the current working directory.
diff --git a/src/os/solaris/vm/jvm_solaris.h b/src/os/solaris/vm/jvm_solaris.h
index 57b32ac16..f1fa075bc 100644
--- a/src/os/solaris/vm/jvm_solaris.h
+++ b/src/os/solaris/vm/jvm_solaris.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,9 @@
* JNI conversion, which should be sorted out later.
*/
+#define __USE_LEGACY_PROTOTYPES__
#include <dirent.h> /* For DIR */
+#undef __USE_LEGACY_PROTOTYPES__
#include <sys/param.h> /* For MAXPATHLEN */
#include <sys/socket.h> /* For socklen_t */
#include <unistd.h> /* For F_OK, R_OK, W_OK */
diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp
index c74dc70c6..2b4e33c66 100644
--- a/src/os/solaris/vm/os_solaris.cpp
+++ b/src/os/solaris/vm/os_solaris.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,75 +178,6 @@ extern "C" {
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
-// Thread Local Storage
-// This is common to all Solaris platforms so it is defined here,
-// in this common file.
-// The declarations are in the os_cpu threadLS*.hpp files.
-//
-// Static member initialization for TLS
-Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
-
-#ifndef PRODUCT
-#define _PCT(n,d) ((100.0*(double)(n))/(double)(d))
-
-int ThreadLocalStorage::_tcacheHit = 0;
-int ThreadLocalStorage::_tcacheMiss = 0;
-
-void ThreadLocalStorage::print_statistics() {
- int total = _tcacheMiss+_tcacheHit;
- tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
- _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
-}
-#undef _PCT
-#endif // PRODUCT
-
-Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
- int index) {
- Thread *thread = get_thread_slow();
- if (thread != NULL) {
- address sp = os::current_stack_pointer();
- guarantee(thread->_stack_base == NULL ||
- (sp <= thread->_stack_base &&
- sp >= thread->_stack_base - thread->_stack_size) ||
- is_error_reported(),
- "sp must be inside of selected thread stack");
-
- thread->set_self_raw_id(raw_id); // mark for quick retrieval
- _get_thread_cache[ index ] = thread;
- }
- return thread;
-}
-
-
-static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
-#define NO_CACHED_THREAD ((Thread*)all_zero)
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-
- // Store the new value before updating the cache to prevent a race
- // between get_thread_via_cache_slowly() and this store operation.
- os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-
- // Update thread cache with new thread if setting on thread create,
- // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
- uintptr_t raw = pd_raw_thread_id();
- int ix = pd_cache_index(raw);
- _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
-}
-
-void ThreadLocalStorage::pd_init() {
- for (int i = 0; i < _pd_cache_size; i++) {
- _get_thread_cache[i] = NO_CACHED_THREAD;
- }
-}
-
-// Invalidate all the caches (happens to be the same as pd_init).
-void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
-
-#undef NO_CACHED_THREAD
-
-// END Thread Local Storage
-
static inline size_t adjust_stack_size(address base, size_t size) {
if ((ssize_t)size < 0) {
// 4759953: Compensate for ridiculous stack size.
@@ -1473,64 +1404,6 @@ int os::current_process_id() {
return (int)(_initial_pid ? _initial_pid : getpid());
}
-int os::allocate_thread_local_storage() {
- // %%% in Win32 this allocates a memory segment pointed to by a
- // register. Dan Stein can implement a similar feature in
- // Solaris. Alternatively, the VM can do the same thing
- // explicitly: malloc some storage and keep the pointer in a
- // register (which is part of the thread's context) (or keep it
- // in TLS).
- // %%% In current versions of Solaris, thr_self and TSD can
- // be accessed via short sequences of displaced indirections.
- // The value of thr_self is available as %g7(36).
- // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
- // assuming that the current thread already has a value bound to k.
- // It may be worth experimenting with such access patterns,
- // and later having the parameters formally exported from a Solaris
- // interface. I think, however, that it will be faster to
- // maintain the invariant that %g2 always contains the
- // JavaThread in Java code, and have stubs simply
- // treat %g2 as a caller-save register, preserving it in a %lN.
- thread_key_t tk;
- if (thr_keycreate( &tk, NULL ) )
- fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
- "(%s)", strerror(errno)));
- return int(tk);
-}
-
-void os::free_thread_local_storage(int index) {
- // %%% don't think we need anything here
- // if ( pthread_key_delete((pthread_key_t) tk) )
- // fatal("os::free_thread_local_storage: pthread_key_delete failed");
-}
-
-#define SMALLINT 32 // libthread allocate for tsd_common is a version specific
- // small number - point is NO swap space available
-void os::thread_local_storage_at_put(int index, void* value) {
- // %%% this is used only in threadLocalStorage.cpp
- if (thr_setspecific((thread_key_t)index, value)) {
- if (errno == ENOMEM) {
- vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR,
- "thr_setspecific: out of swap space");
- } else {
- fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
- "(%s)", strerror(errno)));
- }
- } else {
- ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
- }
-}
-
-// This function could be called before TLS is initialized, for example, when
-// VM receives an async signal or when VM causes a fatal error during
-// initialization. Return NULL if thr_getspecific() fails.
-void* os::thread_local_storage_at(int index) {
- // %%% this is used only in threadLocalStorage.cpp
- void* r = NULL;
- return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
-}
-
-
// gethrtime() should be monotonic according to the documentation,
// but some virtualized platforms are known to break this guarantee.
// getTimeNanos() must be guaranteed not to move backwards, so we
@@ -2168,7 +2041,9 @@ void os::print_memory_info(outputStream* st) {
st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10);
st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10);
st->cr();
- (void) check_addr0(st);
+ if (VMError::fatal_error_in_progress()) {
+ (void) check_addr0(st);
+ }
}
void os::print_siginfo(outputStream* st, void* siginfo) {
@@ -2696,29 +2571,30 @@ void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
}
}
+size_t os::Solaris::page_size_for_alignment(size_t alignment) {
+ assert(is_size_aligned(alignment, (size_t) vm_page_size()),
+ err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT,
+ alignment, (size_t) vm_page_size()));
+
+ for (int i = 0; _page_sizes[i] != 0; i++) {
+ if (is_size_aligned(alignment, _page_sizes[i])) {
+ return _page_sizes[i];
+ }
+ }
+
+ return (size_t) vm_page_size();
+}
+
int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
size_t alignment_hint, bool exec) {
int err = Solaris::commit_memory_impl(addr, bytes, exec);
- if (err == 0) {
- if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) {
- // If the large page size has been set and the VM
- // is using large pages, use the large page size
- // if it is smaller than the alignment hint. This is
- // a case where the VM wants to use a larger alignment size
- // for its own reasons but still want to use large pages
- // (which is what matters to setting the mpss range.
- size_t page_size = 0;
- if (large_page_size() < alignment_hint) {
- assert(UseLargePages, "Expected to be here for large page use only");
- page_size = large_page_size();
- } else {
- // If the alignment hint is less than the large page
- // size, the VM wants a particular alignment (thus the hint)
- // for internal reasons. Try to set the mpss range using
- // the alignment_hint.
- page_size = alignment_hint;
- }
- // Since this is a hint, ignore any failures.
+ if (err == 0 && UseLargePages && alignment_hint > 0) {
+ assert(is_size_aligned(bytes, alignment_hint),
+ err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint));
+
+ // The syscall memcntl requires an exact page size (see man memcntl for details).
+ size_t page_size = page_size_for_alignment(alignment_hint);
+ if (page_size > (size_t) vm_page_size()) {
(void)Solaris::setup_large_pages(addr, bytes, page_size);
}
}
@@ -3251,7 +3127,22 @@ void os::large_page_init() {
}
}
+bool os::Solaris::is_valid_page_size(size_t bytes) {
+ for (int i = 0; _page_sizes[i] != 0; i++) {
+ if (_page_sizes[i] == bytes) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
+ assert(is_valid_page_size(align), err_msg(SIZE_FORMAT " is not a valid page size", align));
+ assert(is_ptr_aligned((void*) start, align),
+ err_msg(PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align));
+ assert(is_size_aligned(bytes, align),
+ err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align));
+
// Signal to OS that we want large pages for addresses
// from addr, addr + bytes
struct memcntl_mha mpss_struct;
@@ -4577,6 +4468,11 @@ void os::Solaris::check_signal_handler(int sig) {
tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
// No need to check this sig any longer
sigaddset(&check_signal_done, sig);
+ // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN
+ if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {
+ tty->print_cr("Running in non-interactive shell, %s handler is replaced by shell",
+ exception_name(sig, buf, O_BUFLEN));
+ }
} else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig));
@@ -5194,10 +5090,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if( mprotect((char *)_polling_page, page_size, PROT_NONE) != 0 )
diff --git a/src/os/solaris/vm/os_solaris.hpp b/src/os/solaris/vm/os_solaris.hpp
index 048534691..a22f0e9fe 100644
--- a/src/os/solaris/vm/os_solaris.hpp
+++ b/src/os/solaris/vm/os_solaris.hpp
@@ -110,6 +110,8 @@ class Solaris {
static meminfo_func_t _meminfo;
// Large Page Support
+ static bool is_valid_page_size(size_t bytes);
+ static size_t page_size_for_alignment(size_t alignment);
static bool setup_large_pages(caddr_t start, size_t bytes, size_t align);
static void init_thread_fpu_state(void);
diff --git a/src/os/solaris/vm/perfMemory_solaris.cpp b/src/os/solaris/vm/perfMemory_solaris.cpp
index 996b6d889..a90623e74 100644
--- a/src/os/solaris/vm/perfMemory_solaris.cpp
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -219,9 +219,9 @@ static bool is_statbuf_secure(struct stat *statp) {
//
return false;
}
- // See if the uid of the directory matches the effective uid of the process.
- //
- if (statp->st_uid != geteuid()) {
+ // If user is not root then see if the uid of the directory matches the effective uid of the process.
+ uid_t euid = geteuid();
+ if ((euid != 0) && (statp->st_uid != euid)) {
// The directory was not created by this user, declare it insecure.
//
return false;
@@ -377,10 +377,23 @@ static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
*saved_cwd_fd = result;
}
- // Set the current directory to dirname by using the fd of the directory.
+ // Set the current directory to dirname by using the fd of the directory and
+ // handle errors, otherwise shared memory files will be created in cwd.
result = fchdir(fd);
-
- return dirp;
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not change to directory %s", dirname);
+ }
+ if (*saved_cwd_fd != -1) {
+ ::close(*saved_cwd_fd);
+ *saved_cwd_fd = -1;
+ }
+ // Close the directory.
+ os::closedir(dirp);
+ return NULL;
+ } else {
+ return dirp;
+ }
}
// Close the directory and restore the current working directory.
diff --git a/src/os/solaris/vm/thread_solaris.inline.hpp b/src/os/solaris/vm/thread_solaris.inline.hpp
index d7d6d378f..48c85aaf7 100644
--- a/src/os/solaris/vm/thread_solaris.inline.hpp
+++ b/src/os/solaris/vm/thread_solaris.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,19 +40,12 @@
// For SPARC, to avoid excessive register window spill-fill faults,
// we aggressively inline these routines.
-inline Thread* ThreadLocalStorage::thread() {
- // don't use specialized code if +UseMallocOnly -- may confuse Purify et al.
- debug_only(if (UseMallocOnly) return get_thread_slow(););
+inline void ThreadLocalStorage::set_thread(Thread* thread) {
+ _thr_current = thread;
+}
- uintptr_t raw = pd_raw_thread_id();
- int ix = pd_cache_index(raw);
- Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix];
- if (candidate->self_raw_id() == raw) {
- // hit
- return candidate;
- } else {
- return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix);
- }
+inline Thread* ThreadLocalStorage::thread() {
+ return _thr_current;
}
#endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp
index c2839a187..e329c9fd6 100644
--- a/src/os/windows/vm/os_windows.cpp
+++ b/src/os/windows/vm/os_windows.cpp
@@ -110,11 +110,13 @@ static FILETIME process_user_time;
static FILETIME process_kernel_time;
#ifdef _M_IA64
-#define __CPU__ ia64
-#elif _M_AMD64
-#define __CPU__ amd64
+ #define __CPU__ ia64
#else
-#define __CPU__ i486
+ #ifdef _M_AMD64
+ #define __CPU__ amd64
+ #else
+ #define __CPU__ i486
+ #endif
#endif
// save DLL module handle, used by GetModuleFileName
@@ -2138,20 +2140,22 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler
// at the beginning of the target bundle.
exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
-#elif _M_AMD64
+#else
+ #ifdef _M_AMD64
// Do not blow up if no thread info available.
if (thread) {
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
}
// Set pc to handler
exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
-#else
+ #else
// Do not blow up if no thread info available.
if (thread) {
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
}
// Set pc to handler
exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
+ #endif
#endif
// Continue the execution
@@ -2250,7 +2254,8 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
// (division by zero is handled explicitly)
#ifdef _M_IA64
assert(0, "Fix Handle_IDiv_Exception");
-#elif _M_AMD64
+#else
+ #ifdef _M_AMD64
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Rip;
assert(pc[0] == 0xF7, "not an idiv opcode");
@@ -2261,7 +2266,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
ctx->Rax = (DWORD)min_jint; // result
ctx->Rdx = (DWORD)0; // remainder
// Continue the execution
-#else
+ #else
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Eip;
assert(pc[0] == 0xF7, "not an idiv opcode");
@@ -2272,6 +2277,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
ctx->Eax = (DWORD)min_jint; // result
ctx->Edx = (DWORD)0; // remainder
// Continue the execution
+ #endif
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
@@ -2351,10 +2357,12 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
// information is saved in the Unix format.
address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
-#elif _M_AMD64
- address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
+ #ifdef _M_AMD64
+ address pc = (address) exceptionInfo->ContextRecord->Rip;
+ #else
address pc = (address) exceptionInfo->ContextRecord->Eip;
+ #endif
#endif
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
@@ -4062,10 +4070,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
DWORD old_status;