RFR: 8346280: C2: implement late barrier elision for G1 [v2]
Roberto Castañeda Lozano
rcastanedalo at openjdk.org
Mon Jan 27 14:06:30 UTC 2025
> 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_index`, `look_through_node`, `is_{undefined|unknown|concrete}`, `get_base_and_offset`, `is_array...
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
-------------
Changes: https://git.openjdk.org/jdk/pull/23235/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23235&range=01
Stats: 777 lines in 9 files changed: 494 ins; 264 del; 19 mod
Patch: https://git.openjdk.org/jdk/pull/23235.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/23235/head:pull/23235
PR: https://git.openjdk.org/jdk/pull/23235
More information about the hotspot-compiler-dev
mailing list