@@ -692,25 +692,27 @@ void VM_PopulateDumpSharedSpace::doit() {
692692 _map_info->header ()->set_class_location_config (cl_config);
693693}
694694
695- class CollectCLDClosure : public CLDClosure {
696- GrowableArray<ClassLoaderData*> _loaded_cld;
697- GrowableArray<OopHandle> _loaded_cld_handles; // keep the CLDs alive
698- Thread* _current_thread;
695+ class CollectClassesForLinking : public KlassClosure {
696+ GrowableArray<OopHandle> _mirrors;
697+
699698public:
700- CollectCLDClosure (Thread* thread) : _current_thread(thread) {}
701- ~CollectCLDClosure () {
702- for (int i = 0 ; i < _loaded_cld_handles.length (); i++) {
703- _loaded_cld_handles.at (i).release (Universe::vm_global ());
699+ ~CollectClassesForLinking () {
700+ for (int i = 0 ; i < _mirrors.length (); i++) {
701+ _mirrors.at (i).release (Universe::vm_global ());
704702 }
705703 }
704+
706705 void do_cld (ClassLoaderData* cld) {
707706 assert (cld->is_alive (), " must be" );
708- _loaded_cld.append (cld);
709- _loaded_cld_handles.append (OopHandle (Universe::vm_global (), cld->holder ()));
710707 }
711708
712- int nof_cld () const { return _loaded_cld.length (); }
713- ClassLoaderData* cld_at (int index) { return _loaded_cld.at (index); }
709+ void do_klass (Klass* k) {
710+ if (k->is_instance_klass ()) {
711+ _mirrors.append (OopHandle (Universe::vm_global (), k->java_mirror ()));
712+ }
713+ }
714+
715+ const GrowableArray<OopHandle>* mirrors () const { return &_mirrors; }
714716};
715717
716718// Check if we can eagerly link this class at dump time, so we can avoid the
@@ -751,28 +753,26 @@ void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) {
751753 LambdaFormInvokers::regenerate_holder_classes (CHECK);
752754 }
753755
754- // Collect all loaded ClassLoaderData.
755- CollectCLDClosure collect_cld (THREAD);
756- {
757- // ClassLoaderDataGraph::loaded_cld_do requires ClassLoaderDataGraph_lock.
758- // We cannot link the classes while holding this lock (or else we may run into deadlock).
759- // Therefore, we need to first collect all the CLDs, and then link their classes after
760- // releasing the lock.
761- MutexLocker lock (ClassLoaderDataGraph_lock);
762- ClassLoaderDataGraph::loaded_cld_do (&collect_cld);
763- }
764756
765757 while (true ) {
758+ CollectClassesForLinking collect_classes;
759+ {
760+ // ClassLoaderDataGraph::loaded_classes_do_keepalive() requires ClassLoaderDataGraph_lock.
761+ // We cannot link the classes while holding this lock (or else we may run into deadlock).
762+ // Therefore, we need to first collect all the classes, keeping them alive by
763+ // holding onto their java_mirrors in global OopHandles. We then link the classes after
764+ // releasing the lock.
765+ MutexLocker lock (ClassLoaderDataGraph_lock);
766+ ClassLoaderDataGraph::loaded_classes_do_keepalive (&collect_classes);
767+ }
768+
766769 bool has_linked = false ;
767- for (int i = 0 ; i < collect_cld.nof_cld (); i++) {
768- ClassLoaderData* cld = collect_cld.cld_at (i);
769- for (Klass* klass = cld->klasses (); klass != nullptr ; klass = klass->next_link ()) {
770- if (klass->is_instance_klass ()) {
771- InstanceKlass* ik = InstanceKlass::cast (klass);
772- if (may_be_eagerly_linked (ik)) {
773- has_linked |= link_class_for_cds (ik, CHECK);
774- }
775- }
770+ const GrowableArray<OopHandle>* mirrors = collect_classes.mirrors ();
771+ for (int i = 0 ; i < mirrors->length (); i++) {
772+ OopHandle mirror = mirrors->at (i);
773+ InstanceKlass* ik = InstanceKlass::cast (java_lang_Class::as_Klass (mirror.resolve ()));
774+ if (may_be_eagerly_linked (ik)) {
775+ has_linked |= link_class_for_cds (ik, CHECK);
776776 }
777777 }
778778
@@ -1532,7 +1532,7 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma
15321532 assert (base_address == nullptr ||
15331533 (address)archive_space_rs.base () == base_address, " Sanity" );
15341534 // Register archive space with NMT.
1535- MemTracker::record_virtual_memory_tag (archive_space_rs. base () , mtClassShared);
1535+ MemTracker::record_virtual_memory_tag (archive_space_rs, mtClassShared);
15361536 return archive_space_rs.base ();
15371537 }
15381538 return nullptr ;
@@ -1605,9 +1605,8 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma
16051605 release_reserved_spaces (total_space_rs, archive_space_rs, class_space_rs);
16061606 return nullptr ;
16071607 }
1608- // NMT: fix up the space tags
1609- MemTracker::record_virtual_memory_tag (archive_space_rs.base (), mtClassShared);
1610- MemTracker::record_virtual_memory_tag (class_space_rs.base (), mtClass);
1608+ MemTracker::record_virtual_memory_tag (archive_space_rs, mtClassShared);
1609+ MemTracker::record_virtual_memory_tag (class_space_rs, mtClass);
16111610 } else {
16121611 if (use_archive_base_addr && base_address != nullptr ) {
16131612 total_space_rs = MemoryReserver::reserve ((char *) base_address,
0 commit comments