On Fri, 11 Apr 2025 08:51:56 GMT, Aleksey Shipilev <sh...@openjdk.org> wrote:

>> I think it would be "easier" to shift `@IntrinsicCandidate` to a private 
>> `Reference.getImpl/get0` pair of methods, and intrinsify one of those 
>> instead. Pretty much like current `clear` and `refersTo` are doing it now. 
>> And it would be in line with what Kim is doing in this PR anyway.
>
> On a second thought, I think we should do this shift before this PR, so that 
> it is cleanly backportable. This bug messes with concurrent GC invariants, so 
> it would be nice to fix it in current LTSes.

As far as I can tell, intrinsic selection only applies when the call target is
exactly the intrinsically attributed method. (Possibly after optimizations
that lead to a call to that specific method.) And that's obviously necessary
for correctness of applying intrinsics.

The documentation for `@IntrinsicCandidate` suggests it is "better to make
intrinsics be static methods", but non-static methods are certainly permitted,
and I've found several. In particular, the method in question,
`Reference::get`, has been a virtual intrinsic with at least three
(non-intrinsic) overrides (SoftReference, PhantomReference, and
FinalReference) for a long time.

I did a bit of experimenting, and as far as I can tell, everything works as
expected.  Reference::get is already registered as having
vmIntrinsics::_Reference_get as it's intrinsic_id, and that intrinsic id is
handled by the various code processors, such as being in the dispatch table
that @vnkozlov refreenced.

All of Reference::get, Reference::refersTo, and Reference::clear are subtly
different in the details of how they are implemented and intrinsified, because
there are differences among them.

refersTo is final, but needs different implementations for Reference and
PhantomReference. That distinction is handled via nonpublic virtual
refersToImpl. And those are implemented in terms of separate intrinsified
private native methods because we found that C2 handling of intrinsified
virtual native methods had problems.  If not for that issue, the refersToImpl
methods would be intrinsified virtual native methods.

Reference::clear also needs clearImpl, but for a different reason. There are
places where we want to directly call the implementation of Reference::clear,
ignoring any overrides by derived application classes. That is accomplished by
calling the virtual clearImpl, which has implementations in Reference and
PhantomReference. And the clearImpls are implemented in terms of separate
intrinsified private native methods because of the above mentioned C2 issue.

The native implementations for clear call the same JVM_ReferenceClear helper
function, which uses unknown_referent_no_keepalive to handle the distinction
between weak and phantom strengths.  If we just had the native implementation
we could drop the PhantomReference override.  But this operation also has
intrinsic support, and the intrinsic makes use of the known strength.

Reference::get already has long-standing intrinsic support.  The only thing
being changed here is the ordinary definition of that method.  It needs to
remain virtual, so we don't want to make it directly native, because of the
above mentioned C2 issue.  So we make it call a private native helper
function.  This method is not applicable to either PhantomReference or
FinalReference, as they provide their own implementations, so the native
implementation only needs to support weak strength.

For Reference::get we don't need a separate virtual getImpl.  The reasons for
the xxxImpl methods for refersTo and clear don't apply here.  We could move
the intrinsification from Reference::get to to private native Reference::get0
(without an intervening Impl), to more closely correspond to refersTo and
clear (where the intrinsics are the associated private native methods).  But
that would require renaming the intrinsic id for consistency with the name of
the intrinsified method, and other renamings as well.  I'd considered doing
that initially, but decided that was a bunch of code churn with no benefit.

So in summary, I don't think any changes to this PR are needed based on this
comment thread (at least so far).

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

PR Review Comment: https://git.openjdk.org/jdk/pull/24315#discussion_r2039137923

Reply via email to