> This PR reduces the amount of lambda forms (LFs) which are created when > generating var handles for simple struct field accessors. This contributes to > the startup regression seen in > [JDK-8337505](https://bugs.openjdk.org/browse/JDK-8337505). > > There are essentially three sources of excessive var handle adaptation: > > 1. `LayoutPath::dereferenceHandle` has to do some very complex adaptation > (including a permute) in order to inject alignment and size checks (against > the enclosing layout) on the generated var handle. > 2. Even in simple cases (e.g. when there's no dynamic coordinate), the offset > of the accessed field is added to the var handle via an expensive collect > adapter. > 3. When we adapt a `long` var handle to work on `MemorySegment` using an > `AddressLayout`, we make no distinction on whether the address layout has a > target layout or not. In the latter case (common!) we can adapt more simply. > > The meat of this PR is to address (1) by changing the shape of the generated > helpers in the `X-VarHandleSegmentView.java.template` class. That is, the > method for doing a plain get will now have the following shape: > > > T get(MemorySegment segment, MemoryLayout enclosing, long base, long offset) > > > Where: > * `segment` is the segment being accessed > * `enclosing` is the enclosing layout (the root of the selected layout path) > against which to check size and alignment > * `base` is the public-facing offset passed by the user when calling `get` on > the var handle > * `offset` is the offset at which the selected layout element can be found > from the root (this can be replaced with an expression that takes several > dynamic indices and turn them into a single offset) > > With this organization, it is easy to see how, in order to create a memory > access var handle for a struct field `S.f` we only need to: > * inject the enclosing layout `S` into the var handle (into the `enclosing` > coordinate) > * inject the offset of `S.f` into the var handle (into the `offset` > coordinate) > > This way, we get our plain old memory access var handle featuring only two > coordinates: a segment and an offset. Note how, to get there, we only needed > very simple adaptations (e.g. `MethodHandles::insertCoordinates`). > > #### Evaluation > > I did some tests using the benchmark in > [JDK-8337505](https://bugs.openjdk.org/browse/JDK-8337505) to assess the > impact of this change on startup. To evaluate startup, I ran the benchmark 50 > times and then took some stats. Here's what the numbers look before this > change (AVG = average, MED = med...
Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Address review comment Clarify code comment ------------- Changes: - all: https://git.openjdk.org/jdk/pull/20647/files - new: https://git.openjdk.org/jdk/pull/20647/files/a3018b26..b6c7cf1d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=20647&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=20647&range=00-01 Stats: 25 lines in 4 files changed: 10 ins; 12 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/20647.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/20647/head:pull/20647 PR: https://git.openjdk.org/jdk/pull/20647