diff options
Diffstat (limited to 'src/os/solaris/vm')
-rw-r--r-- | src/os/solaris/vm/jvm_solaris.h | 4 | ||||
-rw-r--r-- | src/os/solaris/vm/os_solaris.cpp | 198 | ||||
-rw-r--r-- | src/os/solaris/vm/os_solaris.hpp | 2 | ||||
-rw-r--r-- | src/os/solaris/vm/perfMemory_solaris.cpp | 27 | ||||
-rw-r--r-- | src/os/solaris/vm/thread_solaris.inline.hpp | 19 |
5 files changed, 76 insertions, 174 deletions
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 |