Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8348400: GenShen: assert(ShenandoahHeap::heap()->is_full_gc_in_progress() || (used_regions_size() <= _max_capacity)) failed: Cannot use more than capacity # #23998

Closed
14 changes: 9 additions & 5 deletions src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp
Original file line number Diff line number Diff line change
@@ -1310,7 +1310,7 @@ bool ShenandoahFreeSet::flip_to_old_gc(ShenandoahHeapRegion* r) {
// mutator (they have nothing to steal), but they do have a usable region in their partition. What
// we want to do here is swap that region from the mutator partition with one from the old collector
// partition.
// 1. Find an unusable trash region in the old collector partition
// 1. Find a temporarily unusable trash region in the old collector partition
ShenandoahRightLeftIterator iterator(&_partitions, ShenandoahFreeSetPartitionId::OldCollector, true);
idx_t unusable_trash = -1;
for (unusable_trash = iterator.current(); iterator.has_next(); unusable_trash = iterator.next()) {
@@ -1321,20 +1321,24 @@ bool ShenandoahFreeSet::flip_to_old_gc(ShenandoahHeapRegion* r) {
}

if (unusable_trash != -1) {
// 2. Move it to the mutator partition
const size_t unusable_capacity = alloc_capacity(unusable_trash);
// 2. Move the (temporarily) unusable trash region we found to the mutator partition
_partitions.move_from_partition_to_partition(unusable_trash,
ShenandoahFreeSetPartitionId::OldCollector,
ShenandoahFreeSetPartitionId::Mutator, region_capacity);
ShenandoahFreeSetPartitionId::Mutator, unusable_capacity);

// 3. Move this usable region to the old collector partition
// 3. Move this usable region from the mutator partition to the old collector partition
_partitions.move_from_partition_to_partition(idx,
ShenandoahFreeSetPartitionId::Mutator,
ShenandoahFreeSetPartitionId::OldCollector, region_capacity);

_partitions.assert_bounds();

// 4. Do not adjust capacities for generations, we just swapped the regions that have already
// been accounted for.
// been accounted for. However, we should adjust the evacuation reserves as those may have changed.
shenandoah_assert_heaplocked();
const size_t reserve = _heap->old_generation()->get_evacuation_reserve();
_heap->old_generation()->set_evacuation_reserve(reserve - unusable_capacity + region_capacity);
return true;
}
}
4 changes: 3 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp
Original file line number Diff line number Diff line change
@@ -323,9 +323,11 @@ class ShenandoahFreeSet : public CHeapObj<mtGC> {
//
// Typical usage: During evacuation, the GC may find it needs more memory than had been reserved at the start of evacuation to
// hold evacuated objects. If this occurs and memory is still available in the Mutator's free set, we will flip a region from
// the Mutator free set into the Collector or OldCollector free set.
// the Mutator free set into the Collector or OldCollector free set. The conditions to move this region are checked by
// the caller, so the given region is always moved.
void flip_to_gc(ShenandoahHeapRegion* r);

// Return true if and only if the given region is successfully flipped to the old partition
bool flip_to_old_gc(ShenandoahHeapRegion* r);

// Handle allocation for mutator.