# HG changeset patch # User kamg # Date 1294758360 18000 # Node ID db2b0f8c1cef7c326c8acaffb88509e5f54f1cf9 # Parent 7246a374a9f2edc3a9730d28ac59e26f5a14a542 6814943: getcpool001 catches more than one JvmtiThreadState problem Summary: Mark field volatile, use membars, and change access order to close race Reviewed-by: dcubed, dholmes diff -r 7246a374a9f2 -r db2b0f8c1cef src/share/vm/prims/jvmtiEventController.cpp --- a/src/share/vm/prims/jvmtiEventController.cpp Mon Jan 10 17:14:53 2011 -0500 +++ b/src/share/vm/prims/jvmtiEventController.cpp Tue Jan 11 10:06:00 2011 -0500 @@ -667,14 +667,13 @@ JvmtiEventControllerPrivate::thread_ended(JavaThread *thread) { // Removes the JvmtiThreadState associated with the specified thread. // May be called after all environments have been disposed. + assert(JvmtiThreadState_lock->is_locked(), "sanity check"); EC_TRACE(("JVMTI [%s] # thread ended", JvmtiTrace::safe_get_thread_name(thread))); JvmtiThreadState *state = thread->jvmti_thread_state(); - if (state != NULL) { - MutexLocker mu(JvmtiThreadState_lock); - delete state; - } + assert(state != NULL, "else why are we here?"); + delete state; } void JvmtiEventControllerPrivate::set_event_callbacks(JvmtiEnvBase *env, diff -r 7246a374a9f2 -r db2b0f8c1cef src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Mon Jan 10 17:14:53 2011 -0500 +++ b/src/share/vm/prims/jvmtiExport.cpp Tue Jan 11 10:06:00 2011 -0500 @@ -2253,12 +2253,14 @@ void JvmtiExport::cleanup_thread(JavaThread* thread) { assert(JavaThread::current() == thread, "thread is not current"); - + MutexLocker mu(JvmtiThreadState_lock); - // This has to happen after the thread state is removed, which is - // why it is not in post_thread_end_event like its complement - // Maybe both these functions should be rolled into the posts? - JvmtiEventController::thread_ended(thread); + if (thread->jvmti_thread_state() != NULL) { + // This has to happen after the thread state is removed, which is + // why it is not in post_thread_end_event like its complement + // Maybe both these functions should be rolled into the posts? + JvmtiEventController::thread_ended(thread); + } } void JvmtiExport::oops_do(OopClosure* f) { diff -r 7246a374a9f2 -r db2b0f8c1cef src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Mon Jan 10 17:14:53 2011 -0500 +++ b/src/share/vm/runtime/thread.cpp Tue Jan 11 10:06:00 2011 -0500 @@ -31,6 +31,7 @@ #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/linkResolver.hpp" +#include "jvmtifiles/jvmtiEnv.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" @@ -1699,7 +1700,7 @@ tlab().make_parsable(true); // retire TLAB } - if (jvmti_thread_state() != NULL) { + if (JvmtiEnv::environments_might_exist()) { JvmtiExport::cleanup_thread(this); } diff -r 7246a374a9f2 -r db2b0f8c1cef src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Mon Jan 10 17:14:53 2011 -0500 +++ b/src/share/vm/runtime/thread.hpp Tue Jan 11 10:06:00 2011 -0500 @@ -809,7 +809,7 @@ // // _vm_exited is a special value to cover the case of a JavaThread // executing native code after the VM itself is terminated. - TerminatedTypes _terminated; + volatile TerminatedTypes _terminated; // suspend/resume support volatile bool _suspend_equivalent; // Suspend equivalent condition jint _in_deopt_handler; // count of deoptimization