Perf: SATB and WB coalescing

Roman Kennke rkennke at redhat.com
Wed Jan 10 11:35:46 UTC 2018


Am 10.01.2018 um 12:30 schrieb Aleksey Shipilev:
> On 01/10/2018 12:20 PM, Roman Kennke wrote:
>> Am 10.01.2018 um 12:16 schrieb Aleksey Shipilev:
>>> On 01/10/2018 12:12 PM, Roman Kennke wrote:
>>>> That confirms what I suspected since a while. And I also sorta hope that the traversal GC will solve
>>>> it, because it only ever polls a single flag. We might even want to wrap RBs into evac-flag-checks
>>>> initially, so that the optimizer can coalesce them too, and remove lone evac-checks-around-RBs after
>>>> optimization.
>>>
>>> Let's not conflate this with traversal GC: flag handling and coalescing barriers in important even
>>> for our regular cycle. So I'd rather improve that part of the story, and then build traversal GC
>>> on top.
>>>
>>
>> Sure, that makes sense.
>>
>>> Do you have a separate patch that introduces a single flag instead of the assortment of
>>> {mark,evac,updaterefs}-in-progress and fixes all the uses around? That would be a base for further
>>> compiler optimizations, I think.
>>
>> No, for traversal GC I simply picked one flag (evac) and barriers use only that.
>>
>> How would you use a single flag, if we need to check 2 or 3 different phases?
> 
> Flag is int, and then bitmask it?
> 
> Something like:
> 
>    // Describes the current global GC state
>    enum ShenandoahCollectorState {
>      // Heap is not stable: there are forwarded objects.
>      _heap_unstable,
> 
>      // Heap is under stabilization: do not introduce new forwarded objects.
>      _heap_updating,
> 
>      // Heap is under evacuation: new forwarded objects are introduced.
>      _heap_evacuating,
> 
>      // Heap is under marking.
>      _heap_marking,
>    };
> 
>    enum ShenandoahCollectorStateMask {
>      _mask_heap_marking = 1 << _heap_marking;
>      _mask_heap_evacuating = 1 << _heap_evacuating;
>      ...
>    };
> 
> Later:
> 
>    movptr(tmp, (intptr_t) ShenandoahHeap::gc_state_addr());
>    movb(tmp, Address(tmp, 0));
>    testb(tmp, ShenandoahHeap::_mask_heap_evacuating);
> 
> I think phases really have different bit patterns then:
> 
>    mark:                          _heap_marking
>    mark + UR:                     _heap_marking + _heap_updating + _heap_unstable
>    evac:                          _heap_evacuating + _heap_unstable
>    update-refs:                   _heap_updating + _heap_unstable
>    idle:                          0
>    idle + waiting for mark to UR: _heap_unstable
>    partial:                       _heap_evacuating + _heap_updating + _heap_unstable
> 
> Barriers mapping:
>    RB, CAS, ACMP if _heap_unstable
>    WB if _heap_evacuating
>    SVRB if _heap_updating, but not _heap_evacuating
>    SWRB if _heap_updating, and _heap_evacuating
>    SATB if _heap_marking
> 
> Something like that...
> 
> Then a happy path in compiler-specialized code basically checks the GC state for 0, which means no
> barriers are required whatsoever until the safepoint hits, or _heap_unstable, which means only RBs
> are required on that path until the safepoint.
> 
> Thanks,
> -Aleksey
> 

Ah!
I made something like this a while ago and it hasn't gone in back then:
http://cr.openjdk.java.net/~rkennke/gc-phase-flag/webrev.01/

Roman



More information about the shenandoah-dev mailing list