Skip to content

8368274: [lworld] Unsafe.compareAndExchangeFlatValue() wrongly assumes padding bytes are the same for identical value objects#1734

Closed
liach wants to merge 10 commits intoopenjdk:lworldfrom
liach:fix/unsafe-flat-cas
Closed

8368274: [lworld] Unsafe.compareAndExchangeFlatValue() wrongly assumes padding bytes are the same for identical value objects#1734
liach wants to merge 10 commits intoopenjdk:lworldfrom
liach:fix/unsafe-flat-cas

Conversation

@liach
Copy link
Member

@liach liach commented Nov 12, 2025

Use the raw value get as witness, because the flat value get may ignore garbage value and cause infinite loop as a result. Waiting for a test case.


Progress

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

Issue

  • JDK-8368274: [lworld] Unsafe.compareAndExchangeFlatValue() wrongly assumes padding bytes are the same for identical value objects (Bug - P4)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1734

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

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/valhalla/pull/1734.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Nov 12, 2025

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

@openjdk
Copy link

openjdk bot commented Nov 12, 2025

@liach This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8368274: [lworld] Unsafe.compareAndExchangeFlatValue() wrongly assumes padding bytes are the same for identical value objects

Reviewed-by: mcimadamore

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been no new commits pushed to the lworld branch. If another commit should be pushed before you perform the /integrate command, your PR will be automatically rebased. If you prefer to avoid any potential automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the lworld branch, type /integrate in a new comment.

@openjdk openjdk bot changed the title 8368274 8368274: [lworld] Unsafe.compareAndExchangeFlatValue() wrongly assumes padding bytes are the same for identical value objects Nov 12, 2025
@liach liach marked this pull request as ready for review December 8, 2025 16:58
@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 8, 2025
@mlbridge
Copy link

mlbridge bot commented Dec 8, 2025

Webrevs

// compareAndExchange to flattened field in object, non-inline arguments to compare and set
@Test
public Object test70(Object expected, Object x) {
return U.compareAndExchangeFlatValue(this, TEST63_VT_OFFSET, 4, SmallValue.class, expected, x);
Copy link
Member

Choose a reason for hiding this comment

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

Aren't existing tests using compareAndExchangeFlatValue in test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java sufficient? If not, I'd suggest adding your test case there.

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 9, 2026

@liach This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply issue a /touch or /keepalive command to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

}
}
Object[] array = newSpecialArray(valueType, 2, layout);
return compareAndSetFlatValueAsBytes(array, o, offset, layout, valueType, expected, x) ? x : array[0];
Copy link
Member

Choose a reason for hiding this comment

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

This method should return array[0] in all cases.

@TobiHartmann
Copy link
Member

@liach Please un-problem list VarHandleTestMethodHandleAccessValue.java now that JDK-8367346 was closed as duplicate. Thanks.

@liach
Copy link
Member Author

liach commented Jan 17, 2026

Should I keep TestCompareAndExchange any more? I don't know what's the best way to create a C2 test for this.

@TobiHartmann
Copy link
Member

Thanks. I just discussed with @chhagedorn offline and we think that it's sufficient to have VarHandleTestMethodHandleAccessValue.java as regression test that you now un-problem listed. You can remove TestCompareAndExchange. Please verify though that VarHandleTestMethodHandleAccessValue.java now passes.

@liach
Copy link
Member Author

liach commented Jan 19, 2026

Ran the VarHandleTestMethodHandleAccessValue test again with no failure.

putFlatValue(expectedArray, base, layout, valueType, expected);
putFlatValue(xArray, base, layout, valueType, x);

// array 0: witness (to translate to object), 1: x (to translate to raw)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment is hard to read, for a number of reasons:

  • it uses 0/1, but then the code uses base/base + scale (understandably so)
  • translate to object/translate to raw -- yes, x starts off as a value object and we use the array to derive its "raw" representation, whereas witness is always a "raw" value, and stored into the array so we can get it back "as a value". But since this is finicky logic, all this should be spelled out more.
  • the caller can "capture the witness" -- maybe "observe" the (last) witness would be more correct?
  • "we must witness the raw value instead of the value object" -- well, even the old code was witnessing a raw value (of sort) -- the issue is how you compute such a raw value. The fix in this PR is that the raw value is accessed directly from memory (e.g. the content of o at offset offset). E.g. it feels like you are "overloading" what "raw" means -- in some cases you mean "raw == numeric, or !value", in other cases you mean "raw as in -- as accessed from memory"

Copy link
Collaborator

@mcimadamore mcimadamore left a comment

Choose a reason for hiding this comment

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

The code changes look good (a test would be good tho). I left some comments to try and clarify the docs.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jan 21, 2026
@liach
Copy link
Member Author

liach commented Jan 21, 2026

I have updated the comment. Please help proofread again.

// caller pass the array so it can capture the witness if needed
// we must witness the raw value instead of the value object, otherwise
// garbage value can cause failure
// We can convert between a value object and a binary value (of suitable size) using array elements.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Great! Thanks!

@openjdk
Copy link

openjdk bot commented Jan 22, 2026

@liach this pull request can not be integrated into lworld due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout fix/unsafe-flat-cas
git fetch https://git.openjdk.org/valhalla.git lworld
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge lworld"
git push

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Jan 22, 2026
@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Jan 22, 2026
@openjdk openjdk bot added ready Pull request is ready to be integrated and removed merge-conflict Pull request has merge conflict with target branch labels Jan 22, 2026

# valhalla
build/CheckFiles.java 8376088 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessValue.java 8367346 generic-all
Copy link
Member

Choose a reason for hiding this comment

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

This PR's bugID is 8368274 while the ProblemList entry's bugID is 8367346.
It looks like JDK-8367346 is closed as a duplicate of JDK-8368274 so all the
accounting is good here, but I wanted to document what we've done.

@liach
Copy link
Member Author

liach commented Jan 22, 2026

Thanks for the reviews!

/integrate

@openjdk
Copy link

openjdk bot commented Jan 22, 2026

Going to push as commit ccb0ca8.

@openjdk openjdk bot added the integrated Pull request has been integrated label Jan 22, 2026
@openjdk openjdk bot closed this Jan 22, 2026
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jan 22, 2026
@openjdk
Copy link

openjdk bot commented Jan 22, 2026

@liach Pushed as commit ccb0ca8.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integrated Pull request has been integrated

Development

Successfully merging this pull request may close these issues.

5 participants