RFR: 6983726: Reimplement MethodHandleProxies.asInterfaceInstance [v20]

Jorn Vernee jvernee at openjdk.org
Tue Jul 4 21:40:09 UTC 2023


On Tue, 4 Jul 2023 21:00:30 GMT, Mandy Chung <mchung at openjdk.org> wrote:

>> src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java line 324:
>> 
>>> 322:             r = PROXY_LOOKUPS.get(intfc);
>>> 323:         }
>>> 324:         return r.get();
>> 
>> This doesn't look right to me. AFAICT the Lookup can be GC'd before we call `get`.
>> 
>>> No, it wouldn't. PROXY_LOOKUPS.get(intfc) returns the WeakReference of the lookup class which is strongly reachable in the stack frame.
>> 
>> I'm not sure how the lookup class (`intfc` ?) is keeping the `Lookup` alive here?
>
> Sorry I re-read Chen's question and missing the last half of the sentence.   My reply was about:  If the referent is not GC'ed, `r.get()` returns non-null which will be returned to the caller.  If the referent becomes weakly reachable, `r.get()` will return null.
> 
> OK.  In any case, I was thinking to use a local variable to keep the lookup object strongly reachable.   I adjusted the patch to keep a class value of a holder of `WeakReference` ([ab3d8b2](https://github.com/mlchung/jdk/commit/ab3d8b2f086dfac4f8fda1ddce415270c0c53d2b)):
> 
> 
>     private static Lookup getProxyClassLookup(Class<?> intfc) {
>         WeakReferenceHolder<Lookup> r = PROXY_LOOKUPS.get(intfc);
>         Lookup lookup = r.get();
>         if (lookup == null) {
>              // If the referent is cleared, create a new value and update cached weak reference.
>             lookup = newProxyLookup(intfc);
>             r.set(lookup);
>         }
>         return lookup;
>     }

Ok, thanks. This is similar to the solution I would have suggested.

The only thing I'm unsure about is races. ClassValue allows multiple threads to race to compute the final value, but in the end only 1 is chosen that is returned to all threads.

If multiple threads race to create a new proxy lookup here, they will all get a distinct lookup returned to them. I think this is okay? Though, it would mean we have less sharing of proxy classes.

Maybe this code should synchronize on `r` to make sure only 1 lookup is created per interface. (Letting threads race to compute the value is also a possibility, but it also leads some threads to do work that is then discarded, and then the VM has to clean up the class they defined as well).

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

PR Review Comment: https://git.openjdk.org/jdk/pull/13197#discussion_r1252373506


More information about the core-libs-dev mailing list