Perf: SATB and WB coalescing

Aleksey Shipilev shade at redhat.com
Wed Jan 10 11:30:22 UTC 2018


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



More information about the shenandoah-dev mailing list