jdk
jdk copied to clipboard
8314480: Memory ordering spec updates in java.lang.ref
Classes in the java.lang.ref
package would benefit from an update to bring the spec in line with how the VM already behaves. The changes would focus on happens-before edges at some key points during reference processing.
A couple key things we want to be able to say are:
-
Reference.reachabilityFence(x)
happens-before reference processing occurs for 'x'. -
Cleaner.register()
happens-before the Cleaner thread runs the registered cleaning action.
This will bring Cleaner in line (or close) with the memory visibility guarantees made for finalizers in JLS 17.4.5: "There is a happens-before edge from the end of a constructor of an object to the start of a finalizer (§12.6) for that object."
Progress
- [x] Change must be properly reviewed (1 review required, with at least 1 Reviewer)
- [x] Change must not contain extraneous whitespace
- [ ] Change requires CSR request JDK-8327707 to be approved
- [x] Commit message must refer to an issue
Issues
- JDK-8314480: Memory ordering spec updates in java.lang.ref (Bug - P4)
- JDK-8327707: Memory ordering spec updates in java.lang.ref (CSR)
Reviewers
- David Holmes (@dholmes-ora - Reviewer) ⚠️ Review applies to 0f949d3c
- Alan Bateman (@AlanBateman - Reviewer)
Reviewing
Using git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16644/head:pull/16644
$ git checkout pull/16644
Update a local copy of the PR:
$ git checkout pull/16644
$ git pull https://git.openjdk.org/jdk.git pull/16644/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 16644
View PR using the GUI difftool:
$ git pr show -t 16644
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16644.diff
Webrev
:wave: Welcome back bchristi! 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.
⚠️ @bchristi-git This pull request contains merges that bring in commits not present in the target repository. Since this is not a "merge style" pull request, these changes will be squashed when this pull request in integrated. If this is your intention, then please ignore this message. If you want to preserve the commit structure, you must change the title of this pull request to Merge <project>:<branch>
where <project>
is the name of another project in the OpenJDK organization (for example Merge jdk:master
).
@bchristi-git The following label will be automatically applied to this pull request:
-
core-libs
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.
Webrevs
- 34: Full - Incremental (cf0dc3b8)
- 33: Full - Incremental (e02bf98e)
- 32: Full - Incremental (33334d06)
- 31: Full (d7cbf0d3)
- 30: Full - Incremental (4efa5d18)
- 29: Full - Incremental (5db47889)
- 28: Full - Incremental (a41e6fc2)
- 27: Full - Incremental (5f90b5d8)
- 26: Full - Incremental (77d53818)
- 25: Full - Incremental (0b9d3efc)
- 24: Full - Incremental (16fcc764)
- 23: Full - Incremental (cc21d296)
- 22: Full - Incremental (27d0c249)
- 21: Full - Incremental (91d4db48)
- 20: Full - Incremental (bdac5cce)
- 19: Full - Incremental (170c9814)
- 18: Full - Incremental (4648d064)
- 17: Full - Incremental (0748ed04)
- 16: Full - Incremental (54a44414)
- 15: Full - Incremental (15ae0f25)
- 14: Full - Incremental (3df288a5)
- 13: Full - Incremental (80a3973a)
- 12: Full - Incremental (4d6f1dce)
- 11: Full - Incremental (603ff4dc)
- 10: Full - Incremental (855b13a8)
- 09: Full - Incremental (adb1fbe3)
- 08: Full - Incremental (0f949d3c)
- 07: Full - Incremental (1ca169ec)
- 06: Full - Incremental (7eb3397c)
- 05: Full - Incremental (3647f64a)
- 04: Full - Incremental (9b4b1150)
- 03: Full - Incremental (c09db360)
- 02: Full - Incremental (05477522)
- 01: Full - Incremental (84d8b61f)
- 00: Full (dfce0dd5)
/label add hotspot-gc
@bchristi-git
The hotspot-gc
label was successfully added.
@bchristi-git 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 add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!
@bchristi-git 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:
8314480: Memory ordering spec updates in java.lang.ref
Reviewed-by: dholmes, alanb, darcy
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 104 new commits pushed to the master
branch:
- 8aeada105acd143b38b02123377ef86513eee266: 8331159: VM build without C2 fails after JDK-8180450
- e99f6a65a8307e6b31a08a677914dfd20d46687f: 8333236: Test java/foreign/TestAccessModes.java is timing out after passing
- e650bdf4654a0459bb2af95f08ba42ca870642d4: 8332507: compilation result depends on compilation order
- e4fbb15c6a7b18f1ec66176080404818d3871194: 8320215: HeapDumper can use DumpWriter buffer during merge
- 681137cad2b1de8a0af1dfea949439bcaf5e7500: 8333131: Source launcher should work with service loader SPI
- 914423e3b7162ad934fa4edc46ee37e0f401d27b: 8332899: RISC-V: add comment and make the code more readable (if possible) in MacroAssembler::movptr
- 5abc02927b480a85fadecf8d03850604510276e4: 8331877: JFR: Remove JIInliner framework
- d9e7b7e7da98a0170d26301a4bbd61aad0127c6e: 8210471: GZIPInputStream constructor could leak an un-end()ed Inflater
- 1e04ee6d57d5fe84e1d202b16e8d13dc13c002ff: 8331579: Reference to primitive type fails without error or warning
- 32ee252c455d3ddcb5954698b546ac39a40515e8: 8333169: javac NullPointerException record.type
- ... and 94 more: https://git.openjdk.org/jdk/compare/7bf1989f59695c3d08b4bd116fb4c022cf9661f4...master
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.
➡️ To integrate this PR with the above commit message to the master
branch, type /integrate in a new comment.
@bchristi-git Made a suggestion, but beyond that this looks great to me. Thanks for putting this together!
/csr
@AlanBateman has indicated that a compatibility and specification (CSR) request is needed for this pull request.
@bchristi-git please create a CSR request for issue JDK-8314480 with the correct fix version. This pull request cannot be integrated until the CSR request is approved.
Mailing list message from Hans Boehm on core-libs-dev:
Is it worth keeping the discussion starting with "It is sometimes possible to better encapsulate ..." and the associated example code? I find this example extremely unconvincing. It's very hard to construct a case in which you can safely use the result of getExternalResource(). And I don't want to encourage writing getters for things like this; if you use them from a static method, or somebody decides to make it public, things get really messy really quickly.
This example kind of gives the impression that we have a solution to reachabilityFence() proliferation. I don't think we do. There may be a difference of opinion about whether it's worth fixing, but I don't think we should deny the existence of the problem.
On Thu, Mar 21, 2024 at 7:11?PM David Holmes <dholmes at openjdk.org> wrote:
-------------- next part -------------- An HTML attachment was scrubbed... URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240321/c956dca0/attachment-0001.htm>
AFAICT, all review feedback on this change has been addressed. I would love to have some reviewers take another look. Thanks!
Thanks Brent, I have no objections. Good job!
Mailing list message from Hans Boehm on core-libs-dev:
I'm not convinced this helps.
The isAlive() spec says:
"A thread is alive if it has been started and has not yet terminated."
Clearly an object is reachable if it can be accessed by a thread that will be started in the future. Is that part of a "potential continuing computation from any live thread"?
I think the JLS wording is a bit sloppy about what "live thread" means here. And that sloppiness is probably better than pointing at a precise definition that I'm not sure really applies. "in any potential continuing computation from any live thread" really seems to mean something like "in any continuing computation in which no finalizers are run"?
Even if the object is later accessed from an existing "live" thread, it should not be considered reachable if that happens only after a finalizer later makes it reachable again. So I don't see why the thread from which the access happens matters at all.
Hans
On Thu, May 9, 2024 at 11:44?AM Brent Christian <bchristi at openjdk.org> wrote:
-------------- next part -------------- An HTML attachment was scrubbed... URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240510/59fbaa88/attachment.htm>
Mailing list message from Brent Christian on core-libs-dev:
On 5/10/24 10:54 AM, Hans Boehm wrote:
I'm not convinced this helps.
The isAlive() spec says:
"A thread is alive if it has been started and has not yet terminated."
Clearly an object is reachable if it can be accessed by a thread that will be started in the future. Is that part of a "potential continuing computation from any live thread"?
I would think; one "computation" a live thread can perform is to start another thread, which in turn might access the object.
I think the JLS wording is a bit sloppy about what "live thread" means here. And that sloppiness is probably better than pointing at a precise definition that I'm not sure really applies.
"in any potential continuing computation from any live thread" really seems to mean something like "in any continuing computation in which no finalizers are run"?
Once an object becomes finalizer-reachable, it can only be reached via a running finalizer. (JLS 12.6.1: "A finalizer-reachable object can be reached from some finalizable object through some chain of references, but not from any live thread.")
So maybe finalizer threads should not be considered "live" threads.
Even if the object is later accessed from an existing "live" thread, it should not be considered reachable if that happens only after a finalizer later makes it reachable again.
Agreed - if an object can (*and only can*) be accessed again after a finalizer resurrects it, that doesn't count as "reachable". In fact, at that point, the object must have transitioned from reachable to finalizer-reachable.
If an object gets resurrected by a finalizer, it does become reachable again and can again be accessed by the program. (And of course if the object's own finalizer ran, it won't run again if the object again stops being reachable.)
So I don't see why the thread from which the access happens matters at all.
I think it would only matter for accesses from a finalizer thread.
-Brent
Mailing list message from Hans Boehm on core-libs-dev:
On Mon, May 13, 2024 at 12:16?PM Brent Christian <brent.christian at oracle.com> wrote:
On 5/10/24 10:54 AM, Hans Boehm wrote:
I'm not convinced this helps.
The isAlive() spec says:
"A thread is alive if it has been started and has not yet terminated."
Clearly an object is reachable if it can be accessed by a thread that will be started in the future. Is that part of a "potential continuing computation from any live thread"?
I would think; one "computation" a live thread can perform is to start another thread, which in turn might access the object.
I think the JLS wording is a bit sloppy about what "live thread" means here. And that sloppiness is probably better than pointing at a precise definition that I'm not sure really applies.
"in any potential continuing computation from any live thread" really seems to mean something like "in any continuing computation in which no finalizers are run"?
Once an object becomes finalizer-reachable, it can only be reached via a running finalizer. (JLS 12.6.1: "A finalizer-reachable object can be reached from some finalizable object through some chain of references, but not from any live thread.")
So maybe finalizer threads should not be considered "live" threads.
Even if the object is later accessed from an existing "live" thread, it should not be considered reachable if that happens only after a finalizer later makes it reachable again.
Agreed - if an object can (*and only can*) be accessed again after a finalizer resurrects it, that doesn't count as "reachable". In fact, at that point, the object must have transitioned from reachable to finalizer-reachable.
If an object gets resurrected by a finalizer, it does become reachable again and can again be accessed by the program. (And of course if the object's own finalizer ran, it won't run again if the object again stops being reachable.)
So I don't see why the thread from which the access happens matters at all.
I think it would only matter for accesses from a finalizer thread.
I'm arguing that even that doesn't matter. Let's say B is reachable from A, and A has a finalizer. Whether B is accessed directly by the finalizer from the finalizer thread, or the finalizer invokes some parallel algorithm on A, so that B is accessed by a helper "live thread" shouldn't matter. What does matter is that neither A nor B are reachable before the finalizer runs, because they can only be accessed as the result of a finalizer running.
I now wonder whether "A <em>reachable</em> object is any object that can be accessed in any potential continuing computation before any additional finalizers are started." wouldn't actually be a much better way to state this. (Officially, this wording is presumably nearly obsolete, since I don't think Cleaners or References have this particular issue. OTOH, that would also make it much clearer that this is so, and post finalizers, there is no issue here.)
Hans
-Brent
-------------- next part -------------- An HTML attachment was scrubbed... URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240513/874c0d98/attachment.htm>
@bchristi-git Just checking in—we're waiting for CSR-approval here before integrating? 🤔
@bchristi-git Just checking in—we're waiting for CSR-approval here before integrating? 🤔
Indeed - can't move forward without a CSR. Also wouldn't mind more reviewer ✔️s. 😉
Indeed - can't move forward without a CSR. Also wouldn't mind more reviewer ✔️s. 😉
I can do that. One other thing to do is to rebase the changes, it looks like this branch is 6 months behind main line.
@AlanBateman @stuart-marks Any final words before @bchristi-git gets to do the honors of integrating? :)
/integrate
Going to push as commit 2cae9a0397f4e46c6faec0a998ecad1c7015564d.
Since your change was applied there have been 105 commits pushed to the master
branch:
- 9fd0e7349ebf4a49b5c0c7a16c866b5b8e626b53: 8332110: [macos] jpackage tries to sign added files without the --mac-sign option
- 8aeada105acd143b38b02123377ef86513eee266: 8331159: VM build without C2 fails after JDK-8180450
- e99f6a65a8307e6b31a08a677914dfd20d46687f: 8333236: Test java/foreign/TestAccessModes.java is timing out after passing
- e650bdf4654a0459bb2af95f08ba42ca870642d4: 8332507: compilation result depends on compilation order
- e4fbb15c6a7b18f1ec66176080404818d3871194: 8320215: HeapDumper can use DumpWriter buffer during merge
- 681137cad2b1de8a0af1dfea949439bcaf5e7500: 8333131: Source launcher should work with service loader SPI
- 914423e3b7162ad934fa4edc46ee37e0f401d27b: 8332899: RISC-V: add comment and make the code more readable (if possible) in MacroAssembler::movptr
- 5abc02927b480a85fadecf8d03850604510276e4: 8331877: JFR: Remove JIInliner framework
- d9e7b7e7da98a0170d26301a4bbd61aad0127c6e: 8210471: GZIPInputStream constructor could leak an un-end()ed Inflater
- 1e04ee6d57d5fe84e1d202b16e8d13dc13c002ff: 8331579: Reference to primitive type fails without error or warning
- ... and 95 more: https://git.openjdk.org/jdk/compare/7bf1989f59695c3d08b4bd116fb4c022cf9661f4...master
Your commit was automatically rebased without conflicts.
@bchristi-git Pushed as commit 2cae9a0397f4e46c6faec0a998ecad1c7015564d.
:bulb: You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.