8377011: Shenandoah: assert_bounds should be only called when boundaries have changed

Reviewed-by: wkemper, kdnilsen
This commit is contained in:
Xiaolong Peng 2026-02-26 00:24:46 +00:00
parent 32cc7f1f57
commit abec212428
3 changed files with 29 additions and 9 deletions

View File

@ -1194,6 +1194,18 @@ void ShenandoahRegionPartitions::assert_bounds() {
assert(_humongous_waste[int(ShenandoahFreeSetPartitionId::Mutator)] == young_humongous_waste,
"Mutator humongous waste must match");
}
inline void ShenandoahRegionPartitions::assert_bounds_sanity() {
for (uint8_t i = 0; i < UIntNumPartitions; i++) {
ShenandoahFreeSetPartitionId partition = static_cast<ShenandoahFreeSetPartitionId>(i);
assert(leftmost(partition) == _max || membership(leftmost(partition)) == partition, "Left most boundry must be sane");
assert(rightmost(partition) == -1 || membership(rightmost(partition)) == partition, "Right most boundry must be sane");
assert(leftmost_empty(partition) == _max || leftmost_empty(partition) >= leftmost(partition), "Left most empty must be sane");
assert(rightmost_empty(partition) == -1 || rightmost_empty(partition) <= rightmost(partition), "Right most empty must be sane");
}
}
#endif
ShenandoahFreeSet::ShenandoahFreeSet(ShenandoahHeap* heap, size_t max_regions) :
@ -1654,6 +1666,12 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah
// Not old collector alloc, so this is a young collector gclab or shared allocation
orig_partition = ShenandoahFreeSetPartitionId::Collector;
}
DEBUG_ONLY(bool boundary_changed = false;)
if ((result != nullptr) && in_new_region) {
_partitions.one_region_is_no_longer_empty(orig_partition);
DEBUG_ONLY(boundary_changed = true;)
}
if (alloc_capacity(r) < PLAB::min_size() * HeapWordSize) {
// Regardless of whether this allocation succeeded, if the remaining memory is less than PLAB:min_size(), retire this region.
// Note that retire_from_partition() increases used to account for waste.
@ -1662,15 +1680,11 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah
// then retire the region so that subsequent searches can find available memory more quickly.
size_t idx = r->index();
if ((result != nullptr) && in_new_region) {
_partitions.one_region_is_no_longer_empty(orig_partition);
}
size_t waste_bytes = _partitions.retire_from_partition(orig_partition, idx, r->used());
DEBUG_ONLY(boundary_changed = true;)
if (req.is_mutator_alloc() && (waste_bytes > 0)) {
increase_bytes_allocated(waste_bytes);
}
} else if ((result != nullptr) && in_new_region) {
_partitions.one_region_is_no_longer_empty(orig_partition);
}
switch (orig_partition) {
@ -1711,7 +1725,13 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah
default:
assert(false, "won't happen");
}
_partitions.assert_bounds();
#ifdef ASSERT
if (boundary_changed) {
_partitions.assert_bounds();
} else {
_partitions.assert_bounds_sanity();
}
#endif
return result;
}

View File

@ -402,6 +402,9 @@ public:
// idx <= rightmost
// }
void assert_bounds() NOT_DEBUG_RETURN;
// this checks certain sanity conditions related to the bounds with much less effort than is required to
// more rigorously enforce correctness as is done by assert_bounds()
inline void assert_bounds_sanity() NOT_DEBUG_RETURN;
};
// Publicly, ShenandoahFreeSet represents memory that is available to mutator threads. The public capacity(), used(),

View File

@ -96,9 +96,6 @@ gc/TestAllocHumongousFragment.java#g1 8298781 generic-all
gc/TestAllocHumongousFragment.java#static 8298781 generic-all
gc/shenandoah/oom/TestAllocOutOfMemory.java#large 8344312 linux-ppc64le
gc/shenandoah/TestEvilSyncBug.java#generational 8345501 generic-all
gc/shenandoah/TestRetainObjects.java#no-tlab 8361099 generic-all
gc/shenandoah/TestSieveObjects.java#no-tlab 8361099 generic-all
gc/shenandoah/TestSieveObjects.java#no-tlab-genshen 8361099 generic-all
#############################################################################