< prev index next >

src/share/vm/classfile/classLoaderData.cpp

Print this page

        

*** 47,56 **** --- 47,57 ---- // the singleton class the_null_class_loader_data(). #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderData.inline.hpp" + #include "classfile/dictionary.hpp" #include "classfile/javaClasses.hpp" #include "classfile/metadataOnStackMark.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "classfile/systemDictionary.hpp"
*** 111,120 **** --- 112,127 ---- _unnamed_module = ModuleEntry::create_unnamed_module(this); } } else { _unnamed_module = NULL; } + + if (!is_anonymous) { + _dictionary = create_dictionary(); + } else { + _dictionary = NULL; + } TRACE_INIT_ID(this); } void ClassLoaderData::init_dependencies(TRAPS) { assert(!Universe::is_fully_initialized(), "should only be called when initializing");
*** 447,460 **** --- 454,536 ---- p2i((void *)k->class_loader()), loader_name()); } } + // 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; + 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) { + + if (_current_class_entry != NULL) { + Klass* k = _current_class_entry; + _current_class_entry = _current_class_entry->next_link(); + + if (k->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(k); + // Only return loaded classes + if (ik->is_loaded()) { + return ik; + } + } + } else { + // Go to next CLD + if (_current_loader_data != NULL) { + _current_loader_data = _current_loader_data->next(); + } + // Start at the beginning + if (_current_loader_data == NULL) { + _current_loader_data = ClassLoaderDataGraph::_head; + } + + _current_class_entry = _current_loader_data->klasses(); + } + } + // never reached: an InstanceKlass should be returned above + } + + // If the current class for the static iterator is a class being unloaded or + // deallocated, adjust the current class. + void adjust_saved_class(ClassLoaderData* cld) { + if (_current_loader_data == cld) { + _current_loader_data = cld->next(); + if (_current_loader_data != NULL) { + _current_class_entry = _current_loader_data->klasses(); + } // else try_get_next_class will start at the head + } + } + + void adjust_saved_class(Klass* klass) { + if (_current_class_entry == klass) { + _current_class_entry = klass->next_link(); + } + } + }; + + static ClassLoaderDataGraphKlassIteratorStatic static_klass_iterator; + + InstanceKlass* ClassLoaderDataGraph::try_get_next_class() { + return static_klass_iterator.try_get_next_class(); + } + + // Remove a klass from the _klasses list for scratch_class during redefinition // or parsed class in the case of an error. void ClassLoaderData::remove_class(Klass* scratch_class) { assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); + + // Adjust global class iterator. + static_klass_iterator.adjust_saved_class(scratch_class); + Klass* prev = NULL; for (Klass* k = _klasses; k != NULL; k = k->next_link()) { if (k == scratch_class) { if (prev == NULL) { _klasses = k->next_link();
*** 489,498 **** --- 565,577 ---- } // In some rare cases items added to this list will not be freed elsewhere. // To keep it simple, just free everything in it here. free_deallocate_list(); + + // Clean up global class iterator for compiler + static_klass_iterator.adjust_saved_class(this); } ModuleEntryTable* ClassLoaderData::modules() { // Lazily create the module entry table at first request. // Lock-free access requires load_ptr_acquire.
*** 511,520 **** --- 590,641 ---- } } return modules; } + const int _boot_loader_dictionary_size = 1009; + const int _prime_array_size = 8; // array of primes for system dictionary size + const int _average_depth_goal = 3; // goal for lookup length + const int _primelist[_prime_array_size] = {107, 1009, 2017, 4049, 5051, 10103, 20201, 40423}; + + // Calculate a "good" dictionary size based + // on predicted or current loaded classes count *per class loader* + // This size will be used for all class loaders if specified, + // except boot loader and reflection class loaders + static int calculate_dictionary_size(int classcount) { + static int newsize = 0; // only calculate once + if (newsize != 0) { + return newsize; + } + newsize = _primelist[0]; + if (classcount > 0 && !DumpSharedSpaces) { + int index = 0; + int desiredsize = classcount/_average_depth_goal; + for (newsize = _primelist[index]; index < _prime_array_size -1; + newsize = _primelist[++index]) { + if (desiredsize <= newsize) { + break; + } + } + } + return newsize; + } + + Dictionary* ClassLoaderData::create_dictionary() { + assert(!is_anonymous(), "anonymous class loader data do not have a 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 new Dictionary(this, size); + } + + // Unloading support oop ClassLoaderData::keep_alive_object() const { assert_locked_or_safepoint(_metaspace_lock); assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); return is_anonymous() ? _klasses->java_mirror() : class_loader(); }
*** 542,551 **** --- 663,679 ---- // Destroy the table itself delete _modules; _modules = NULL; } + // Release C heap allocated hashtable for the dictionary + if (_dictionary != NULL) { + // Destroy the table itself + delete _dictionary; + _dictionary = NULL; + } + if (_unnamed_module != NULL) { _unnamed_module->delete_unnamed_module(); _unnamed_module = NULL; }
*** 969,978 **** --- 1097,1146 ---- assert(cld->is_unloading(), "invariant"); cld->classes_do(f); } } + #define FOR_ALL_DICTIONARY(X) for (ClassLoaderData* X = _head; X != NULL; X = X->next()) \ + 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); + } + } + + void ClassLoaderDataGraph::verify_dictionary() { + FOR_ALL_DICTIONARY(cld) { + cld->dictionary()->verify(); + } + } + + void ClassLoaderDataGraph::print_dictionary(bool details) { + FOR_ALL_DICTIONARY(cld) { + tty->print("Dictionary for class loader "); + cld->print_value(); + tty->cr(); + cld->dictionary()->print(details); + } + } + GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() { assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?"); GrowableArray<ClassLoaderData*>* array = new GrowableArray<ClassLoaderData*>();
*** 1069,1086 **** dead->set_next(_unloading); _unloading = dead; } if (seen_dead_loader) { ! // 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. - data = _head; - while (data != NULL) { if (data->packages() != NULL) { data->packages()->purge_all_package_exports(); } if (data->modules_defined()) { data->modules()->purge_all_module_reads(); --- 1237,1259 ---- dead->set_next(_unloading); _unloading = dead; } if (seen_dead_loader) { ! data = _head; ! while (data != 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(); } if (data->modules_defined()) { data->modules()->purge_all_module_reads();
*** 1248,1257 **** --- 1421,1439 ---- out->print("class loader " INTPTR_FORMAT " ", p2i(this)); class_loader()->print_value_on(out); } } + void ClassLoaderData::print_on(outputStream* out) const { + if (class_loader() == NULL) { + out->print("NULL class_loader"); + } else { + out->print("class loader " INTPTR_FORMAT " ", p2i(this)); + class_loader()->print_on(out); + } + } + #if INCLUDE_TRACE Ticks ClassLoaderDataGraph::_class_unload_time; void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
< prev index next >