jdk icon indicating copy to clipboard operation
jdk copied to clipboard

8160821: VarHandle accesses are penalized when argument conversion is required

Open liach opened this issue 1 month ago • 10 comments

Since access descriptor is created for each VH operation site, we can optimistically cache the adapted method handle in a site if the site operates on a constant VH. Used a C2 IR test to verify such a setup through an inexact VarHandle invocation can be constant folded through (previously, it was blocked by asType)


Progress

  • [ ] Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • [x] Change must not contain extraneous whitespace
  • [x] Commit message must refer to an issue

Issue

  • JDK-8160821: VarHandle accesses are penalized when argument conversion is required (Enhancement - P3)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28585/head:pull/28585
$ git checkout pull/28585

Update a local copy of the PR:
$ git checkout pull/28585
$ git pull https://git.openjdk.org/jdk.git pull/28585/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28585

View PR using the GUI difftool:
$ git pr show -t 28585

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28585.diff

Using Webrev

Link to Webrev Comment

liach avatar Dec 01 '25 20:12 liach

:wave: Welcome back liach! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

bridgekeeper[bot] avatar Dec 01 '25 20:12 bridgekeeper[bot]

@liach This change is no longer ready for integration - check the PR body for details.

openjdk[bot] avatar Dec 01 '25 20:12 openjdk[bot]

@liach The following labels will be automatically applied to this pull request:

  • build
  • core-libs
  • graal
  • hotspot

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

openjdk[bot] avatar Dec 01 '25 20:12 openjdk[bot]

java.lang.invoke tests all pass. New benchmark results for VarHandleExact:

Benchmark                                 Mode  Cnt  Score   Error  Units
VarHandleExact.exact_exactInvocation      avgt   30  0.380 ± 0.007  ns/op
VarHandleExact.generic_exactInvocation    avgt   30  0.389 ± 0.008  ns/op
VarHandleExact.generic_genericInvocation  avgt   30  0.384 ± 0.008  ns/op

Submitting internal CI runs.

liach avatar Dec 01 '25 20:12 liach

/cc hotspot-compiler

liach avatar Dec 01 '25 20:12 liach

@liach The hotspot-compiler label was successfully added.

openjdk[bot] avatar Dec 01 '25 20:12 openjdk[bot]

Since I removed the return type dropping VarHandle bypass, TestGetAndAdd became affected because it can no longer access the x86 assembly. Updated the Java calling convention to fix it.

liach avatar Dec 01 '25 23:12 liach

After consulting with @iwanowww, I realized the non-constant status cannot be determined, that the C2 compiled method can even transition from 0 to 1, so I am simplifying this code to only handle the constant case. It seems the getAndAdd IR test no longer fails with this change, and I removed a lot of other redundant changes.

I updated the VarHandleExact benchmark added by @JornVernee, and added a case of dropping return values by changing access mode to getAndAdd consistently. Now they have the following performance numbers:

Benchmark                                        Mode  Cnt  Score   Error  Units
VarHandleExact.exact_exactInvocation             avgt   30  3.843 ± 0.062  ns/op
VarHandleExact.generic_exactInvocation           avgt   30  3.797 ± 0.049  ns/op
VarHandleExact.generic_genericInvocation         avgt   30  3.757 ± 0.034  ns/op
VarHandleExact.generic_returnDroppingInvocation  avgt   30  3.754 ± 0.026  ns/op

liach avatar Dec 02 '25 23:12 liach

Since I just noticed the actual cause of the failure of caching is that AD is created per name+type combination, I have created a benchmark case for that instead of reusing the existing exact ones:

Benchmark                                 Mode  Cnt  Score   Error  Units
VarHandleTypeMismatch.exactInvocation     avgt   30  0.396 ± 0.009  ns/op
VarHandleTypeMismatch.genericInvocation   avgt   30  0.375 ± 0.009  ns/op
VarHandleTypeMismatch.pollutedInvocation  avgt   30  8.281 ± 0.222  ns/op

liach avatar Dec 15 '25 17:12 liach