On Mon, 3 Nov 2025 13:00:38 GMT, Paul Hübner <[email protected]> wrote:
> Hi all, > > This PR fixes [JDK-8370479](https://bugs.openjdk.org/browse/JDK-8370479), as > we currently don't emit barriers correctly. Tested tiers 1-3. > > ## Context > > If we consider a value class/record that contains a single field, which is a > reference to an identity object: > > public static value record Element(Identity underlying) {} > public static class Identity {} > > We can create a flattened array via the JDK-internal `ValueClass` API: > > Object[] array = ValueClass.newNullableAtomicArray(Element.class, 16); > > This will indeed be flattened when running with compressed oops. T the > reference to `underlying` will be four bytes, and the null-marker an > additional byte. Hence, we are below the 64-bit limit. Copying this array via > `Arrays.copyOf` will trigger Valhalla-specific copying. > > When running with G1, there are various crashes and verification errors. This > should not impact ZGC, as the pointers are too large to be flattened in a > nullable array. > > ## New Barrier Emission > > We do not emit a post-write barrier when copying to an uninitialized memory > destination. The tables below summarize what barriers, if any, are emitted > both in the old and new versions of the copy implementation. Note that > Serial, Parallel and G1 have the notion of post-write barriers to track > intergenerational references. G1 is the only GC requiring pre-write barriers. > > **Old G1 barrier emission during flat array copying:** > | | oopless | contains oops | > | --- | --- | --- | > | uninitialized | | | > | initialized | | pre, post | > > **New G1 barrier emission during flat array copying:** > | | oopless | contains oops | > | --- | --- | --- | > | uninitialized | | post | > | initialized | | pre, post | > > As mentioned, when copying to uninitialized memory, a cross-generational > could be "lost" due to the lack of a post-write barrier. We should *not* use > a pre-write barrier when copying to uninitialized memory when running with > G1. Doing so means we may get garbage in our SATB buffers. > > ## New Test Cases > > I introduce a test scenario where we grow a flat array similar to how one > would grow an `ArrayList`. This should generate plenty of garbage, and > triggers this crash even without the whitebox GC. I test the three GCs that > use `ModRefBarrierSet`: Serial, Parallel and G1. These are tweaked to be less > concurrent/parallel to aid with reproducability in case of crashes. > > ## Fixed Oop Printing > > When G1 verification fails, it tries to print diagnostic information. This > will eventually end up printing oops. We handle the ca... Good catch on the memory barrier! LGTM. ------------- Marked as reviewed by fparain (Committer). PR Review: https://git.openjdk.org/valhalla/pull/1713#pullrequestreview-3416291992
