# HG changeset patch # User ehelin # Date 1393595764 -3600 # Node ID 7d30d4f37d3143accf04bf6c70f9e3ca3fc52d13 # Parent 5e7eb424460479251adf29ef00d3bbccd1d4989a# Parent 7f0e0366ec81e7c5f0865f0ee5e333cc9dcb2e92 Merge diff -r 7f0e0366ec81 -r 7d30d4f37d31 make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Thu Feb 27 10:36:50 2014 +0100 +++ b/make/windows/makefiles/projectcreator.make Fri Feb 28 14:56:04 2014 +0100 @@ -72,6 +72,7 @@ -ignorePath arm \ -ignorePath ppc \ -ignorePath zero \ + -ignorePath aix \ -hidePath .hg diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/bsd/vm/os_bsd.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -994,7 +994,7 @@ jlong os::javaTimeNanos() { - if (Bsd::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { struct timespec tp; int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); @@ -1010,7 +1010,7 @@ } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { - if (Bsd::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { info_ptr->max_value = ALL_64_BITS; // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past @@ -2513,85 +2513,6 @@ RESTARTABLE_RETURN_INT(::read(fd, buf, nBytes)); } -// TODO-FIXME: reconcile Solaris' os::sleep with the bsd variation. -// Solaris uses poll(), bsd uses park(). -// Poll() is likely a better choice, assuming that Thread.interrupt() -// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with -// SIGSEGV, see 4355769. - -int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - - ParkEvent * const slp = thread->_SleepEvent ; - slp->reset() ; - OrderAccess::fence() ; - - if (interruptible) { - jlong prevtime = javaTimeNanos(); - - for (;;) { - if (os::is_interrupted(thread, true)) { - return OS_INTRPT; - } - - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Bsd::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) { - return OS_OK; - } - - prevtime = newtime; - - { - assert(thread->is_Java_thread(), "sanity check"); - JavaThread *jt = (JavaThread *) thread; - ThreadBlockInVM tbivm(jt); - OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); - - jt->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - - slp->park(millis); - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); - } - } - } else { - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); - jlong prevtime = javaTimeNanos(); - - for (;;) { - // It'd be nice to avoid the back-to-back javaTimeNanos() calls on - // the 1st iteration ... - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Bsd::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) break ; - - prevtime = newtime; - slp->park(millis); - } - return OS_OK ; - } -} - void os::naked_short_sleep(jlong ms) { struct timespec req; @@ -2987,50 +2908,6 @@ guarantee(osthread->sr.is_running(), "Must be running!"); } -//////////////////////////////////////////////////////////////////////////////// -// interrupt support - -void os::interrupt(Thread* thread) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - if (!osthread->interrupted()) { - osthread->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); - ParkEvent * const slp = thread->_SleepEvent ; - if (slp != NULL) slp->unpark() ; - } - - // For JSR166. Unpark even if interrupt status already was set - if (thread->is_Java_thread()) - ((JavaThread*)thread)->parker()->unpark(); - - ParkEvent * ev = thread->_ParkEvent ; - if (ev != NULL) ev->unpark() ; - -} - -bool os::is_interrupted(Thread* thread, bool clear_interrupted) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - bool interrupted = osthread->interrupted(); - - if (interrupted && clear_interrupted) { - osthread->set_interrupted(false); - // consider thread->_SleepEvent->reset() ... optional optimization - } - - return interrupted; -} - /////////////////////////////////////////////////////////////////////////////////// // signal handling (except suspend/resume) diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/bsd/vm/os_bsd.hpp --- a/src/os/bsd/vm/os_bsd.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/bsd/vm/os_bsd.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -134,10 +134,6 @@ // Real-time clock functions static void clock_init(void); - static inline bool supports_monotonic_clock() { - return _clock_gettime != NULL; - } - static int clock_gettime(clockid_t clock_id, struct timespec *tp) { return _clock_gettime ? _clock_gettime(clock_id, tp) : -1; } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/bsd/vm/os_bsd.inline.hpp --- a/src/os/bsd/vm/os_bsd.inline.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/bsd/vm/os_bsd.inline.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -286,4 +286,8 @@ return ::setsockopt(fd, level, optname, optval, optlen); } +inline bool os::supports_monotonic_clock() { + return Bsd::_clock_gettime != NULL; +} + #endif // OS_BSD_VM_OS_BSD_INLINE_HPP diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/linux/vm/os_linux.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1456,7 +1456,7 @@ } jlong os::javaTimeNanos() { - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { struct timespec tp; int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); @@ -1472,7 +1472,7 @@ } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { info_ptr->max_value = ALL_64_BITS; // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past @@ -3757,85 +3757,6 @@ return ::read(fd, buf, nBytes); } -// TODO-FIXME: reconcile Solaris' os::sleep with the linux variation. -// Solaris uses poll(), linux uses park(). -// Poll() is likely a better choice, assuming that Thread.interrupt() -// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with -// SIGSEGV, see 4355769. - -int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - - ParkEvent * const slp = thread->_SleepEvent ; - slp->reset() ; - OrderAccess::fence() ; - - if (interruptible) { - jlong prevtime = javaTimeNanos(); - - for (;;) { - if (os::is_interrupted(thread, true)) { - return OS_INTRPT; - } - - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Linux::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) { - return OS_OK; - } - - prevtime = newtime; - - { - assert(thread->is_Java_thread(), "sanity check"); - JavaThread *jt = (JavaThread *) thread; - ThreadBlockInVM tbivm(jt); - OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); - - jt->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - - slp->park(millis); - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); - } - } - } else { - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); - jlong prevtime = javaTimeNanos(); - - for (;;) { - // It'd be nice to avoid the back-to-back javaTimeNanos() calls on - // the 1st iteration ... - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Linux::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) break ; - - prevtime = newtime; - slp->park(millis); - } - return OS_OK ; - } -} - // // Short sleep, direct OS call. // @@ -4188,50 +4109,6 @@ guarantee(osthread->sr.is_running(), "Must be running!"); } -//////////////////////////////////////////////////////////////////////////////// -// interrupt support - -void os::interrupt(Thread* thread) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - if (!osthread->interrupted()) { - osthread->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); - ParkEvent * const slp = thread->_SleepEvent ; - if (slp != NULL) slp->unpark() ; - } - - // For JSR166. Unpark even if interrupt status already was set - if (thread->is_Java_thread()) - ((JavaThread*)thread)->parker()->unpark(); - - ParkEvent * ev = thread->_ParkEvent ; - if (ev != NULL) ev->unpark() ; - -} - -bool os::is_interrupted(Thread* thread, bool clear_interrupted) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - bool interrupted = osthread->interrupted(); - - if (interrupted && clear_interrupted) { - osthread->set_interrupted(false); - // consider thread->_SleepEvent->reset() ... optional optimization - } - - return interrupted; -} - /////////////////////////////////////////////////////////////////////////////////// // signal handling (except suspend/resume) @@ -4756,7 +4633,7 @@ fatal(err_msg("pthread_condattr_init: %s", strerror(status))); } // Only set the clock if CLOCK_MONOTONIC is available - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { if (status == EINVAL) { warning("Unable to use monotonic clock with relative timed-waits" \ @@ -5586,7 +5463,7 @@ seconds = 50000000; } - if (os::Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { struct timespec now; int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); assert_status(status == 0, status, "clock_gettime"); @@ -5803,7 +5680,7 @@ assert (time > 0, "convertTime"); time_t max_secs = 0; - if (!os::Linux::supports_monotonic_clock() || isAbsolute) { + if (!os::supports_monotonic_clock() || isAbsolute) { struct timeval now; int status = gettimeofday(&now, NULL); assert(status == 0, "gettimeofday"); diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/linux/vm/os_linux.hpp --- a/src/os/linux/vm/os_linux.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/linux/vm/os_linux.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -206,10 +206,6 @@ // fast POSIX clocks support static void fast_thread_clock_init(void); - static inline bool supports_monotonic_clock() { - return _clock_gettime != NULL; - } - static int clock_gettime(clockid_t clock_id, struct timespec *tp) { return _clock_gettime ? _clock_gettime(clock_id, tp) : -1; } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/linux/vm/os_linux.inline.hpp --- a/src/os/linux/vm/os_linux.inline.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/linux/vm/os_linux.inline.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -288,4 +288,8 @@ return ::setsockopt(fd, level, optname, optval, optlen); } +inline bool os::supports_monotonic_clock() { + return Linux::_clock_gettime != NULL; +} + #endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/posix/vm/os_posix.cpp --- a/src/os/posix/vm/os_posix.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/posix/vm/os_posix.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -25,6 +25,7 @@ #include "utilities/globalDefinitions.hpp" #include "prims/jvm.h" #include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "utilities/vmError.hpp" @@ -315,6 +316,135 @@ return agent_entry_name; } +int os::sleep(Thread* thread, jlong millis, bool interruptible) { + assert(thread == Thread::current(), "thread consistency check"); + + ParkEvent * const slp = thread->_SleepEvent ; + slp->reset() ; + OrderAccess::fence() ; + + if (interruptible) { + jlong prevtime = javaTimeNanos(); + + for (;;) { + if (os::is_interrupted(thread, true)) { + return OS_INTRPT; + } + + jlong newtime = javaTimeNanos(); + + if (newtime - prevtime < 0) { + // time moving backwards, should only happen if no monotonic clock + // not a guarantee() because JVM should not abort on kernel/glibc bugs + assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected in os::sleep(interruptible)"); + } else { + millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; + } + + if (millis <= 0) { + return OS_OK; + } + + prevtime = newtime; + + { + assert(thread->is_Java_thread(), "sanity check"); + JavaThread *jt = (JavaThread *) thread; + ThreadBlockInVM tbivm(jt); + OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); + + jt->set_suspend_equivalent(); + // cleared by handle_special_suspend_equivalent_condition() or + // java_suspend_self() via check_and_wait_while_suspended() + + slp->park(millis); + + // were we externally suspended while we were waiting? + jt->check_and_wait_while_suspended(); + } + } + } else { + OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); + jlong prevtime = javaTimeNanos(); + + for (;;) { + // It'd be nice to avoid the back-to-back javaTimeNanos() calls on + // the 1st iteration ... + jlong newtime = javaTimeNanos(); + + if (newtime - prevtime < 0) { + // time moving backwards, should only happen if no monotonic clock + // not a guarantee() because JVM should not abort on kernel/glibc bugs + assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected on os::sleep(!interruptible)"); + } else { + millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; + } + + if (millis <= 0) break ; + + prevtime = newtime; + slp->park(millis); + } + return OS_OK ; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// interrupt support + +void os::interrupt(Thread* thread) { + assert(Thread::current() == thread || Threads_lock->owned_by_self(), + "possibility of dangling Thread pointer"); + + OSThread* osthread = thread->osthread(); + + if (!osthread->interrupted()) { + osthread->set_interrupted(true); + // More than one thread can get here with the same value of osthread, + // resulting in multiple notifications. We do, however, want the store + // to interrupted() to be visible to other threads before we execute unpark(). + OrderAccess::fence(); + ParkEvent * const slp = thread->_SleepEvent ; + if (slp != NULL) slp->unpark() ; + } + + // For JSR166. Unpark even if interrupt status already was set + if (thread->is_Java_thread()) + ((JavaThread*)thread)->parker()->unpark(); + + ParkEvent * ev = thread->_ParkEvent ; + if (ev != NULL) ev->unpark() ; + +} + +bool os::is_interrupted(Thread* thread, bool clear_interrupted) { + assert(Thread::current() == thread || Threads_lock->owned_by_self(), + "possibility of dangling Thread pointer"); + + OSThread* osthread = thread->osthread(); + + bool interrupted = osthread->interrupted(); + + // NOTE that since there is no "lock" around the interrupt and + // is_interrupted operations, there is the possibility that the + // interrupted flag (in osThread) will be "false" but that the + // low-level events will be in the signaled state. This is + // intentional. The effect of this is that Object.wait() and + // LockSupport.park() will appear to have a spurious wakeup, which + // is allowed and not harmful, and the possibility is so rare that + // it is not worth the added complexity to add yet another lock. + // For the sleep event an explicit reset is performed on entry + // to os::sleep, so there is no early return. It has also been + // recommended not to put the interrupted flag into the "event" + // structure because it hides the issue. + if (interrupted && clear_interrupted) { + osthread->set_interrupted(false); + // consider thread->_SleepEvent->reset() ... optional optimization + } + + return interrupted; +} + // Returned string is a constant. For unknown signals "UNKNOWN" is returned. const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) { diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/solaris/vm/os_solaris.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -332,12 +332,6 @@ ThreadStateTransition::transition(thread, thread_state, _thread_blocked); } -// Version of setup_interruptible() for threads that are already in -// _thread_blocked. Used by os_sleep(). -void os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) { - thread->frame_anchor()->make_walkable(thread); -} - JavaThread* os::Solaris::setup_interruptible() { JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); setup_interruptible(thread); @@ -3370,61 +3364,6 @@ return true; } -static int os_sleep(jlong millis, bool interruptible) { - const jlong limit = INT_MAX; - jlong prevtime; - int res; - - while (millis > limit) { - if ((res = os_sleep(limit, interruptible)) != OS_OK) - return res; - millis -= limit; - } - - // Restart interrupted polls with new parameters until the proper delay - // has been completed. - - prevtime = getTimeMillis(); - - while (millis > 0) { - jlong newtime; - - if (!interruptible) { - // Following assert fails for os::yield_all: - // assert(!thread->is_Java_thread(), "must not be java thread"); - res = poll(NULL, 0, millis); - } else { - JavaThread *jt = JavaThread::current(); - - INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt, - os::Solaris::clear_interrupted); - } - - // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for - // thread.Interrupt. - - // See c/r 6751923. Poll can return 0 before time - // has elapsed if time is set via clock_settime (as NTP does). - // res == 0 if poll timed out (see man poll RETURN VALUES) - // using the logic below checks that we really did - // sleep at least "millis" if not we'll sleep again. - if( ( res == 0 ) || ((res == OS_ERR) && (errno == EINTR))) { - newtime = getTimeMillis(); - assert(newtime >= prevtime, "time moving backwards"); - /* Doing prevtime and newtime in microseconds doesn't help precision, - and trying to round up to avoid lost milliseconds can result in a - too-short delay. */ - millis -= newtime - prevtime; - if(millis <= 0) - return OS_OK; - prevtime = newtime; - } else - return res; - } - - return OS_OK; -} - // Read calls from inside the vm need to perform state transitions size_t os::read(int fd, void *buf, unsigned int nBytes) { INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); @@ -3434,69 +3373,6 @@ INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); } -int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - - // TODO-FIXME: this should be removed. - // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock - // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate - // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving - // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel - // is fooled into believing that the system is making progress. In the code below we block the - // the watcher thread while safepoint is in progress so that it would not appear as though the - // system is making progress. - if (!Solaris::T2_libthread() && - thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) { - // We now try to acquire the threads lock. Since this lock is held by the VM thread during - // the entire safepoint, the watcher thread will line up here during the safepoint. - Threads_lock->lock_without_safepoint_check(); - Threads_lock->unlock(); - } - - if (thread->is_Java_thread()) { - // This is a JavaThread so we honor the _thread_blocked protocol - // even for sleeps of 0 milliseconds. This was originally done - // as a workaround for bug 4338139. However, now we also do it - // to honor the suspend-equivalent protocol. - - JavaThread *jt = (JavaThread *) thread; - ThreadBlockInVM tbivm(jt); - - jt->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - - int ret_code; - if (millis <= 0) { - thr_yield(); - ret_code = 0; - } else { - // The original sleep() implementation did not create an - // OSThreadWaitState helper for sleeps of 0 milliseconds. - // I'm preserving that decision for now. - OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); - - ret_code = os_sleep(millis, interruptible); - } - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); - - return ret_code; - } - - // non-JavaThread from this point on: - - if (millis <= 0) { - thr_yield(); - return 0; - } - - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); - - return os_sleep(millis, interruptible); -} - void os::naked_short_sleep(jlong ms) { assert(ms < 1000, "Un-interruptable sleep, short time use only"); @@ -4139,68 +4015,6 @@ errno = old_errno; } - -void os::interrupt(Thread* thread) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - int isInterrupted = osthread->interrupted(); - if (!isInterrupted) { - osthread->set_interrupted(true); - OrderAccess::fence(); - // os::sleep() is implemented with either poll (NULL,0,timeout) or - // by parking on _SleepEvent. If the former, thr_kill will unwedge - // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper. - ParkEvent * const slp = thread->_SleepEvent ; - if (slp != NULL) slp->unpark() ; - } - - // For JSR166: unpark after setting status but before thr_kill -dl - if (thread->is_Java_thread()) { - ((JavaThread*)thread)->parker()->unpark(); - } - - // Handle interruptible wait() ... - ParkEvent * const ev = thread->_ParkEvent ; - if (ev != NULL) ev->unpark() ; - - // When events are used everywhere for os::sleep, then this thr_kill - // will only be needed if UseVMInterruptibleIO is true. - - if (!isInterrupted) { - int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt()); - assert_status(status == 0, status, "thr_kill"); - - // Bump thread interruption counter - RuntimeService::record_thread_interrupt_signaled_count(); - } -} - - -bool os::is_interrupted(Thread* thread, bool clear_interrupted) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - bool res = osthread->interrupted(); - - // NOTE that since there is no "lock" around these two operations, - // there is the possibility that the interrupted flag will be - // "false" but that the interrupt event will be set. This is - // intentional. The effect of this is that Object.wait() will appear - // to have a spurious wakeup, which is not harmful, and the - // possibility is so rare that it is not worth the added complexity - // to add yet another lock. It has also been recommended not to put - // the interrupted flag into the os::Solaris::Event structure, - // because it hides the issue. - if (res && clear_interrupted) { - osthread->set_interrupted(false); - } - return res; -} - - void os::print_statistics() { } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/solaris/vm/os_solaris.inline.hpp --- a/src/os/solaris/vm/os_solaris.inline.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/solaris/vm/os_solaris.inline.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -260,4 +260,10 @@ const char *optval, socklen_t optlen) { return ::setsockopt(fd, level, optname, optval, optlen); } + +inline bool os::supports_monotonic_clock() { + // javaTimeNanos() is monotonic on Solaris, see getTimeNanos() comments + return true; +} + #endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/windows/vm/os_windows.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -628,8 +628,6 @@ delete osthread; } - -static int has_performance_count = 0; static jlong first_filetime; static jlong initial_performance_count; static jlong performance_frequency; @@ -645,7 +643,7 @@ jlong os::elapsed_counter() { LARGE_INTEGER count; - if (has_performance_count) { + if (win32::_has_performance_count) { QueryPerformanceCounter(&count); return as_long(count) - initial_performance_count; } else { @@ -657,7 +655,7 @@ jlong os::elapsed_frequency() { - if (has_performance_count) { + if (win32::_has_performance_count) { return performance_frequency; } else { // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601. @@ -736,15 +734,15 @@ return false; } -static void initialize_performance_counter() { +void os::win32::initialize_performance_counter() { LARGE_INTEGER count; if (QueryPerformanceFrequency(&count)) { - has_performance_count = 1; + win32::_has_performance_count = 1; performance_frequency = as_long(count); QueryPerformanceCounter(&count); initial_performance_count = as_long(count); } else { - has_performance_count = 0; + win32::_has_performance_count = 0; FILETIME wt; GetSystemTimeAsFileTime(&wt); first_filetime = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime); @@ -839,7 +837,7 @@ } jlong os::javaTimeNanos() { - if (!has_performance_count) { + if (!win32::_has_performance_count) { return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do. } else { LARGE_INTEGER current_count; @@ -852,7 +850,7 @@ } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { - if (!has_performance_count) { + if (!win32::_has_performance_count) { // javaTimeMillis() doesn't have much percision, // but it is not going to wrap -- so all 64 bits info_ptr->max_value = ALL_64_BITS; @@ -3682,6 +3680,8 @@ bool os::win32::_is_windows_2003 = false; bool os::win32::_is_windows_server = false; +bool os::win32::_has_performance_count = 0; + void os::win32::initialize_system_info() { SYSTEM_INFO si; GetSystemInfo(&si); diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/windows/vm/os_windows.hpp --- a/src/os/windows/vm/os_windows.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/windows/vm/os_windows.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -42,6 +42,7 @@ static bool _is_nt; static bool _is_windows_2003; static bool _is_windows_server; + static bool _has_performance_count; static void print_windows_version(outputStream* st); @@ -63,6 +64,9 @@ // load dll from Windows system directory or Windows directory static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen); + private: + static void initialize_performance_counter(); + public: // Generic interface: diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/os/windows/vm/os_windows.inline.hpp --- a/src/os/windows/vm/os_windows.inline.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/os/windows/vm/os_windows.inline.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -107,6 +107,10 @@ return ::close(fd); } +inline bool os::supports_monotonic_clock() { + return win32::_has_performance_count; +} + #ifndef PRODUCT #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \ os::win32::call_test_func_with_wrapper(f) diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -2276,7 +2276,7 @@ if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) { assert(instruction->exception_state() == NULL || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState - || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()), + || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->should_retain_local_variables()), "exception_state should be of exception kind"); return new XHandlers(); } @@ -2367,7 +2367,7 @@ // This scope and all callees do not handle exceptions, so the local // variables of this scope are not needed. However, the scope itself is // required for a correct exception stack trace -> clear out the locals. - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); } else { cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); @@ -3251,7 +3251,7 @@ ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { ValueStack* s = copy_state_exhandling_with_bci(bci); if (s == NULL) { - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { s = state()->copy(ValueStack::ExceptionState, bci); } else { s = state()->copy(ValueStack::EmptyExceptionState, bci); diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/c1/c1_Instruction.cpp --- a/src/share/vm/c1/c1_Instruction.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/c1/c1_Instruction.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -76,7 +76,7 @@ void Instruction::update_exception_state(ValueStack* state) { if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { - assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); + assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->should_retain_local_variables(), "unexpected state kind"); _exception_state = state; } else { _exception_state = NULL; diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/c1/c1_ValueStack.cpp --- a/src/share/vm/c1/c1_ValueStack.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/c1/c1_ValueStack.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -52,7 +52,7 @@ , _stack() , _locks(copy_from->locks_size()) { - assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals"); + assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals"); if (kind != EmptyExceptionState) { // only allocate space if we need to copy the locals-array _locals = Values(copy_from->locals_size()); diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/c1/c1_ValueStack.hpp --- a/src/share/vm/c1/c1_ValueStack.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/c1/c1_ValueStack.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -75,7 +75,7 @@ void set_caller_state(ValueStack* s) { assert(kind() == EmptyExceptionState || - (Compilation::current()->env()->jvmti_can_access_local_variables() && kind() == ExceptionState), + (Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState), "only EmptyExceptionStates can be modified"); _caller_state = s; } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/ci/ciEnv.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -136,6 +136,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::ciEnv(Arena* arena) { @@ -186,6 +191,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::~ciEnv() { @@ -205,6 +215,31 @@ _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); + _jvmti_can_pop_frame = JvmtiExport::can_pop_frame(); +} + +bool ciEnv::should_retain_local_variables() const { + return _jvmti_can_access_local_variables || _jvmti_can_pop_frame; +} + +bool ciEnv::jvmti_state_changed() const { + if (!_jvmti_can_access_local_variables && + JvmtiExport::can_access_local_variables()) { + return true; + } + if (!_jvmti_can_hotswap_or_post_breakpoint && + JvmtiExport::can_hotswap_or_post_breakpoint()) { + return true; + } + if (!_jvmti_can_post_on_exceptions && + JvmtiExport::can_post_on_exceptions()) { + return true; + } + if (!_jvmti_can_pop_frame && + JvmtiExport::can_pop_frame()) { + return true; + } + return false; } // ------------------------------------------------------------------ @@ -940,13 +975,7 @@ No_Safepoint_Verifier nsv; // Change in Jvmti state may invalidate compilation. - if (!failing() && - ( (!jvmti_can_hotswap_or_post_breakpoint() && - JvmtiExport::can_hotswap_or_post_breakpoint()) || - (!jvmti_can_access_local_variables() && - JvmtiExport::can_access_local_variables()) || - (!jvmti_can_post_on_exceptions() && - JvmtiExport::can_post_on_exceptions()) )) { + if (!failing() && jvmti_state_changed()) { record_failure("Jvmti state change invalidated dependencies"); } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/ci/ciEnv.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -69,6 +69,7 @@ bool _jvmti_can_hotswap_or_post_breakpoint; bool _jvmti_can_access_local_variables; bool _jvmti_can_post_on_exceptions; + bool _jvmti_can_pop_frame; // Cache DTrace flags bool _dtrace_extended_probes; @@ -332,8 +333,9 @@ // Cache Jvmti state void cache_jvmti_state(); + bool jvmti_state_changed() const; + bool should_retain_local_variables() const; bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; } - bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; } bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions; } // Cache DTrace flags diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/ci/ciMethod.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -412,7 +412,7 @@ // information. MethodLivenessResult ciMethod::liveness_at_bci(int bci) { MethodLivenessResult result = raw_liveness_at_bci(bci); - if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { + if (CURRENT_ENV->should_retain_local_variables() || DeoptimizeALot || CompileTheWorld) { // Keep all locals live for the user's edification and amusement. result.at_put_range(0, result.size(), true); } diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -49,6 +49,7 @@ #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/jvmtiRedefineClasses.hpp" +#include "prims/jvmtiThreadState.hpp" #include "prims/methodComparator.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" @@ -862,10 +863,16 @@ // Step 10 and 11 Handle e(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError + JvmtiExport::clear_detected_exception((JavaThread*)THREAD); { EXCEPTION_MARK; this_oop->set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError + JvmtiExport::clear_detected_exception((JavaThread*)THREAD); } DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_oop()), -1,wait); if (e->is_a(SystemDictionary::Error_klass())) { diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/opto/c2compiler.cpp --- a/src/share/vm/opto/c2compiler.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/opto/c2compiler.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -114,7 +114,7 @@ assert(is_initialized(), "Compiler thread must be initialized"); bool subsume_loads = SubsumeLoads; - bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); + bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables(); bool eliminate_boxing = EliminateAutoBox; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/opto/graphKit.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -864,7 +864,7 @@ } } - if (env()->jvmti_can_access_local_variables()) { + if (env()->should_retain_local_variables()) { // At any safepoint, this method can get breakpointed, which would // then require an immediate deoptimization. can_prune_locals = false; // do not prune locals diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/prims/jvm.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1241,7 +1241,11 @@ if (HAS_PENDING_EXCEPTION) { pending_exception = Handle(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report PrivilegedActionException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); + } if ( pending_exception->is_a(SystemDictionary::Exception_klass()) && !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { // Throw a java.security.PrivilegedActionException(Exception e) exception diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/prims/jvmtiExport.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -2161,6 +2161,15 @@ } } +void JvmtiExport::clear_detected_exception(JavaThread* thread) { + assert(JavaThread::current() == thread, "thread is not current"); + + JvmtiThreadState* state = thread->jvmti_thread_state(); + if (state != NULL) { + state->clear_exception_detected(); + } +} + void JvmtiExport::oops_do(OopClosure* f) { JvmtiCurrentBreakpoints::oops_do(f); JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f); diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/prims/jvmtiExport.hpp --- a/src/share/vm/prims/jvmtiExport.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/prims/jvmtiExport.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -363,6 +363,7 @@ } static void cleanup_thread (JavaThread* thread) NOT_JVMTI_RETURN; + static void clear_detected_exception (JavaThread* thread) NOT_JVMTI_RETURN; static void oops_do(OopClosure* f) NOT_JVMTI_RETURN; static void weak_oops_do(BoolObjectClosure* b, OopClosure* f) NOT_JVMTI_RETURN; diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -3081,6 +3081,23 @@ } } } + + StackValueCollection* exprs = jvf->expressions(); + for (int index=0; index < exprs->size(); index++) { + if (exprs->at(index)->type() == T_OBJECT) { + oop o = exprs->obj_at(index)(); + if (o == NULL) { + continue; + } + + // stack reference + if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method, + bci, locals->size() + index, o)) { + return false; + } + } + } + } else { blk->set_context(thread_tag, tid, depth, method); if (is_top_frame) { diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/runtime/arguments.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -1661,6 +1661,9 @@ return result; } +// Use static initialization to get the default before parsing +static const uintx DefaultHeapBaseMinAddress = HeapBaseMinAddress; + void Arguments::set_heap_size() { if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) { // Deprecated flag @@ -1692,6 +1695,23 @@ if (UseCompressedOops) { // Limit the heap size to the maximum possible when using compressed oops julong max_coop_heap = (julong)max_heap_for_compressed_oops(); + + // HeapBaseMinAddress can be greater than default but not less than. + if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) { + if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) { + if (PrintMiscellaneous && Verbose) { // matches compressed oops printing flags + jio_fprintf(defaultStream::error_stream(), + "HeapBaseMinAddress must be at least " UINTX_FORMAT + " (" UINTX_FORMAT "G) which is greater than value given " + UINTX_FORMAT "\n", + DefaultHeapBaseMinAddress, + DefaultHeapBaseMinAddress/G, + HeapBaseMinAddress); + } + FLAG_SET_ERGO(uintx, HeapBaseMinAddress, DefaultHeapBaseMinAddress); + } + } + if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) { // Heap should be above HeapBaseMinAddress to get zero based compressed oops // but it should be not less than default MaxHeapSize. diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/runtime/os.hpp Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -165,6 +165,7 @@ static jlong javaTimeNanos(); static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr); static void run_periodic_checks(); + static bool supports_monotonic_clock(); // Returns the elapsed time in seconds since the vm started. diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/runtime/reflection.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -36,6 +36,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.hpp" #include "prims/jvm.h" +#include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -941,6 +942,11 @@ // Method resolution threw an exception; wrap it in an InvocationTargetException oop resolution_exception = PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report InvocationTargetException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); + } JavaCallArguments args(Handle(THREAD, resolution_exception)); THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), vmSymbols::throwable_void_signature(), @@ -1073,6 +1079,12 @@ // Method threw an exception; wrap it in an InvocationTargetException oop target_exception = PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report InvocationTargetException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); + } + JavaCallArguments args(Handle(THREAD, target_exception)); THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), vmSymbols::throwable_void_signature(), diff -r 7f0e0366ec81 -r 7d30d4f37d31 src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Thu Feb 27 10:36:50 2014 +0100 +++ b/src/share/vm/services/heapDumper.cpp Fri Feb 28 14:56:04 2014 +0100 @@ -1604,6 +1604,18 @@ } } } + StackValueCollection *exprs = jvf->expressions(); + for(int index = 0; index < exprs->size(); index++) { + if (exprs->at(index)->type() == T_OBJECT) { + oop o = exprs->obj_at(index)(); + if (o != NULL) { + writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME); + writer()->write_objectID(o); + writer()->write_u4(thread_serial_num); + writer()->write_u4((u4) (stack_depth + extra_frames)); + } + } + } } else { // native frame if (stack_depth == 0) { diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/TEST.groups --- a/test/TEST.groups Thu Feb 27 10:36:50 2014 +0100 +++ b/test/TEST.groups Fri Feb 28 14:56:04 2014 +0100 @@ -67,10 +67,8 @@ gc/metaspace/TestPerfCountersAndMemoryPools.java \ runtime/6819213/TestBootNativeLibraryPath.java \ runtime/6925573/SortMethodsTest.java \ - runtime/7107135/Test7107135.sh \ runtime/7158988/FieldMonitor.java \ runtime/7194254/Test7194254.java \ - runtime/jsig/Test8017498.sh \ runtime/Metaspace/FragmentMetaspace.java \ runtime/NMT/BaselineWithParameter.java \ runtime/NMT/JcmdScale.java \ @@ -175,7 +173,6 @@ gc/startup_warnings/TestParallelScavengeSerialOld.java \ gc/startup_warnings/TestParNewCMS.java \ gc/startup_warnings/TestParNewSerialOld.java \ - runtime/6929067/Test6929067.sh \ runtime/SharedArchiveFile/SharedArchiveFile.java # Minimal VM on Compact 2 adds in some compact2 tests diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/6925573/SortMethodsTest.java --- a/test/runtime/6925573/SortMethodsTest.java Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/6925573/SortMethodsTest.java Fri Feb 28 14:56:04 2014 +0100 @@ -47,6 +47,7 @@ import javax.tools.ToolProvider; /* + * @ignore 6959423 * @test SortMethodsTest * @bug 6925573 * @summary verify that class loading does not need quadratic time with regard to the number of class diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/6929067/Test6929067.sh --- a/test/runtime/6929067/Test6929067.sh Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/6929067/Test6929067.sh Fri Feb 28 14:56:04 2014 +0100 @@ -4,6 +4,7 @@ ## @test Test6929067.sh ## @bug 6929067 ## @bug 8021296 +## @bug 8025519 ## @summary Stack guard pages should be removed when thread is detached ## @run shell Test6929067.sh ## @@ -113,7 +114,7 @@ export LD_LIBRARY_PATH cp ${TESTSRC}${FS}*.java ${THIS_DIR} -${TESTJAVA}${FS}bin${FS}javac *.java +${COMPILEJAVA}${FS}bin${FS}javac *.java echo "Architecture: ${ARCH}" echo "Compilation flag: ${COMP_FLAG}" @@ -123,8 +124,8 @@ # for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. $gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - -L${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE} \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ ${TESTSRC}${FS}invoke.c -ljvm -lpthread ./invoke diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/7107135/Test7107135.sh --- a/test/runtime/7107135/Test7107135.sh Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/7107135/Test7107135.sh Fri Feb 28 14:56:04 2014 +0100 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011 SAP AG. All Rights Reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # @@ -25,9 +25,11 @@ # ## +## @ignore 8025519 ## @test Test7107135.sh ## @bug 7107135 ## @bug 8021296 +## @bug 8025519 ## @summary Stack guard pages lost after loading library with executable stack. ## @run shell Test7107135.sh ## @@ -63,10 +65,10 @@ THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} -${TESTJAVA}${FS}bin${FS}javac *.java +${COMPILEJAVA}${FS}bin${FS}javac *.java $gcc_cmd -fPIC -shared -c -o test.o \ - -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \ + -I${COMPILEJAVA}${FS}include -I${COMPILEJAVA}${FS}include${FS}linux \ ${TESTSRC}${FS}test.c ld -shared -z execstack -o libtest-rwx.so test.o diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/CompressedOops/CompressedClassPointers.java --- a/test/runtime/CompressedOops/CompressedClassPointers.java Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/CompressedOops/CompressedClassPointers.java Fri Feb 28 14:56:04 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -80,6 +80,18 @@ output.shouldHaveExitValue(0); } + public static void heapBaseMinAddressTest() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:HeapBaseMinAddress=1m", + "-XX:+PrintMiscellaneous", + "-XX:+Verbose", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("HeapBaseMinAddress must be at least"); + output.shouldContain("HotSpot"); + output.shouldHaveExitValue(0); + } + public static void sharingTest() throws Exception { // Test small heaps ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( @@ -113,24 +125,25 @@ } } - public static void main(String[] args) throws Exception { - if (!Platform.is64bit()) { - // Can't test this on 32 bit, just pass - System.out.println("Skipping test on 32bit"); - return; - } - // Solaris 10 can't mmap compressed oops space without a base - if (Platform.isSolaris()) { - String name = System.getProperty("os.version"); - if (name.equals("5.10")) { - System.out.println("Skipping test on Solaris 10"); - return; - } - } - smallHeapTest(); - smallHeapTestWith3G(); - largeHeapTest(); - largePagesTest(); - sharingTest(); - } + public static void main(String[] args) throws Exception { + if (!Platform.is64bit()) { + // Can't test this on 32 bit, just pass + System.out.println("Skipping test on 32bit"); + return; + } + // Solaris 10 can't mmap compressed oops space without a base + if (Platform.isSolaris()) { + String name = System.getProperty("os.version"); + if (name.equals("5.10")) { + System.out.println("Skipping test on Solaris 10"); + return; + } + } + smallHeapTest(); + smallHeapTestWith3G(); + largeHeapTest(); + largePagesTest(); + heapBaseMinAddressTest(); + sharingTest(); + } } diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java --- a/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Fri Feb 28 14:56:04 2014 +0100 @@ -22,6 +22,7 @@ */ /* + * @ignore 8025642 * @test CdsDifferentObjectAlignment * @summary Testing CDS (class data sharing) using varying object alignment. * Using different object alignment for each dump/load pair. @@ -29,6 +30,7 @@ * is different from object alignment for creating a CDS file * should fail when loading. * @library /testlibrary + * @bug 8025642 */ import com.oracle.java.testlibrary.*; diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/SharedArchiveFile/CdsWriteError.java --- a/test/runtime/SharedArchiveFile/CdsWriteError.java Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/SharedArchiveFile/CdsWriteError.java Fri Feb 28 14:56:04 2014 +0100 @@ -22,12 +22,14 @@ */ /* + * @ignore 8032222 * @test CdsWriteError * @summary Test how VM handles situation when it is impossible to write the * CDS archive. VM is expected to exit gracefully and display the * correct reason for the error. * @library /testlibrary * @run main CdsWriteError + * @bug 8032222 */ import com.oracle.java.testlibrary.*; diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/SharedArchiveFile/DefaultUseWithClient.java --- a/test/runtime/SharedArchiveFile/DefaultUseWithClient.java Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/SharedArchiveFile/DefaultUseWithClient.java Fri Feb 28 14:56:04 2014 +0100 @@ -22,10 +22,12 @@ */ /* + * @ignore 8032224 * @test DefaultUseWithClient * @summary Test default behavior of sharing with -client * @library /testlibrary * @run main DefaultUseWithClient + * @bug 8032224 */ import com.oracle.java.testlibrary.*; diff -r 7f0e0366ec81 -r 7d30d4f37d31 test/runtime/jsig/Test8017498.sh --- a/test/runtime/jsig/Test8017498.sh Thu Feb 27 10:36:50 2014 +0100 +++ b/test/runtime/jsig/Test8017498.sh Fri Feb 28 14:56:04 2014 +0100 @@ -30,8 +30,9 @@ ## @bug 8020791 ## @bug 8021296 ## @bug 8022301 +## @bug 8025519 ## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX -## @run shell/timeout=30 Test8017498.sh +## @run shell/timeout=60 Test8017498.sh ## if [ "${TESTSRC}" = "" ] @@ -55,12 +56,9 @@ echo "WARNING: gcc not found. Cannot execute test." 2>&1 exit 0; fi - if [ "$VM_BITS" = "64" ] - then - MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so - else - MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}i386${FS}libjsig.so - EXTRA_CFLAG=-m32 + MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}${VM_CPU}${FS}libjsig.so + if [ "$VM_BITS" == "32" ] && [ "$VM_CPU" != "arm" ] && [ "$VM_CPU" != "ppc" ]; then + EXTRA_CFLAG=-m32 fi echo MY_LD_PRELOAD = ${MY_LD_PRELOAD} ;; @@ -73,13 +71,13 @@ THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} -${TESTJAVA}${FS}bin${FS}javac *.java +${COMPILEJAVA}${FS}bin${FS}javac *.java $gcc_cmd -DLINUX -fPIC -shared \ ${EXTRA_CFLAG} -z noexecstack \ -o ${TESTSRC}${FS}libTestJNI.so \ - -I${TESTJAVA}${FS}include \ - -I${TESTJAVA}${FS}include${FS}linux \ + -I${COMPILEJAVA}${FS}include \ + -I${COMPILEJAVA}${FS}include${FS}linux \ ${TESTSRC}${FS}TestJNI.c # run the java test in the background