RFR: 8339526: C2: store incorrectly removed for clone() transformed to series of loads/stores

Roland Westrelin roland at openjdk.org
Thu Oct 2 10:45:47 UTC 2025


In the `test1()` method of the test case:

`inlined2()` calls `clone()` for an object loaded from field `field`
that has inexact type `A` at parse time. The intrinsic for `clone()`
inserts an `Allocate` and an `ArrayCopy` nodes. When igvn runs, the
load of `field` is optimized out because it reads back a newly
allocated `B` written to `field` in the same method. `ArrayCopy` can
now be optimized because the type of its `src` input is known. The
type of its `dest` input is the `CheckCastPP` from the allocation of
the cloned object created at parse time. That one has type `A`. A
series of `Load`s/`Store`s are created to copy the fields of class `B`
from `src` (of type `B`) to `dest` of (type `A`).

Writting to `dest` with offsets for fields that don't exist in `A`,
causes this code in `Compile::flatten_alias_type()`:


    } else if (offset < 0 || offset >= ik->layout_helper_size_in_bytes()) {
      // Static fields are in the space above the normal instance
      // fields in the java.lang.Class instance.
      if (ik != ciEnv::current()->Class_klass()) {
        to = nullptr;
        tj = TypeOopPtr::BOTTOM;
        offset = tj->offset();
      }


to assign it some slice that doesn't match the one that's used at the
same offset in `B`.

That causes an assert in `ArrayCopyNode::try_clone_instance()` to
fire. With a release build, execution proceeds. `test1()` also has a
non escaping allocation. That one causes EA to run and
`ConnectionGraph::split_unique_types()` to move the store to the non
escaping allocation to a new slice. In the process, when it iterates
over `MergeMem` nodes, it notices the stores added by
`ArrayCopyNode::try_clone_instance()`, finds that some are not on the
right slice, tries to move them to the correct slice (expecting they
are from a non escaping EA). That causes some of the `Store`s to be
disconnected. When the resulting code runs, execution fails as some
fields are not copied.

The fix I propose is to skip `ArrayCopyNode::try_clone_instance()`
when `src` and `dest` classes don't match as this seems like a rare
enough corner case.

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

Commit messages:
 - test & fix

Changes: https://git.openjdk.org/jdk/pull/27604/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27604&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8339526
  Stats: 99 lines in 2 files changed: 99 ins; 0 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/27604.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27604/head:pull/27604

PR: https://git.openjdk.org/jdk/pull/27604


More information about the hotspot-compiler-dev mailing list