RFR: 8371667: Shenandoah: Re-design alloc request type enum for better efficiency and cleaner code [v11]
Xiaolong Peng
xpeng at openjdk.org
Mon Nov 17 16:36:18 UTC 2025
On Mon, 17 Nov 2025 16:25:55 GMT, Xiaolong Peng <xpeng at openjdk.org> wrote:
>> Current alloc request type enum:
>>
>> enum Type {
>> _alloc_shared, // Allocate common, outside of TLAB
>> _alloc_shared_gc, // Allocate common, outside of GCLAB/PLAB
>> _alloc_cds, // Allocate for CDS
>> _alloc_tlab, // Allocate TLAB
>> _alloc_gclab, // Allocate GCLAB
>> _alloc_plab, // Allocate PLAB
>> _ALLOC_LIMIT
>> };
>>
>> With current design, we have to use switch statement in multiple places resulting in unnecessary branches, for instance the function is_mutator_alloc:
>>
>>
>> inline bool is_mutator_alloc() const {
>> switch (_alloc_type) {
>> case _alloc_tlab:
>> case _alloc_shared:
>> case _alloc_cds:
>> return true;
>> case _alloc_gclab:
>> case _alloc_plab:
>> case _alloc_shared_gc:
>> return false;
>> default:
>> ShouldNotReachHere();
>> return false;
>> }
>> }
>>
>>
>>
>> In PR, I have re-designed the enum to make the function like is_mutator_alloc much simpler by making the values of the enum follow two simple rules:
>> 1. Smaller value for mutator alloc, larger value for gc alloc; GC alloc types are always greater than any of mutator alloc types.
>> 2. Odd for lab, even number for non-lab
>>
>> Three functions have been simplified to one-line impl w/o branches in machine code:
>>
>>
>> inline bool is_mutator_alloc() const {
>> return _alloc_type <= _alloc_shared;
>> }
>>
>> inline bool is_gc_alloc() const {
>> return _alloc_type >= _alloc_shared_gc;
>> }
>>
>> inline bool is_lab_alloc() const {
>> return (_alloc_type & 1) == 1;
>> }
>>
>>
>> I didn't check compiled assemble code of hotspot, in instead, I wrote similar/equivalent code and compile with gcc for comparison using godbolt.org:
>>
>> bool is_lab_alloc(int alloc_type) {
>> return (alloc_type & 1) == 1;
>> }
>>
>> bool is_lab_alloc_switch(int alloc_type) {
>> switch (alloc_type) {
>> case 0:
>> case 2:
>> case 4:
>> return false;
>> case 1:
>> case 3:
>> case 5:
>> return true;
>> default:
>> throw "Should not reach here";
>>
>> }
>> }
>>
>> x86_64 assembly code (https://godbolt.org/z/h7xfz8PaT):
>>
>> is_lab_alloc(int):
>> push rbp
>> mov rbp, rsp
>> mov DWORD PTR [rbp-4], edi
>> mov eax, DWORD PTR [rbp-4]
>> and eax, 1
>> and eax, 1
>> pop rbp
>> ret
>> .LC0:
>> .string "Should not reach here"
>> is_lab_allo...
>
> Xiaolong Peng has updated the pull request incrementally with one additional commit since the last revision:
>
> Address review comments
src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp line 1618:
> 1616: size_t ac = alloc_capacity(r);
> 1617: ShenandoahFreeSetPartitionId orig_partition;
> 1618: ShenandoahGeneration* request_generation = nullptr;
`ac` and `request_generation` are not actually used, we can remove them, but it is not really related to the purpose of this PR, probably better create a separate PR for the clean-ups.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/28247#discussion_r2534765340
More information about the hotspot-gc-dev
mailing list