8166364: fatal error: acquiring lock DirtyCardQ_CBL_mon/16 out of order with lock Module_lock/6 -- possible deadlock
Set the mirror's module field outside of the module lock. Reviewed-by: dsamersoff, dholmes, rehn
This commit is contained in:
parent
b7b3fb4266
commit
63e0cc39e9
@ -780,19 +780,26 @@ void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Hand
|
|||||||
// Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
|
// Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
|
||||||
// for java.base is known.
|
// for java.base is known.
|
||||||
assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
|
assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
|
||||||
MutexLocker m1(Module_lock, THREAD);
|
|
||||||
// Keep list of classes needing java.base module fixup
|
bool javabase_was_defined = false;
|
||||||
if (!ModuleEntryTable::javabase_defined()) {
|
{
|
||||||
if (fixup_module_field_list() == NULL) {
|
MutexLocker m1(Module_lock, THREAD);
|
||||||
GrowableArray<Klass*>* list =
|
// Keep list of classes needing java.base module fixup
|
||||||
new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
|
if (!ModuleEntryTable::javabase_defined()) {
|
||||||
set_fixup_module_field_list(list);
|
if (fixup_module_field_list() == NULL) {
|
||||||
|
GrowableArray<Klass*>* list =
|
||||||
|
new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
|
||||||
|
set_fixup_module_field_list(list);
|
||||||
|
}
|
||||||
|
k->class_loader_data()->inc_keep_alive();
|
||||||
|
fixup_module_field_list()->push(k());
|
||||||
|
} else {
|
||||||
|
javabase_was_defined = true;
|
||||||
}
|
}
|
||||||
k->class_loader_data()->inc_keep_alive();
|
}
|
||||||
fixup_module_field_list()->push(k());
|
|
||||||
} else {
|
// If java.base was already defined then patch this particular class with java.base.
|
||||||
// java.base was defined at some point between calling create_mirror()
|
if (javabase_was_defined) {
|
||||||
// and obtaining the Module_lock, patch this particular class with java.base.
|
|
||||||
ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
|
ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
|
||||||
assert(javabase_entry != NULL && javabase_entry->module() != NULL,
|
assert(javabase_entry != NULL && javabase_entry->module() != NULL,
|
||||||
"Setting class module field, java.base should be defined");
|
"Setting class module field, java.base should be defined");
|
||||||
|
@ -368,9 +368,6 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version,
|
|||||||
|
|
||||||
// Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
|
// Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
|
||||||
java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
|
java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
|
||||||
|
|
||||||
// Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module.
|
|
||||||
patch_javabase_entries(module_handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Within java.lang.Class instances there is a java.lang.reflect.Module field
|
// Within java.lang.Class instances there is a java.lang.reflect.Module field
|
||||||
@ -378,7 +375,6 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version,
|
|||||||
// definition, classes needing their module field set are added to the fixup_module_list.
|
// definition, classes needing their module field set are added to the fixup_module_list.
|
||||||
// Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
|
// Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
|
||||||
void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
|
void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
|
||||||
assert(Module_lock->owned_by_self(), "should have the Module_lock");
|
|
||||||
if (module_handle.is_null()) {
|
if (module_handle.is_null()) {
|
||||||
fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
|
fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,12 @@ static void define_javabase_module(jobject module, jstring version,
|
|||||||
"Module java.base is already defined");
|
"Module java.base is already defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only the thread that actually defined the base module will get here,
|
||||||
|
// so no locking is needed.
|
||||||
|
|
||||||
|
// Patch any previously loaded class's module field with java.base's java.lang.reflect.Module.
|
||||||
|
ModuleEntryTable::patch_javabase_entries(module_handle);
|
||||||
|
|
||||||
log_debug(modules)("define_javabase_module(): Definition of module: java.base,"
|
log_debug(modules)("define_javabase_module(): Definition of module: java.base,"
|
||||||
" version: %s, location: %s, package #: %d",
|
" version: %s, location: %s, package #: %d",
|
||||||
module_version != NULL ? module_version : "NULL",
|
module_version != NULL ? module_version : "NULL",
|
||||||
|
Loading…
Reference in New Issue
Block a user