From e658b4ad109106a2570630eb01bfc174824279b9 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 16 Jul 2025 17:30:42 +0000 Subject: [PATCH] 8360288: Shenandoah crash at size_given_klass in op_degenerated Reviewed-by: shade --- .../share/gc/shenandoah/shenandoahHeap.cpp | 27 +++++++++---------- .../share/gc/shenandoah/shenandoahHeap.hpp | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index ceb067389a2..b07a085796e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1039,26 +1039,23 @@ void ShenandoahHeap::print_heap_regions_on(outputStream* st) const { } } -void ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) { +size_t ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) const { assert(start->is_humongous_start(), "reclaim regions starting with the first one"); - - oop humongous_obj = cast_to_oop(start->bottom()); - size_t size = humongous_obj->size(); - size_t required_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize); - size_t index = start->index() + required_regions - 1; - assert(!start->has_live(), "liveness must be zero"); - for(size_t i = 0; i < required_regions; i++) { - // Reclaim from tail. Otherwise, assertion fails when printing region to trace log, - // as it expects that every region belongs to a humongous region starting with a humongous start region. - ShenandoahHeapRegion* region = get_region(index --); - - assert(region->is_humongous(), "expect correct humongous start or continuation"); + // Do not try to get the size of this humongous object. STW collections will + // have already unloaded classes, so an unmarked object may have a bad klass pointer. + ShenandoahHeapRegion* region = start; + size_t index = region->index(); + do { + assert(region->is_humongous(), "Expect correct humongous start or continuation"); assert(!region->is_cset(), "Humongous region should not be in collection set"); - region->make_trash_immediate(); - } + region = get_region(++index); + } while (region != nullptr && region->is_humongous_continuation()); + + // Return number of regions trashed + return index - start->index(); } class ShenandoahCheckCleanGCLABClosure : public ThreadClosure { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index c7ba21e6e9f..a26f8375489 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -651,7 +651,7 @@ class ShenandoahHeap : public CollectedHeap { static inline void atomic_clear_oop(narrowOop* addr, oop compare); static inline void atomic_clear_oop(narrowOop* addr, narrowOop compare); - void trash_humongous_region_at(ShenandoahHeapRegion *r); + size_t trash_humongous_region_at(ShenandoahHeapRegion *r) const; private: void trash_cset_regions();