RFR: 8361099: Shenandoah: Improve heap lock contention by using CAS for memory allocation [v20]

Xiaolong Peng xpeng at openjdk.org
Mon Jan 12 21:14:16 UTC 2026


On Tue, 6 Jan 2026 21:17:57 GMT, Kelvin Nilsen <kdnilsen at openjdk.org> wrote:

>> Xiaolong Peng has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 265 commits:
>> 
>>  - Merge branch 'openjdk:master' into cas-alloc-1
>>  - Fix build error after merging from tip
>>  - Merge branch 'master' into cas-alloc-1
>>  - Merge branch 'master' into cas-alloc-1
>>  - Some comments updates as suggested in PR review
>>  - Fix build failure after merge
>>  - Expend promoted from ShenandoahOldCollectorAllocator
>>  - Merge branch 'master' into cas-alloc-1
>>  - Address PR comments
>>  - Merge branch 'openjdk:master' into cas-alloc-1
>>  - ... and 255 more: https://git.openjdk.org/jdk/compare/de81d389...cf13b7b5
>
> src/hotspot/share/gc/shenandoah/shenandoahAllocator.cpp line 194:
> 
>> 192:     if (ShenandoahHeapRegion* r =  nullptr; (r = _alloc_regions[i].address) != nullptr && r->is_active_alloc_region()) {
>> 193:       bool ready_for_retire = false;
>> 194:       HeapWord* obj = atomic_allocate_in(r, true, req, in_new_region, ready_for_retire);
> 
> Insert before atomic_allocate_in: int contended
> Pass this as 6th arg to atomic_allocate_in()
> Add this code after atomic_allocate_in():
>   if ((i == alloc_start_index) && (contended > 1)) {
>     randomize_start_index();  // I think this is realized by setting _alloc_start_index to UINT_MAX
>   }

template <ShenandoahFreeSetPartitionId ALLOC_PARTITION>
template<bool HOLDING_HEAP_LOCK>
HeapWord* ShenandoahAllocator<ALLOC_PARTITION>::attempt_allocation_in_alloc_regions(ShenandoahAllocRequest &req,
                                                                                    bool &in_new_region,
                                                                                    uint const alloc_start_index,
                                                                                    uint &regions_ready_for_refresh)


The API attempt_allocation_in_alloc_regions is designed as above, it tries to allocate from shared alloc regions, iterating from `alloc_start_index` in one run, it doesn't make sense to change the starting index inside this method during the loop.

Also, the `contended` you are suggesting is actually the number regions it has attempted in `attempt_allocation_in_alloc_regions`, It doesn't reflect the contention.

There might be case we truly want to shuffle/re-random the alloc_start_index for mutator threads, e.g. most of mutator threads have same alloc_start_index causing congestion/contention in one shared alloc region, but it is a bit tricky to trace and detects, we could do it in future improvments.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/26171#discussion_r2683919611


More information about the shenandoah-dev mailing list