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