--- old/src/share/vm/classfile/moduleEntry.cpp 2017-04-14 10:29:08.684144951 -0400 +++ new/src/share/vm/classfile/moduleEntry.cpp 2017-04-14 10:29:07.596144906 -0400 @@ -129,6 +129,11 @@ // Add a new module to this module's reads list void ModuleEntry::add_read(ModuleEntry* m) { + // Unnamed module is special cased and can read all modules + if (!is_named()) { + return; + } + MutexLocker m1(Module_lock); if (m == NULL) { set_can_read_all_unnamed(); @@ -153,6 +158,7 @@ // safepoint. Modules have the same life cycle as their defining class // loaders and should be removed if dead. void ModuleEntry::set_read_walk_required(ClassLoaderData* m_loader_data) { + assert(is_named(), "Cannot call set_read_walk_required on unnamed module"); assert_locked_or_safepoint(Module_lock); if (!_must_walk_reads && loader_data() != m_loader_data && @@ -166,6 +172,8 @@ } } +// Returns true if the module has a non-empty reads list. As such, the unnamed +// module will return false. bool ModuleEntry::has_reads() const { assert_locked_or_safepoint(Module_lock); return ((_reads != NULL) && !_reads->is_empty()); @@ -219,8 +227,58 @@ _reads = NULL; } +ModuleEntry* ModuleEntry::create_unnamed_module(ClassLoaderData* cld) { + // The java.lang.Module for this loader's + // corresponding unnamed module can be found in the java.lang.ClassLoader object. + oop module = java_lang_ClassLoader::unnamedModule(cld->class_loader()); + ModuleEntry* unnamed_module = new_unnamed_module_entry(Handle(Thread::current(), module), cld); + + // Store pointer to the ModuleEntry in the unnamed module's java.lang.Module + // object. + java_lang_reflect_Module::set_module_entry(module, unnamed_module); + + return unnamed_module; +} + +ModuleEntry* ModuleEntry::create_boot_unnamed_module(ClassLoaderData* cld) { + // For the boot loader, the java.lang.Module for the unnamed module + // is not known until a call to JVM_SetBootLoaderUnnamedModule is made. At + // this point initially create the ModuleEntry for the unnamed module. + ModuleEntry* unnamed_module = new_unnamed_module_entry(Handle(), cld); + assert(unnamed_module != NULL, "boot loader unnamed module should not be null"); + return unnamed_module; +} + +// When creating an unnamed module, this is called without holding the Module_lock. +// This is okay because the unnamed module gets created before the ClassLoaderData +// is available to other threads. +ModuleEntry* ModuleEntry::new_unnamed_module_entry(Handle module_handle, ClassLoaderData* cld) { + ModuleEntry* entry = (ModuleEntry*) NEW_C_HEAP_ARRAY(char, sizeof(ModuleEntry), mtModule); + + // Initialize everything BasicHashtable would + entry->set_next(NULL); + entry->set_hash(0); + entry->set_literal(NULL); + + // Initialize fields specific to a ModuleEntry + entry->init(); + + // Unnamed modules can read all other unnamed modules. + entry->set_can_read_all_unnamed(); + + if (!module_handle.is_null()) { + entry->set_module(cld->add_handle(module_handle)); + } + + entry->set_loader_data(cld); + + TRACE_INIT_ID(entry); + + return entry; +} + ModuleEntryTable::ModuleEntryTable(int table_size) - : Hashtable(table_size, sizeof(ModuleEntry)), _unnamed_module(NULL) + : Hashtable(table_size, sizeof(ModuleEntry)) { } @@ -261,30 +319,6 @@ free_buckets(); } -void ModuleEntryTable::create_unnamed_module(ClassLoaderData* loader_data) { - assert(Module_lock->owned_by_self(), "should have the Module_lock"); - - // Each ModuleEntryTable has exactly one unnamed module - if (loader_data->is_the_null_class_loader_data()) { - // For the boot loader, the java.lang.reflect.Module for the unnamed module - // is not known until a call to JVM_SetBootLoaderUnnamedModule is made. At - // this point initially create the ModuleEntry for the unnamed module. - _unnamed_module = new_entry(0, Handle(), NULL, NULL, NULL, loader_data); - } else { - // For all other class loaders the java.lang.reflect.Module for their - // corresponding unnamed module can be found in the java.lang.ClassLoader object. - oop module = java_lang_ClassLoader::unnamedModule(loader_data->class_loader()); - _unnamed_module = new_entry(0, Handle(Thread::current(), module), NULL, NULL, NULL, loader_data); - - // Store pointer to the ModuleEntry in the unnamed module's java.lang.reflect.Module - // object. - java_lang_reflect_Module::set_module_entry(module, _unnamed_module); - } - - // Add to bucket 0, no name to hash on - add_entry(0, _unnamed_module); -} - ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle, Symbol* name, Symbol* version, Symbol* location, ClassLoaderData* loader_data) { @@ -351,10 +385,7 @@ // lookup_only by Symbol* to find a ModuleEntry. ModuleEntry* ModuleEntryTable::lookup_only(Symbol* name) { - if (name == NULL) { - // Return this table's unnamed module - return unnamed_module(); - } + assert(name != NULL, "name cannot be NULL"); int index = index_for(name); for (ModuleEntry* m = bucket(index); m != NULL; m = m->next()) { if (m->name()->fast_compare(name) == 0) {