From 347084bfbdbf048cd50c0e13e43ae53f6da77e6e Mon Sep 17 00:00:00 2001 From: William Kemper Date: Thu, 17 Jul 2025 16:50:07 +0000 Subject: [PATCH] 8360288: Shenandoah crash at size_given_klass in op_degenerated Reviewed-by: shade Backport-of: 3b44d7bfa4d78e3ec715fce1863e052852f33180 --- .../share/gc/shenandoah/shenandoahHeap.cpp | 28 ++++++++----------- .../share/gc/shenandoah/shenandoahHeap.hpp | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 55dfb2e8de4..0fc7ba39cfa 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1452,27 +1452,23 @@ void ShenandoahHeap::print_heap_regions_on(outputStream* st) const { } } -size_t 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(); - } - return required_regions; + 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 4124bf8be7f..9f5f384cc29 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -828,7 +828,7 @@ public: static inline void atomic_clear_oop(narrowOop* addr, oop compare); static inline void atomic_clear_oop(narrowOop* addr, narrowOop compare); - size_t trash_humongous_region_at(ShenandoahHeapRegion *r); + size_t trash_humongous_region_at(ShenandoahHeapRegion *r) const; static inline void increase_object_age(oop obj, uint additional_age);