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);