# HG changeset patch # User hseigel # Date 1493302082 14400 # Node ID 227f72691ac1e83e20fadf2b7bc0662418d2a662 # Parent ddfa5bcf1d7acfc79fd24ff41852f55a0a5cc2aa 8179235: PackageEntryTables should be created eagerly Summary: Create the PackageEntryTables in the constructor for ClassLoaderData. Reviewed-by: dholmes, sspitsyn diff -r ddfa5bcf1d7a -r 227f72691ac1 hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Apr 26 21:28:22 2017 -0700 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Apr 27 10:08:02 2017 -0400 @@ -102,6 +102,7 @@ // ModuleEntryTable or PackageEntryTable created for it. The defining package // and module for an anonymous class will be found in its host class. if (!is_anonymous) { + _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); if (h_class_loader.is_null()) { // Create unnamed module for boot loader _unnamed_module = ModuleEntry::create_boot_unnamed_module(this); @@ -297,8 +298,8 @@ if (_modules != NULL) { for (int i = 0; i < _modules->table_size(); i++) { for (ModuleEntry* entry = _modules->bucket(i); - entry != NULL; - entry = entry->next()) { + entry != NULL; + entry = entry->next()) { f(entry); } } @@ -306,13 +307,12 @@ } void ClassLoaderData::packages_do(void f(PackageEntry*)) { - // Lock-free access requires load_ptr_acquire - PackageEntryTable* packages = load_ptr_acquire(&_packages); - if (packages != NULL) { - for (int i = 0; i < packages->table_size(); i++) { - for (PackageEntry* entry = packages->bucket(i); - entry != NULL; - entry = entry->next()) { + assert_locked_or_safepoint(Module_lock); + if (_packages != NULL) { + for (int i = 0; i < _packages->table_size(); i++) { + for (PackageEntry* entry = _packages->bucket(i); + entry != NULL; + entry = entry->next()) { f(entry); } } @@ -494,22 +494,6 @@ free_deallocate_list(); } -PackageEntryTable* ClassLoaderData::packages() { - // Lazily create the package entry table at first request. - // Lock-free access requires load_ptr_acquire. - PackageEntryTable* packages = load_ptr_acquire(&_packages); - if (packages == NULL) { - MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag); - // Check if _packages got allocated while we were waiting for this lock. - if ((packages = _packages) == NULL) { - packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); - // Ensure _packages is stable, since it is examined without a lock - OrderAccess::release_store_ptr(&_packages, packages); - } - } - return packages; -} - ModuleEntryTable* ClassLoaderData::modules() { // Lazily create the module entry table at first request. // Lock-free access requires load_ptr_acquire. @@ -1096,7 +1080,7 @@ // occur after each class loader's aliveness is determined. data = _head; while (data != NULL) { - if (data->packages_defined()) { + if (data->packages() != NULL) { data->packages()->purge_all_package_exports(); } if (data->modules_defined()) { diff -r ddfa5bcf1d7a -r 227f72691ac1 hotspot/src/share/vm/classfile/classLoaderData.hpp --- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Apr 26 21:28:22 2017 -0700 +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Apr 27 10:08:02 2017 -0400 @@ -347,8 +347,7 @@ bool contains_klass(Klass* k); void record_dependency(const Klass* to, TRAPS); void init_dependencies(TRAPS); - PackageEntryTable* packages(); - bool packages_defined() { return (_packages != NULL); } + PackageEntryTable* packages() { return _packages; } ModuleEntry* unnamed_module() { return _unnamed_module; } ModuleEntryTable* modules(); bool modules_defined() { return (_modules != NULL); } diff -r ddfa5bcf1d7a -r 227f72691ac1 hotspot/src/share/vm/classfile/packageEntry.cpp --- a/hotspot/src/share/vm/classfile/packageEntry.cpp Wed Apr 26 21:28:22 2017 -0700 +++ b/hotspot/src/share/vm/classfile/packageEntry.cpp Thu Apr 27 10:08:02 2017 -0400 @@ -174,8 +174,6 @@ } PackageEntryTable::~PackageEntryTable() { - assert_locked_or_safepoint(Module_lock); - // Walk through all buckets and all entries in each bucket, // freeing each entry. for (int i = 0; i < table_size(); ++i) { @@ -271,6 +269,7 @@ // Called when a define module for java.base is being processed. // Verify the packages loaded thus far are in java.base's package list. void PackageEntryTable::verify_javabase_packages(GrowableArray *pkg_list) { + assert_lock_strong(Module_lock); for (int i = 0; i < table_size(); i++) { for (PackageEntry* entry = bucket(i); entry != NULL;