Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]
On Mon, May 13, 2024 at 12:16 PM Brent Christian 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 reachable 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 >
Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]
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
Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]
On Thu, 9 May 2024 18:44:10 GMT, Brent Christian wrote: >> 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](https://docs.oracle.com/javase/specs/jls/se18/html/jls-17.html#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."_ > > Brent Christian has updated the pull request incrementally with one > additional commit since the last revision: > > add link to Thread.isAlive() You've addressed my comments, I don't have anything else. - Marked as reviewed by alanb (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/16644#pullrequestreview-2052249974
Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]
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 wrote: > > 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]( > https://docs.oracle.com/javase/specs/jls/se18/html/jls-17.html#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."_ > > Brent Christian has updated the pull request incrementally with one > additional commit since the last revision: > > add link to Thread.isAlive() > > - > > Changes: > - all: https://git.openjdk.org/jdk/pull/16644/files > - new: https://git.openjdk.org/jdk/pull/16644/files/5db47889..4efa5d18 > > Webrevs: > - full: https://webrevs.openjdk.org/?repo=jdk=16644=30 > - incr: https://webrevs.openjdk.org/?repo=jdk=16644=29-30 > > Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod > Patch: https://git.openjdk.org/jdk/pull/16644.diff > Fetch: git fetch https://git.openjdk.org/jdk.git > pull/16644/head:pull/16644 > > PR: https://git.openjdk.org/jdk/pull/16644 >
Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]
> 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](https://docs.oracle.com/javase/specs/jls/se18/html/jls-17.html#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."_ Brent Christian has updated the pull request incrementally with one additional commit since the last revision: add link to Thread.isAlive() - Changes: - all: https://git.openjdk.org/jdk/pull/16644/files - new: https://git.openjdk.org/jdk/pull/16644/files/5db47889..4efa5d18 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk=16644=30 - incr: https://webrevs.openjdk.org/?repo=jdk=16644=29-30 Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/16644.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/16644/head:pull/16644 PR: https://git.openjdk.org/jdk/pull/16644