RFR: 8314480: Memory ordering spec updates in java.lang.ref

Hans Boehm duke at openjdk.org
Mon Nov 27 22:36:09 UTC 2023


On Tue, 21 Nov 2023 22:58:09 GMT, Roger Riggs <rriggs at openjdk.org> 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."_
>
> src/java.base/share/classes/java/lang/ref/Reference.java line 552:
> 
>> 550:      * of this method.
>> 551:      * Invocation of this method does not itself initiate reference processing,
>> 552:      * garbage collection, or finalization.
> 
> My understanding was that it is not the object instance that is being guarded, only that the reference holding the object is considered a strong root and is only used to delimit a range of bytecodes for which the reference is considered to be strong.
> In particular, the invocation of the method itself has no semantics, only that a control flow could reach that statement and the reference was considered strong as long as the reference was in a scope that included the reachability fence.

IMO, the core of the semantics here are that the reachabilityFence() call happens before clearing or enqueueing of any References to the argument. I think it's the call itself, not the end of the argument.s scope (which may not even make sense) that matters here.

Perhaps reachabilityFence(x) should also happen before any objects that are definitely reachable from x (JLS 12.6.2) at that point are cleared or enqueued. That is not completely clear to me, since it impacts the legality of dead field elimination. And it would be nice to get rid of 12.6.2.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/16644#discussion_r1406842978


More information about the core-libs-dev mailing list