--- old/src/share/vm/classfile/classLoaderData.cpp 2017-07-19 11:07:20.450964223 -0400 +++ new/src/share/vm/classfile/classLoaderData.cpp 2017-07-19 11:07:20.076759222 -0400 @@ -114,6 +114,12 @@ } else { _unnamed_module = NULL; } + + if (!is_anonymous) { + _dictionary = create_dictionary(); + } else { + _dictionary = NULL; + } TRACE_INIT_ID(this); } @@ -453,10 +459,12 @@ // Class iterator used by the compiler. It gets some number of classes at // a safepoint to decay invocation counters on the methods. class ClassLoaderDataGraphKlassIteratorStatic { - ClassLoaderData* _current_loader_data = NULL; - Klass* _current_class_entry = NULL; + ClassLoaderData* _current_loader_data; + Klass* _current_class_entry; public: + ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(NULL), _current_class_entry(NULL) {} + InstanceKlass* try_get_next_class() { assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); while (true) { @@ -612,34 +620,17 @@ return newsize; } -Dictionary* ClassLoaderData::dictionary_or_null() { - return load_ptr_acquire(&_dictionary); -} - -Dictionary* ClassLoaderData::dictionary() { +Dictionary* ClassLoaderData::create_dictionary() { assert(!is_anonymous(), "anonymous class loader data do not have a dictionary"); - // Lazily create the dictionary, in the same way of lazily creating modules. - // Lock-free access requires load_ptr_acquire. - Dictionary* dictionary = load_ptr_acquire(&_dictionary); - if (dictionary == NULL) { - MutexLocker m1(SystemDictionary_lock); - // Check if _dictionary got allocated while we were waiting for this lock. - if ((dictionary = _dictionary) == NULL) { - int size; - if (this == the_null_class_loader_data()) { - size = _boot_loader_dictionary_size; - } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { - size = 1; // there's only one class in relection class loader and no initiated classes - } else { - size = calculate_dictionary_size(PredictedLoadedClassCount); - } - dictionary = new Dictionary(this, size); - // Ensure _dictionary is stable, since it is examined without a lock. - // Don't need metaspace_lock since SystemDictionary_lock is held. - OrderAccess::release_store_ptr(&_dictionary, dictionary); - } + int size; + if (_the_null_class_loader_data == NULL) { + size = _boot_loader_dictionary_size; + } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { + size = 1; // there's only one class in relection class loader and no initiated classes + } else { + size = calculate_dictionary_size(PredictedLoadedClassCount); } - return dictionary; + return new Dictionary(this, size); } // Unloading support @@ -1109,21 +1100,24 @@ } #define FOR_ALL_DICTIONARY(X) for (ClassLoaderData* X = _head; X != NULL; X = X->next()) \ - if (X->dictionary_or_null() != NULL) + if (X->dictionary() != NULL) // Walk classes in the loaded class dictionaries in various forms. +// Only walks the classes defined in this class loader. void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*)) { FOR_ALL_DICTIONARY(cld) { cld->dictionary()->classes_do(f); } } +// Only walks the classes defined in this class loader. void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS) { FOR_ALL_DICTIONARY(cld) { cld->dictionary()->classes_do(f, CHECK); } } +// Walks all entries in the dictionary including entries initiated by this class loader. void ClassLoaderDataGraph::dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) { FOR_ALL_DICTIONARY(cld) { cld->dictionary()->all_entries_do(f); @@ -1245,17 +1239,19 @@ } if (seen_dead_loader) { - // Walk a Dictionary, ModuleEntry's reads, and a PackageEntry's exports - // lists to determine if there are modules on those lists that are now - // dead and should be removed. A module's life cycle is equivalent - // to its defining class loader's life cycle. Since a module is - // considered dead if its class loader is dead, these walks must - // occur after each class loader's aliveness is determined. data = _head; while (data != NULL) { - if (data->dictionary_or_null() != NULL) { + // Remove entries in the dictionary of live class loader that have + // initiated loading classes in a dead class loader. + if (data->dictionary() != NULL) { data->dictionary()->do_unloading(); } + // Walk a ModuleEntry's reads, and a PackageEntry's exports + // lists to determine if there are modules on those lists that are now + // dead and should be removed. A module's life cycle is equivalent + // to its defining class loader's life cycle. Since a module is + // considered dead if its class loader is dead, these walks must + // occur after each class loader's aliveness is determined. if (data->packages() != NULL) { data->packages()->purge_all_package_exports(); }