RFR: 8346280: C2: implement late barrier elision for G1 [v2]
Martin Doerr
mdoerr at openjdk.org
Mon Jan 27 18:43:52 UTC 2025
On Mon, 27 Jan 2025 14:06:30 GMT, Roberto Castañeda Lozano <rcastanedalo at openjdk.org> wrote:
>> G1 barriers can be safely elided from writes to newly allocated objects as long as no safepoint is taken between the allocation and the write. This changeset complements early G1 barrier elision (performed by the platform-independent phases of C2, and limited to writes immediately following allocations) with a more general elision pass done at a late stage.
>>
>> The late elision pass exploits that it runs at a stage where the relative order of memory accesses and safepoints cannot change anymore to elide barriers from initialization writes that do not immediately follow the corresponding allocation, e.g. in conditional initialization writes:
>>
>>
>> o = new MyObject();
>> if (...) {
>> o.myField = ...; // barrier elided only after this changeset
>> // (assuming no safepoint in the if condition)
>> }
>>
>>
>> or in initialization writes placed after exception-throwing checks:
>>
>>
>> o = new MyObject();
>> if (...) {
>> throw new Exception("");
>> }
>> o.myField = ...; // barrier elided only after this changeset
>> // (assuming no safepoint in the above if condition)
>>
>>
>> These patterns are commonly found in Java code, e.g. in the core libraries:
>>
>> - [conditional initialization](https://github.com/openjdk/jdk/blob/25fecaaf87400af535c242fe50296f1f89ceeb16/src/java.base/share/classes/java/lang/String.java#L4850), or
>>
>> - [initialization after exception-throwing checks (in the superclass constructor)](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/nio/X-Buffer.java.template#L324).
>>
>> The optimization also enhances barrier elision for array initialization writes, for example eliding barriers from small array initialization loops (for which safepoints are not inserted):
>>
>>
>> Object[] a = new Object[...];
>> for (int i = 0; i < a.length; i++) {
>> a[i] = ...; // barrier elided only after this changeset
>> }
>>
>>
>> or eliding barriers from array initialization writes with unknown array index:
>>
>>
>> Object[] a = new Object[...];
>> a[index] = ...; // barrier elided only after this changeset
>>
>>
>> The logic used to perform this additional barrier elision is a subset of a pre-existing ZGC-specific optimization. This changeset simply reuses the relevant subset (barrier elision for writes to newly-allocated objects) by extracting the core of the optimization logic from `zBarrierSetC2.cpp` into the GC-shared file `barrierSetC2.cpp`. The functions `block_has_safepoint`, `block_inde...
>
> 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 11 commits:
>
> - Merge commit 'afcc2b0' into JDK-8346280-late-barrier-elision
> - Add new test case (store after exception)
> - Remove unused includes
> - Remove temporary UseNewCode guard
> - Use clearer names and document access API interface
> - Move ZGC-specific barrier elision code to BarrierSetC2
> - Set UseNewCode to true temporarily
> - Make elide_mach_barrier virtual
> - Move late barrier elision analysis from G1BarrierSetC2 to BarrierSetC2
> - Initial implementation
> - ... and 1 more: https://git.openjdk.org/jdk/compare/afcc2b03...ab47d7f8
Thanks for updating it! The tests which previously failed were all green, but I'll rerun more tests.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/23235#issuecomment-2616611577
More information about the hotspot-compiler-dev
mailing list