diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 3c7f25a950b38..de2f14155eb1a 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -559,7 +559,18 @@ ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref ref->msotype() == MetaspaceObj::KlassTrainingDataType || ref->msotype() == MetaspaceObj::MethodTrainingDataType || ref->msotype() == MetaspaceObj::CompileTrainingDataType) { - return (TrainingData::need_data() || TrainingData::assembling_data()) ? make_a_copy : set_to_null; + if (TrainingData::need_data() || TrainingData::assembling_data()) { + // Only add MethodCounters that are reachable via MethodTrainingData, + // i.e. MethodCounters associated with a valid MethodTrainingData. + if (ref->msotype() == MetaspaceObj::MethodCountersType) { + MethodCounters* mcs = (MethodCounters*)obj; + return mcs->has_valid_method_training_data() ? make_a_copy : set_to_null; + } else { + return make_a_copy; + } + } else { + return set_to_null; + } } else if (ref->msotype() == MetaspaceObj::AdapterHandlerEntryType) { return CDSConfig::is_dumping_adapters() ? make_a_copy : set_to_null; } else { diff --git a/src/hotspot/share/oops/methodCounters.cpp b/src/hotspot/share/oops/methodCounters.cpp index 8f29f9b7bbde4..3f01f724d58b2 100644 --- a/src/hotspot/share/oops/methodCounters.cpp +++ b/src/hotspot/share/oops/methodCounters.cpp @@ -95,6 +95,12 @@ void MethodCounters::restore_unshareable_info(TRAPS) { } #endif // INCLUDE_CDS +bool MethodCounters::has_valid_method_training_data() { + Metadata* mtd = method_training_data(); + Metadata* mts = method_training_data_sentinel(); + return mtd != mts; +} + void MethodCounters::print_on(outputStream* st) const { assert(is_methodCounters(), "should be method counters"); st->print("method counters"); diff --git a/src/hotspot/share/oops/methodCounters.hpp b/src/hotspot/share/oops/methodCounters.hpp index 5733e6e61f096..f9fb9fe8de737 100644 --- a/src/hotspot/share/oops/methodCounters.hpp +++ b/src/hotspot/share/oops/methodCounters.hpp @@ -165,6 +165,8 @@ class MethodCounters : public Metadata { return false; } + bool has_valid_method_training_data(); + #if INCLUDE_CDS void remove_unshareable_info(); void restore_unshareable_info(TRAPS); diff --git a/src/hotspot/share/oops/trainingData.cpp b/src/hotspot/share/oops/trainingData.cpp index 1a16fd70e446d..d049f6d0dd439 100644 --- a/src/hotspot/share/oops/trainingData.cpp +++ b/src/hotspot/share/oops/trainingData.cpp @@ -119,7 +119,7 @@ void TrainingData::verify() { MethodTrainingData* MethodTrainingData::make(const methodHandle& method, bool null_if_not_found, bool use_cache) { MethodTrainingData* mtd = nullptr; - if (!have_data() && !need_data()) { + if ((!have_data() && !need_data()) || (assembling_data() && !CDSConfig::is_at_aot_safepoint())) { return mtd; } // Try grabbing the cached value first.