RFR: 8346280: C2: implement late barrier elision for G1

Sergey Nazarkin snazarki at openjdk.org
Fri Jan 24 07:42:47 UTC 2025


On Wed, 22 Jan 2025 15:20:19 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_index`, `look_through_node`, `is_{undefined|unknown|concrete}`, `get_base_and_offset`, `is_array...

I observe several test failures on arm32. Investigating the problem

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23235#issuecomment-2611857946


More information about the hotspot-compiler-dev mailing list