--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 05 23:44:18 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jun 22 00:51:07 2017 +0200
@@ -97,6 +97,22 @@
_next(NULL), _dependencies(dependencies),
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
Monitor::_safepoint_check_never)) {
+
+ // A ClassLoaderData created solely for an anonymous class should never have a
+ // 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);
+ } else {
+ // Create unnamed module for all other loaders
+ _unnamed_module = ModuleEntry::create_unnamed_module(this);
+ }
+ } else {
+ _unnamed_module = NULL;
+ }
TRACE_INIT_ID(this);
}
@@ -247,16 +263,15 @@
void ClassLoaderData::methods_do(void f(Method*)) {
// Lock-free access requires load_ptr_acquire
for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
- if (k->is_instance_klass()) {
+ if (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded()) {
InstanceKlass::cast(k)->methods_do(f);
}
}
}
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
- // Lock to avoid classes being modified/added/removed during iteration
- MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
- for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
+ // Lock-free access requires load_ptr_acquire
+ for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
// Do not filter ArrayKlass oops here...
if (k->is_array_klass() || (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded())) {
klass_closure->do_klass(k);
@@ -276,11 +291,14 @@
void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
assert_locked_or_safepoint(Module_lock);
+ if (_unnamed_module != NULL) {
+ f(_unnamed_module);
+ }
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);
}
}
@@ -288,13 +306,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);
}
}
@@ -476,22 +493,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.
@@ -501,10 +502,6 @@
// Check if _modules got allocated while we were waiting for this lock.
if ((modules = _modules) == NULL) {
modules = new ModuleEntryTable(ModuleEntryTable::_moduletable_entry_size);
- // Each loader has one unnamed module entry. Create it before
- // any classes, loaded by this loader, are defined in case
- // they end up being defined in loader's unnamed module.
- modules->create_unnamed_module(this);
{
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
@@ -529,7 +526,6 @@
return alive;
}
-
ClassLoaderData::~ClassLoaderData() {
// Release C heap structures for all the classes.
classes_do(InstanceKlass::release_C_heap_structures);
@@ -548,6 +544,11 @@
_modules = NULL;
}
+ if (_unnamed_module != NULL) {
+ _unnamed_module->delete_unnamed_module();
+ _unnamed_module = NULL;
+ }
+
// release the metaspace
Metaspace *m = _metaspace;
if (m != NULL) {
@@ -586,10 +587,9 @@
// (boot, application/system or platform) class loaders. Note, the
// builtin loaders are not freed by a GC.
bool ClassLoaderData::is_builtin_class_loader_data() const {
- Handle classLoaderHandle = class_loader();
return (is_the_null_class_loader_data() ||
- SystemDictionary::is_system_class_loader(classLoaderHandle) ||
- SystemDictionary::is_platform_class_loader(classLoaderHandle));
+ SystemDictionary::is_system_class_loader(class_loader()) ||
+ SystemDictionary::is_platform_class_loader(class_loader()));
}
Metaspace* ClassLoaderData::metaspace_non_null() {
@@ -686,7 +686,8 @@
// These anonymous class loaders are to contain classes used for JSR292
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
// Add a new class loader data to the graph.
- return ClassLoaderDataGraph::add(loader, true, THREAD);
+ Handle lh(THREAD, loader);
+ return ClassLoaderDataGraph::add(lh, true, THREAD);
}
const char* ClassLoaderData::loader_name() {
@@ -818,7 +819,7 @@
// Include the result of loader.toString() in the output. This allows
// the user of the log to identify the class loader instance.
JavaValue result(T_OBJECT);
- KlassHandle spec_klass(THREAD, SystemDictionary::ClassLoader_klass());
+ Klass* spec_klass = SystemDictionary::ClassLoader_klass();
JavaCalls::call_virtual(&result,
loader,
spec_klass,
@@ -826,7 +827,7 @@
vmSymbols::void_string_signature(),
CHECK);
assert(result.get_type() == T_OBJECT, "just checking");
- string = (oop)result.get_jobject();
+ string = Handle(THREAD, (oop)result.get_jobject());
}
ResourceMark rm;
@@ -1078,7 +1079,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()) {