Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reapply "Optimize OpenJDK VarHandle operation methods" #19566

Merged
merged 2 commits into from
Jun 12, 2024

Conversation

jdmpapin
Copy link
Contributor

This PR reverts #19535, effectively reapplying #19234.

But before that, it fixes two problems in the determination of the address to use when unsafe fast path transforms an access to a static field via VarHandle with OpenJDK VarHandles. Applying these fixes first allows them to be kept separate from the revert commit without reintroducing the bugs between commits.

First, for getAnd{Set,Add}{Int,Long} intrinsics accessing static fields, the address should be

object.vmRef.ramStatics + (offset & ~J9_SUN_FIELD_OFFSET_MASK)

but with OpenJDK VarHandles it would instead be (object + offset), as though for an instance field. So the access would produce an incorrect result and almost certainly corrupt the java/lang/Class instance or something near it in the heap.

Unsafe fast path already knows how to generate code that will use the right address for these static field VarHandle accesses, but it didn't apply to OpenJDK VarHandles because it was looking for a specific recognized method value that will not occur. Now instead it detects static accesses using isUnsafeCallerAccessingStaticField().

Second, transformed get and put operations accessing static fields with OpenJDK VarHandles were using the wrong mask to clear the low bits of the offset, specifically 1 instead of J9_SUN_FIELD_OFFSET_MASK (3). It worked in Java 11 because FieldVarHandle uses lookupField(), which (for static fields) sets J9_SUN_STATIC_FIELD_OFFSET_TAG (1) but never sets J9_SUN_FINAL_FIELD_OFFSET_TAG (2). In Java 17+, a VarHandle representing a static final field does have J9_SUN_FINAL_FIELD_OFFSET_TAG set in its offset field, and clearing only the lowest bit will produce an offset that is off by 2.

Fixes #19532

This commit fixes two problems in the determination of the address to
use when unsafe fast path transforms an access to a static field via
VarHandle with OpenJDK VarHandles. The changes should have no meaningful
effect until unsafe fast path's support for OpenJDK VarHandles is
reinstated in a following commit.

First, for getAnd{Set,Add}{Int,Long} intrinsics accessing static fields,
the address should be

    object.vmRef.ramStatics + (offset & ~J9_SUN_FIELD_OFFSET_MASK)

but with OpenJDK VarHandles it would instead be (object + offset), as
though for an instance field. So the access would produce an incorrect
result and almost certainly corrupt the java/lang/Class instance or
something near it in the heap.

Unsafe fast path already knows how to generate code that will use the
right address for these static field VarHandle accesses, but it didn't
apply to OpenJDK VarHandles because it was looking for a specific
recognized method value that will not occur. Now instead it detects
static accesses using isUnsafeCallerAccessingStaticField().

Second, transformed get and put operations accessing static fields with
OpenJDK VarHandles were using the wrong mask to clear the low bits of
the offset, specifically 1 instead of J9_SUN_FIELD_OFFSET_MASK (3). It
worked in Java 11 because FieldVarHandle uses lookupField(), which (for
static fields) sets J9_SUN_STATIC_FIELD_OFFSET_TAG (1) but never sets
J9_SUN_FINAL_FIELD_OFFSET_TAG (2). In Java 17+, a VarHandle representing
a static final field does have J9_SUN_FINAL_FIELD_OFFSET_TAG set in its
offset field, and clearing only the lowest bit will produce an offset
that is off by 2.
@jdmpapin jdmpapin added comp:jit project:MH Used to track Method Handles related work labels May 28, 2024
@jdmpapin jdmpapin requested a review from dsouzai as a code owner May 28, 2024 15:35
@jdmpapin jdmpapin requested review from 0xdaryl and removed request for dsouzai May 28, 2024 15:35
@jdmpapin
Copy link
Contributor Author

@0xdaryl could you please review?

@pshipton
Copy link
Member

When it comes time for PR testing, pls ensure sanity.openjdk is run, if it hasn't already been done internally. There was quite a bit of fallout from the previous bad PR. It took jenkins machines offline after filling the disk, and delayed testing for the 0.44 release.

@jdmpapin
Copy link
Contributor Author

Oh, sorry, I forgot to mention that. I did run JDK17 sanity.openjdk as part of my own testing, and it was good. I also ran a 5x grinder of jdk_lang_VarHandleTest_j9_[01], which passed. To make sure the grinder was meaningful, I made a build with the revert only, i.e. without my additional fixes, and used it to run another grinder the same way. That one failed all over the place and showed JIT and VM crashes similar to those in #19532

@0xdaryl
Copy link
Contributor

0xdaryl commented Jun 10, 2024

Jenkins test sanity.functional,sanity.openjdk all jdk21

@0xdaryl 0xdaryl self-assigned this Jun 10, 2024
@0xdaryl
Copy link
Contributor

0xdaryl commented Jun 10, 2024

@0xdaryl
Copy link
Contributor

0xdaryl commented Jun 10, 2024

Actually, at least some of those failures have been seen elsewhere, so likely not related to this PR:
#19661

@jdmpapin
Copy link
Contributor Author

I've looked at all of the failures so far, and they're all #19661

Only the windows tests are still running at the moment. I expect to see the same crashes in windows sanity.openjdk

@0xdaryl
Copy link
Contributor

0xdaryl commented Jun 11, 2024

Can you rebase so we pick up the fix for 19661 and I can re-start testing? I will only do the platform/OS combos that failed before.

@jdmpapin
Copy link
Contributor Author

PR builds use refs/pull/<n>/merge, which is the merge of the PR branch and master, e.g. from the AArch64 Linux build:

[2024-06-10T00:22:38.642Z]  > git fetch --tags --progress -- https://github.com/eclipse-openj9/openj9.git +refs/pull/19566/merge:refs/remotes/origin/pr/19566/merge # timeout=10
[2024-06-10T00:22:39.452Z] JENKINS-19022: warning: possible memory leak due to Git plugin usage; see: https://plugins.jenkins.io/git/#remove-git-plugin-buildsbybranch-builddata-script
[2024-06-10T00:22:39.452Z] Checking out Revision 755d0cc95fcaac1e79b8e49bb4feb07c00747647 (refs/remotes/origin/pr/19566/merge)

So the fix will already be included. I fetched it myself to double check:

$ git fetch -- https://github.com/eclipse-openj9/openj9.git +refs/pull/19566/merge:pr19566-merge
$ git log --oneline pr19566-merge --grep='Fix vectorAPI' -2
cf5ff36a71 Merge pull request #19667 from rmnattas/offheap-vector-fix
205aba9e1b Fix vectorAPI address node helper after offheap changes

I might as well restart them now

Jenkins test sanity.openjdk alinux64,amac,aix,xlinux,xmac,zlinux jdk21

@jdmpapin
Copy link
Contributor Author

Both Windows test jobs were aborted

Jenkins test sanity.functional,sanity.openjdk win jdk21

Copy link
Contributor

@0xdaryl 0xdaryl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AIX tests appear to pass despite reported as failing. All other testing has completed and is successful.

@0xdaryl 0xdaryl merged commit 2233a60 into eclipse-openj9:master Jun 12, 2024
22 of 24 checks passed
@pshipton
Copy link
Member

I'm guessing this has caused #19693

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:jit project:MH Used to track Method Handles related work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test failures in VarHandle-related sanity.openjdk components
3 participants