8179235: PackageEntryTables should be created eagerly
authorhseigel
Thu, 27 Apr 2017 10:08:02 -0400
changeset 46420 227f72691ac1
parent 46418 ddfa5bcf1d7a
child 46421 6365d86cf722
8179235: PackageEntryTables should be created eagerly Summary: Create the PackageEntryTables in the constructor for ClassLoaderData. Reviewed-by: dholmes, sspitsyn
hotspot/src/share/vm/classfile/classLoaderData.cpp
hotspot/src/share/vm/classfile/classLoaderData.hpp
hotspot/src/share/vm/classfile/packageEntry.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()) {
--- 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;