Skip to content

Commit a83760a

Browse files
committedMar 31, 2025
8352092: -XX:AOTMode=record crashes with InstanceKlass in allocated state
Reviewed-by: dholmes, coleenp
1 parent 1077265 commit a83760a

File tree

1 file changed

+31
-31
lines changed

1 file changed

+31
-31
lines changed
 

‎src/hotspot/share/cds/metaspaceShared.cpp

+31-31
Original file line numberDiff line numberDiff line change
@@ -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+
699698
public:
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

0 commit comments

Comments
 (0)
Please sign in to comment.