8160821: VarHandle accesses are penalized when argument conversion is required
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
- Jorn Vernee (@JornVernee - Reviewer) 🔄 Re-review required (review applies to d734e8a6)
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
: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.
@liach This change is no longer ready for integration - check the PR body for details.
@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.
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.
Webrevs
- 10: Full - Incremental (1d5461db)
- 09: Full - Incremental (f9d808c1)
- 08: Full - Incremental (d734e8a6)
- 07: Full - Incremental (eebb8ff7)
- 06: Full - Incremental (8200fb28)
- 05: Full - Incremental (ff7b3629)
- 04: Full - Incremental (89e21b4b)
- 03: Full - Incremental (d49ad129)
- 02: Full - Incremental (7bcdcbf3)
- 01: Full - Incremental (886d3918)
- 00: Full (522cbe9d)
/cc hotspot-compiler
@liach
The hotspot-compiler label was successfully added.
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.
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
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