Re: RFR: 8314480: Memory ordering spec updates in java.lang.ref [v31]

2024-05-13 Thread Hans Boehm
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]

2024-05-13 Thread Brent Christian

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]

2024-05-13 Thread Alan Bateman
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]

2024-05-10 Thread Hans Boehm
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]

2024-05-09 Thread Brent Christian
> 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