8179235: PackageEntryTables should be created eagerly
Summary: Create the PackageEntryTables in the constructor for ClassLoaderData.
Reviewed-by: dholmes, sspitsyn
--- 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()) {
--- 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); }
--- 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<Symbol*> *pkg_list) {
+ assert_lock_strong(Module_lock);
for (int i = 0; i < table_size(); i++) {
for (PackageEntry* entry = bucket(i);
entry != NULL;