RFR: 8371667: Shenandoah: Re-design alloc request type enum for better efficiency and cleaner code [v7]

Aleksey Shipilev shade at openjdk.org
Fri Nov 14 09:45:20 UTC 2025


On Thu, 13 Nov 2025 01:03:28 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:
> 
>   Fix wrong bit masks(offset by 1)

A bit confusing still. How about this:


[x|xx|xxx|xx]
           ^---- Requester:   
                     00 -- mutator
                     10 -- mutator (CDS)
                     01 -- GC
        ^------- Purpose:
                     00 -- shared
                     01 -- TLAB/GCLAB
                     11 -- PLAB
     ^---------- Affiliation: 
                     00 -- YOUNG
                     01 -- OLD
                     11 -- OLD, promotion


Then:


  static constexpr int bit_gc_alloc         = 1 << 0;
  static constexpr int bit_cds_alloc        = 1 << 1;
  static constexpr int bit_lab_alloc        = 1 << 2;
  static constexpr int bit_plab_alloc       = 1 << 3;
  static constexpr int bit_old_alloc        = 1 << 4;
  static constexpr int bit_promotion_alloc  = 1 << 5;

  static constexpr Type _alloc_shared              = 0;
  static constexpr Type _alloc_tlab                = bit_lab_alloc;
  static constexpr Type _alloc_cds                 = bit_cds_alloc;
  static constexpr Type _alloc_shared_gc           = bit_gc_alloc;
  static constexpr Type _alloc_shared_gc_old       = bit_gc_alloc | bit_old_alloc;
  static constexpr Type _alloc_shared_gc_promotion = bit_gc_alloc | bit_old_alloc | bit_promotion_alloc;
  static constexpr Type _alloc_gclab               = bit_gc_alloc | bit_lab_alloc;
  static constexpr Type _alloc_plab                = bit_gc_alloc | bit_plab_alloc | bit_old_alloc;

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

PR Review: https://git.openjdk.org/jdk/pull/28247#pullrequestreview-3463990104


More information about the hotspot-gc-dev mailing list