RFR: 8295842: Generational ZGC: Elide barriers on variable array accesses after array allocations [v2]

Roberto Castañeda Lozano rcastanedalo at openjdk.org
Wed Nov 16 12:15:38 UTC 2022

On Wed, 16 Nov 2022 12:11:31 GMT, Roberto Castañeda Lozano <rcastanedalo at openjdk.org> wrote:

>> This changeset extends C2's barrier elision so that variable array accesses (array accesses with unknown offset at compile-time) are elided when they are dominated by the array's allocation and no safepoint is present in between, like in this example:
>> Element[] a = new Element[10]; // allocation
>> a[i] = e; // variable array access: the barrier is elided
>> This is achieved by relaxing the dominator-dominated pair test in [zBarrierSetC2.cpp](https://github.com/openjdk/zgc/blob/a460756f08df30af232fc631e94cf37c10c38352/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp#L714) so that unknown memory access offsets are accepted for array allocation dominators.
>> This refinement does not yield significant overall throughput changes in standard benchmark suites (DaCapo, SPECjvm2008), but has been observed to at least elide a few additional  barriers in individual benchmarks, e.g. DaCapo's H2:
>> Value[] keyValues = new Value[groupIndex.length]; // array allocation
>> // update group
>> for (int i = 0; i < groupIndex.length; i++) {
>>     int idx = groupIndex[i];
>>     Expression expr = expressions.get(idx);
>>     keyValues[i] = expr.getValue(session); // store barrier is elided by this changeset
>> }
>> #### Testing
>> - tier1-5 (windows-x64, linux-x64, linux-aarch64, macosx-x64, and macosx-aarch64; release and debug mode)
> Roberto Castañeda Lozano has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains four commits:
>  - Refine assertions
>  - Avoid eliding barriers if offsets are negative or undefined
>  - Merge zgc_generational
>  - Elide barriers on variable array accesses after array allocations

Thanks for looking at this, Erik!

> You changed get_base_and_offset to return the base even if the offset < 0, and then where get_base_and_offset is used, you check if the offset is < 0 and treat it as if the base returned NULL. Why is that? Is it because there is some kind of array case we want to optimize for, where the offset is negative but valid?

Right. An offset can be a special value `Type::OffsetTop` (-2000000000, representing undefined values), a special value `Type::OffsetBot` (-2000000001, representing unknown values), or a concrete value. Before this PR, we simply required that offsets be concrete and >= 0. The initial version of this PR relaxes this requirement to accept unknown offsets (with offset `Type::OffsetBot`) in allocation-dominated array accesses:

  Element[] a = new Element[10]; // allocation
  a[i] = e; // variable array access with unknown offset

  I have pushed (and re-tested) a new version that makes offset tests more explicit, documents what is expected in each case using assertions, and actually discards candidate array accesses with undefined or concrete-but-negative offsets (which was simply assumed to not happen in the previous revision). Please let me know whether this makes the changes clearer.


PR: https://git.openjdk.org/zgc/pull/8

More information about the zgc-dev mailing list