From 99c299f0985c8be63b9b60e589db520d83fd8033 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 14 Jul 2025 09:39:06 +0000 Subject: [PATCH] 8361706: Parallel weak klass link cleaning does not clean out previous klasses Reviewed-by: eosterlund, coleenp --- .../share/gc/shared/parallelCleaning.cpp | 2 +- .../share/gc/shared/parallelCleaning.hpp | 4 ---- src/hotspot/share/oops/klass.cpp | 17 ++++++++++------- src/hotspot/share/oops/klass.hpp | 3 +++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/shared/parallelCleaning.cpp b/src/hotspot/share/gc/shared/parallelCleaning.cpp index 4708df4d3e5..0cba1f8e166 100644 --- a/src/hotspot/share/gc/shared/parallelCleaning.cpp +++ b/src/hotspot/share/gc/shared/parallelCleaning.cpp @@ -128,6 +128,6 @@ void KlassCleaningTask::work() { // All workers will help cleaning the classes, InstanceKlass* klass; while ((klass = claim_next_klass()) != nullptr) { - clean_klass(klass); + Klass::clean_weak_instanceklass_links(klass); } } diff --git a/src/hotspot/share/gc/shared/parallelCleaning.hpp b/src/hotspot/share/gc/shared/parallelCleaning.hpp index a15326f1b85..6b16894954c 100644 --- a/src/hotspot/share/gc/shared/parallelCleaning.hpp +++ b/src/hotspot/share/gc/shared/parallelCleaning.hpp @@ -66,10 +66,6 @@ private: public: - void clean_klass(InstanceKlass* ik) { - ik->clean_weak_instanceklass_links(); - } - void work(); }; diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 958e1f61351..41ab8e325ab 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -749,17 +749,20 @@ void Klass::clean_weak_klass_links(bool unloading_occurred, bool clean_alive_kla // Clean the implementors list and method data. if (clean_alive_klasses && current->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(current); - ik->clean_weak_instanceklass_links(); - - // JVMTI RedefineClasses creates previous versions that are not in - // the class hierarchy, so process them here. - while ((ik = ik->previous_versions()) != nullptr) { - ik->clean_weak_instanceklass_links(); - } + clean_weak_instanceklass_links(ik); } } } +void Klass::clean_weak_instanceklass_links(InstanceKlass* ik) { + ik->clean_weak_instanceklass_links(); + // JVMTI RedefineClasses creates previous versions that are not in + // the class hierarchy, so process them here. + while ((ik = ik->previous_versions()) != nullptr) { + ik->clean_weak_instanceklass_links(); + } +} + void Klass::metaspace_pointers_do(MetaspaceClosure* it) { if (log_is_enabled(Trace, aot)) { ResourceMark rm; diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 58112b732b9..18b8b5885a3 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -734,7 +734,10 @@ public: void clean_subklass(); + // Clean out unnecessary weak klass links from the whole klass hierarchy. static void clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses = true); + // Clean out unnecessary weak klass links from the given InstanceKlass. + static void clean_weak_instanceklass_links(InstanceKlass* ik); // Return self, except for abstract classes with exactly 1 // implementor. Then return the 1 concrete implementation.