diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp index 9cafbd1..e24f8c9 100644 --- a/src/share/vm/prims/jvmtiEnv.cpp +++ b/src/share/vm/prims/jvmtiEnv.cpp @@ -298,10 +298,12 @@ //TODO: add locking if (AllowEnhancedClassRedefinition) { VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine); + MutexLocker sd_mutex(RedefineClasses_lock); VMThread::execute(&op); return (op.check_error()); } VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine); + MutexLocker sd_mutex(RedefineClasses_lock); VMThread::execute(&op); return (op.check_error()); } /* end RedefineClasses */ diff --git a/src/share/vm/runtime/mutexLocker.cpp b/src/share/vm/runtime/mutexLocker.cpp index f358c75..02377a4 100644 --- a/src/share/vm/runtime/mutexLocker.cpp +++ b/src/share/vm/runtime/mutexLocker.cpp @@ -38,6 +38,7 @@ // Consider using GCC's __read_mostly. Mutex* Patching_lock = NULL; +Mutex* RedefineClasses_lock = NULL; Monitor* SystemDictionary_lock = NULL; Mutex* PackageTable_lock = NULL; Mutex* CompiledIC_lock = NULL; @@ -279,6 +280,7 @@ def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread def(CompileThread_lock , Monitor, nonleaf+5, false ); def(PeriodicTask_lock , Monitor, nonleaf+5, true); + def(RedefineClasses_lock , Mutex , nonleaf+7, false ); // for ensuring that class redefinition is not done in parallel #ifdef INCLUDE_TRACE def(JfrMsg_lock , Monitor, leaf, true); diff --git a/src/share/vm/runtime/mutexLocker.hpp b/src/share/vm/runtime/mutexLocker.hpp index be86bac..a77f546 100644 --- a/src/share/vm/runtime/mutexLocker.hpp +++ b/src/share/vm/runtime/mutexLocker.hpp @@ -46,6 +46,7 @@ // Mutexes used in the VM. extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code +extern Mutex* RedefineClasses_lock; // a lock on class redefinition extern Monitor* SystemDictionary_lock; // a lock on the system dictonary extern Mutex* PackageTable_lock; // a lock on the class loader package table extern Mutex* CompiledIC_lock; // a lock used to guard compiled IC patching and access diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index 0dc86d9..9f4c2e9 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -910,6 +910,15 @@ return false; } +bool Thread::owns_locks_but_redefine_classes_lock() const { + for(Monitor *cur = _owned_locks; cur; cur = cur->next()) { + if (cur != RedefineClasses_lock && cur->rank() != Mutex::redefine_classes) { + return true; + } + } + return false; +} + #endif diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index 1117c87..77b716c 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -211,11 +211,14 @@ void enter_signal_handler() { _num_nested_signal++; } void leave_signal_handler() { _num_nested_signal--; } bool is_inside_signal_handler() const { return _num_nested_signal > 0; } + Mutex* redefine_classes_mutex() { return _redefine_classes_mutex; } private: // Debug tracing static void trace(const char* msg, const Thread* const thread) PRODUCT_RETURN; + Mutex* _redefine_classes_mutex; + // Active_handles points to a block of handles JNIHandleBlock* _active_handles; @@ -585,6 +588,7 @@ void print_owned_locks() const { print_owned_locks_on(tty); } Monitor* owned_locks() const { return _owned_locks; } bool owns_locks() const { return owned_locks() != NULL; } + bool owns_locks_but_redefine_classes_lock() const; bool owns_locks_but_compiled_lock() const; // Deadlock detection