On Thu, 13 Mar 2025 15:22:43 GMT, Per Minborg <pminb...@openjdk.org> wrote:

>> Implement JEP 502.
>> 
>> The PR passes tier1-tier3 tests.
>
> Per Minborg has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains 246 commits:
> 
>  - Merge branch 'master' into implement-jep502
>  - Clean up exception messages and fix comments
>  - Rename field
>  - Rename method and fix comment
>  - Rework reenterant logic
>  - Use acquire semantics for reading rather than volatile semantics
>  - Add missing null check
>  - Simplify handling of sentinel, wrap, and unwrap
>  - Fix JavaDoc issues
>  - Fix members in StableEnumFunction
>  - ... and 236 more: https://git.openjdk.org/jdk/compare/4e51a8c9...d6e1573f

The example code `class Component` uses a `Supplier` non-static field to hold a 
singular stable value, in a lambda which does not capture `this`.  It may be 
best not to claim a solution (yet) for lazy non-statics, so consider making 
`Component.logger` static.

I'm not saying you should attempt this in the present PR!  But here are some 
related thoughts, for later.

Solving the problem of lazy statics, using stable suppliers, is a big deal.  It 
allows single-static-holder-classes to be refactored more cheaply.

Here's why I think non-static lazy fields are not fully addressed by this PR.  
(A) Their initializer function should probably not capture `this`, for best 
performance, and (B) the VM's special casing of non-static fields of type 
`StableValue` does not extend to fields of type `Supplier`.  (Nor should it.)  
But it seems we either need strict fields, or a JVM lockout of 
instance-supplier fields, to avoid problems with reflective object patching.

You might consider a type `StableSupplier` <: `Supplier` to address (B), but 
unless (A) is addressed as well there is not an efficient end-to-end solution 
for lazy non-statics.

(B) will also be addressed (independently) by strict statics.

A full solution might require an indexed version of Supplier (i.e., a 
restricted Function) which takes `this` whenever needed to evaluate the lazily 
supplied value.  So there's some cross-connection with the design of stable 
functions in this PR.

(A stable function which caches one value seems useless, but it exactly fits 
the use case of a non-static lazy object attribute.  The argument to the 
function is `this`.  That's the only argument the instance-supplier will ever 
see.  Every distinct instance of an instance-supplier will only ever see one 
instance of `this` as its argument value.)


class Component {
  private strict final
      StableInstanceSupplier<Compenent,Logger>
          instanceSpecificLogger = StableValue.instanceSupplier(
              self -> Logger.getLogger(Component.class, self.getName() );
}


In today's API you can get this effect but you have redundant bindings of 
`this` buried in the supplier structure.  As other PR threads have pointed out, 
it's hard to drop the lambda after its invocation, so as to GC the storage of 
the bindings.

OTOH, maybe there are more reasons we can't get rid of `this`.  If so, maybe we 
have arrived at a final state for problem (A): the lambda has to capture 
`this`, so be it.  But if that's true, we still want a story for problem (B) as 
well (non-strictness of instance fields).

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

PR Comment: https://git.openjdk.org/jdk/pull/23972#issuecomment-2727157600

Reply via email to