< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page

        

*** 54,63 **** --- 54,64 ---- #include "classfile/metadataOnStackMark.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" + #include "gc/shared/oopStorage.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceShared.hpp"
*** 508,517 **** --- 509,524 ---- InstanceKlass* ClassLoaderDataGraph::try_get_next_class() { return static_klass_iterator.try_get_next_class(); } + void ClassLoaderData::update_holder(Handle holder) { + assert(holder() != NULL, "should be called with non-NULL loader"); + assert(_holder.peek() == NULL, "never replace holders"); + _holder = WeakHandle::create(holder); + } + // 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");
*** 615,642 **** // A klass that was previously considered dead can be looked up in the // CLD/SD, and its _java_mirror or _class_loader can be stored in a root // or a reachable object making it alive again. The SATB part of G1 needs // to get notified about this potential resurrection, otherwise the marking // might not find the object. ! if (!keep_alive()) { ! oop* o = is_anonymous() ? _klasses->java_mirror_handle().ptr_raw() : &_class_loader; ! return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(o); ! } else { ! return NULL; ! } } // 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(); ! } ! ! bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const { bool alive = keep_alive() // null class loader and incomplete anonymous klasses. ! || is_alive_closure->do_object_b(keep_alive_object()); return alive; } class ReleaseKlassClosure: public KlassClosure { --- 622,639 ---- // A klass that was previously considered dead can be looked up in the // CLD/SD, and its _java_mirror or _class_loader can be stored in a root // or a reachable object making it alive again. The SATB part of G1 needs // to get notified about this potential resurrection, otherwise the marking // might not find the object. ! return _holder.resolve(); } // Unloading support ! bool ClassLoaderData::is_alive() const { bool alive = keep_alive() // null class loader and incomplete anonymous klasses. ! || _holder.is_null() ! || (_holder.peek() != NULL); // not cleaned by weak reference processing return alive; } class ReleaseKlassClosure: public KlassClosure {
*** 666,675 **** --- 663,677 ---- classes_do(&cl); ClassLoaderDataGraph::dec_array_classes(cl.array_class_released()); ClassLoaderDataGraph::dec_instance_classes(cl.instance_class_released()); + // Release the WeakHandle, if already set + if (!_holder.is_null()) { + _holder.release(); + } + // Release C heap allocated hashtable for all the packages. if (_packages != NULL) { // Destroy the table itself delete _packages; _packages = NULL;
*** 967,987 **** // ClassLoaderData in the graph since the CLD // contains unhandled oops ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); - if (!is_anonymous) { // First, Atomically set it ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL); if (old != NULL) { delete cld; // Returns the data. return old; } } // We won the race, and therefore the task of adding the data to the list of // class loader data ClassLoaderData** list_head = &_head; ClassLoaderData* next = _head; --- 969,993 ---- // ClassLoaderData in the graph since the CLD // contains unhandled oops ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); if (!is_anonymous) { // First, Atomically set it ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL); if (old != NULL) { delete cld; // Returns the data. return old; } + + // Update the holder if we've won the race + // The holder of this class is the class_loader generically. + cld->update_holder(loader); } + // We won the race, and therefore the task of adding the data to the list of // class loader data ClassLoaderData** list_head = &_head; ClassLoaderData* next = _head;
*** 1242,1251 **** --- 1248,1259 ---- bool clean_previous_versions) { ClassLoaderData* data = _head; ClassLoaderData* prev = NULL; bool seen_dead_loader = false; + int loaders_processed = 0; + int loaders_removed = 0; // Mark metadata seen on the stack only so we can delete unneeded entries. // Only walk all metadata, including the expensive code cache walk, for Full GC // and only if class redefinition and if there's previous versions of // Klasses to delete.
*** 1258,1278 **** // purging and we don't want to rewalk the previously unloaded class loader data. _saved_unloading = _unloading; data = _head; while (data != NULL) { ! if (data->is_alive(is_alive_closure)) { // clean metaspace if (walk_all_metadata) { data->classes_do(InstanceKlass::purge_previous_versions); } data->free_deallocate_list(); prev = data; data = data->next(); continue; } seen_dead_loader = true; ClassLoaderData* dead = data; dead->unload(); data = data->next(); // Remove from loader list. // This class loader data will no longer be found --- 1266,1288 ---- // purging and we don't want to rewalk the previously unloaded class loader data. _saved_unloading = _unloading; data = _head; while (data != NULL) { ! if (data->is_alive()) { // clean metaspace if (walk_all_metadata) { data->classes_do(InstanceKlass::purge_previous_versions); } data->free_deallocate_list(); prev = data; data = data->next(); + loaders_processed++; continue; } seen_dead_loader = true; + loaders_removed++; ClassLoaderData* dead = data; dead->unload(); data = data->next(); // Remove from loader list. // This class loader data will no longer be found
*** 1311,1320 **** --- 1321,1332 ---- } post_class_unload_events(); } + log_debug(class, loader, data)("do_unloading: loaders processed %d, loaders removed %d", loaders_processed, loaders_removed); + return seen_dead_loader; } void ClassLoaderDataGraph::purge() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
< prev index next >