diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 9cd22e6ee25..817f5e8dc47 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -2700,10 +2700,7 @@ GrowableArray ShenandoahHeap::memory_pools() { } MemoryUsage ShenandoahHeap::memory_usage() { - assert(_initial_size <= ShenandoahHeap::heap()->max_capacity(), "sanity"); - assert(used() <= ShenandoahHeap::heap()->max_capacity(), "sanity"); - assert(committed() <= ShenandoahHeap::heap()->max_capacity(), "sanity"); - return MemoryUsage(_initial_size, used(), committed(), max_capacity()); + return shenandoah_memory_usage(_initial_size, used(), committed(), max_capacity()); } ShenandoahRegionIterator::ShenandoahRegionIterator() : diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp index d55d1bd8147..dfc34dcc3c3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp @@ -48,25 +48,7 @@ ShenandoahMemoryPool::ShenandoahMemoryPool(ShenandoahHeap* heap, MemoryUsage ShenandoahMemoryPool::get_memory_usage() { - size_t initial = initial_size(); - size_t max = max_size(); - size_t used = used_in_bytes(); - size_t committed = _heap->committed(); - - // These asserts can never fail: max is stable, and all updates to other values never overflow max. - assert(initial <= max, "initial: %zu, max: %zu", initial, max); - assert(used <= max, "used: %zu, max: %zu", used, max); - assert(committed <= max, "committed: %zu, max: %zu", committed, max); - - // Committed and used are updated concurrently and independently. They can momentarily break - // the assert below, which would also fail in downstream code. To avoid that, adjust values - // to make sense under the race. See JDK-8207200. - committed = MAX2(used, committed); - assert(used <= committed, "used: %zu, committed: %zu", used, committed); - assert(initial <= _heap->max_capacity(), "sanity"); - assert(committed <= _heap->max_capacity(), "sanity"); - assert(max <= _heap->max_capacity(), "sanity"); - return MemoryUsage(initial, used, committed, max); + return shenandoah_memory_usage(initial_size(), used_in_bytes(), _heap->committed(), max_size()); } size_t ShenandoahMemoryPool::used_in_bytes() { @@ -83,16 +65,7 @@ ShenandoahGenerationalMemoryPool::ShenandoahGenerationalMemoryPool(ShenandoahHea _generation(generation) { } MemoryUsage ShenandoahGenerationalMemoryPool::get_memory_usage() { - size_t initial = initial_size(); - size_t max = max_size(); - size_t used = used_in_bytes(); - size_t committed = _generation->used_regions_size(); - - assert(initial <= _heap->max_capacity(), "sanity"); - assert(used <= _heap->max_capacity(), "sanity"); - assert(committed <= _heap->max_capacity(), "sanity"); - assert(max <= _heap->max_capacity(), "sanity"); - return MemoryUsage(initial, used, committed, max); + return shenandoah_memory_usage(initial_size(), used_in_bytes(), _generation->used_regions_size(), max_size()); } size_t ShenandoahGenerationalMemoryPool::used_in_bytes() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp index ccdfdddede9..d466087b9b7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp @@ -30,6 +30,17 @@ #include "services/memoryPool.hpp" #include "services/memoryUsage.hpp" +// Constructs a MemoryUsage from concurrently sampled values, clamping committed +// to be at least as large as used to account for concurrent updates. See JDK-8207200. +inline MemoryUsage shenandoah_memory_usage(size_t initial, size_t used, size_t committed, size_t max) { + assert(initial <= max, "initial: %zu, max: %zu", initial, max); + assert(used <= max, "used: %zu, max: %zu", used, max); + assert(committed <= max, "committed: %zu, max: %zu", committed, max); + committed = MAX2(used, committed); + assert(used <= committed, "used: %zu, committed: %zu", used, committed); + return MemoryUsage(initial, used, committed, max); +} + class ShenandoahMemoryPool : public CollectedMemoryPool { protected: ShenandoahHeap* _heap;