RFR: 8373116: Genshen: arraycopy_work should be always done for arrays in old gen during young concurrent marking [v6]
William Kemper
wkemper at openjdk.org
Mon Dec 8 15:58:02 UTC 2025
On Sun, 7 Dec 2025 20:34:13 GMT, Xiaolong Peng <xpeng at openjdk.org> wrote:
>> Chasing the root cause of JDK-8372498, I have narrowed down root cause to the commit https://github.com/openjdk/jdk/commit/f8cf9ca69cfef286c80559bfe1d147b6303d10d2
>>
>> It is caused by the behavior change from follow code:
>>
>> Original:
>>
>> if (ShenandoahSATBBarrier) {
>> T* array = dst;
>> HeapWord* array_addr = reinterpret_cast<HeapWord*>(array);
>> ShenandoahHeapRegion* r = _heap->heap_region_containing(array_addr);
>> if (is_old_marking) {
>> // Generational, old marking
>> assert(_heap->mode()->is_generational(), "Invariant");
>> if (r->is_old() && (array_addr < _heap->marking_context()->top_at_mark_start(r))) {
>> arraycopy_work<T, false, false, true>(array, count);
>> }
>> } else if (_heap->mode()->is_generational()) {
>> // Generational, young marking
>> if (r->is_old() || (array_addr < _heap->marking_context()->top_at_mark_start(r))) {
>> arraycopy_work<T, false, false, true>(array, count);
>> }
>> } else if (array_addr < _heap->marking_context()->top_at_mark_start(r)) {
>> // Non-generational, marking
>> arraycopy_work<T, false, false, true>(array, count);
>> }
>> }
>>
>> New:
>>
>> if (ShenandoahSATBBarrier) {
>> if (!_heap->marking_context()->allocated_after_mark_start(reinterpret_cast<HeapWord*>(dst))) {
>> arraycopy_work<T, false, false, true>(dst, count);
>> }
>> }
>>
>>
>>
>> With the new STAB barrier code for arraycopy_marking, if is it young GC and the array is in old region, but array is above TAMS(Old GC may not be started, TAMS of old region is not captured), arraycopy_work won't be applied anymore, so we may have missed some pointers in SATB in such case during concurrent young marking.
>>
>> ### Test
>> - [x] hotspot_gc_shenandoah
>> - [x] repeat gc/TestAllocHumongousFragment.java#generational and sure it won't crash with the fix
>> - [x] GHA
>
> Xiaolong Peng has updated the pull request incrementally with one additional commit since the last revision:
>
> enqueue objects stored in old array at ShenandoahSATBBarrier when concurrent young marking is in progress
src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp line 451:
> 449: if (ShenandoahSATBBarrier) {
> 450: if (!_heap->marking_context()->allocated_after_mark_start(reinterpret_cast<HeapWord*>(dst)) ||
> 451: (_heap->is_concurrent_young_mark_in_progress() && _heap->heap_region_containing(dst)->is_old())) {
We could also check if Shenandoah is running in generational mode. Even in non-generational mode, we set `YOUNG_MARKING` in gc state.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/28669#discussion_r2599168582
More information about the shenandoah-dev
mailing list