# HG changeset patch # User coleenp # Date 1292001183 18000 # Node ID 7cf1a74771e8c92c7f44ac1634685d6808898cca # Parent a5610f0862fe5c66a89db4e3f843599d50a229a4 6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock Summary: Don't acquire methodData_lock while holding pending list lock Reviewed-by: kvn, never, ysr diff -r a5610f0862fe -r 7cf1a74771e8 src/share/vm/oops/instanceRefKlass.cpp --- a/src/share/vm/oops/instanceRefKlass.cpp Thu Dec 09 20:12:06 2010 -0500 +++ b/src/share/vm/oops/instanceRefKlass.cpp Fri Dec 10 12:13:03 2010 -0500 @@ -457,6 +457,11 @@ } } +bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) { + Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock()); + return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock); +} + void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) { // we may enter this with pending exception set PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument diff -r a5610f0862fe -r 7cf1a74771e8 src/share/vm/oops/instanceRefKlass.hpp --- a/src/share/vm/oops/instanceRefKlass.hpp Thu Dec 09 20:12:06 2010 -0500 +++ b/src/share/vm/oops/instanceRefKlass.hpp Fri Dec 10 12:13:03 2010 -0500 @@ -89,6 +89,7 @@ static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock); static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock); + static bool owns_pending_list_lock(JavaThread* thread); // Update non-static oop maps so 'referent', 'nextPending' and // 'discovered' will look like non-oops diff -r a5610f0862fe -r 7cf1a74771e8 src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Thu Dec 09 20:12:06 2010 -0500 +++ b/src/share/vm/oops/methodOop.cpp Fri Dec 10 12:13:03 2010 -0500 @@ -309,6 +309,12 @@ // Build a methodDataOop object to hold information about this method // collected in the interpreter. void methodOopDesc::build_interpreter_method_data(methodHandle method, TRAPS) { + // Do not profile method if current thread holds the pending list lock, + // which avoids deadlock for acquiring the MethodData_lock. + if (instanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) { + return; + } + // Grab a lock here to prevent multiple // methodDataOops from being created. MutexLocker ml(MethodData_lock, THREAD);