void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { if (cld->keep_alive()) { cld->oops_do(f, klass_closure, must_claim); } } }
void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) { CLDClosure* closure = cld->keep_alive() ? strong : weak; if (closure != NULL) { closure->do_cld(cld); } } }
// Move class loader data from main list to the unloaded list for unloading // and deallocation later. bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { ClassLoaderData* data = _head; ClassLoaderData* prev = NULL; bool seen_dead_loader = false; // mark metadata seen on the stack and code cache so we can delete // unneeded entries. bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); MetadataOnStackMark md_on_stack; while (data != NULL) { if (data->keep_alive() || data->is_alive(is_alive_closure)) { if (has_redefined_a_class) { 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 // in the ClassLoaderDataGraph. if (prev != NULL) { prev->set_next(data); } else { assert(dead == _head, "sanity check"); _head = data; } dead->set_next(_unloading); _unloading = dead; } if (seen_dead_loader) { post_class_unload_events(); } return seen_dead_loader; }