JDK-6824466 java.lang.reflect.Method should use java.lang.invoke.MethodHandle

Johannes Kuhn info at j-kuhn.de
Mon Feb 1 15:19:54 UTC 2021



On 01-Feb-21 15:58, Remi Forax wrote:
> ----- Mail original -----
>> De: "Johannes Kuhn" <info at j-kuhn.de>
>> À: "core-libs-dev" <core-libs-dev at openjdk.java.net>
>> Envoyé: Lundi 1 Février 2021 15:50:51
>> Objet: JDK-6824466 java.lang.reflect.Method should use java.lang.invoke.MethodHandle
> 
>> While implementing a prototype for JDK-8242888 (Convert dynamic proxy to
>> hidden classes) I came across the problem that hidden classes can't be
>> mentioned in the constant pool, breaking the constructor for serialization.
>>
>> To remedy that problem, I used a MHConstructorAccessor which delegates
>> the actual work to MethodHandles - not unlike what JDK-6824466 suggests.
>>
>> As there has been previous work in that area, (I am aware of at least 3
>> independently developed prototypes for that bug/enchantment) I would
>> like to ask a few questions around it:
>>
>>
>>
>> 1) What are the challenges?
>>
>>  From the bug I could infer, that it's cold start is slower than
>> NativeMethodAccessor, but still faster than the generated (bytecode
>> spinning) accessors.
>>
>> 2) Are there any roadblocks that prevent replacing the
>> MethodAccessorGenerator with accessors that use MethodHandles?
>>
>>  From my limited tests, it appears to work well enough.
>>
>> 3) Should I try to implement it?
>>
>>
>>
>>  From my POV, replacing MethodAccessorGenerator with accessors that
>> delegate to MethodHandles has a few benefits:
>>
>> * Support for hidden classes. (Currently fallback to native accessors)
>> * Removal of MethodAccessorGenerator (which is old and clunky)
> 
> Hi Johannes,
> the native accessors doesn't play with loom (a C stack frame in the middle of the Java stack can not be moved) so it doesn't seem to be a good idea to rely on the native accessors for hidden classes.
> 
>>
>> - Johannes
> 
> Rémi
> 


Thanks Rémi.

The problem here is that (according to Peter Levart tests), the cold use 
of a MHMethodAccessor is 11x as expensive as using the native accessor.

In some way, it sill makes sense to keep the native accessor around, at 
least during startup. On the other hand, I heard that there have been 
some improvements on the AppCDS w.r.t MethodHandles, but I'm out of the 
loop there.

An other problem with completely replacing the native accessors is some 
bootstrap problem - if certain flags are set (some of them are used to 
build the CDS), then the java.lang.invoke infrastructure tries to write 
stuff to System.out. But to initialize System.out, the charset has to be 
constructed, which relies on reflection.

I can see some potential in improving the initialization of the standard 
charset, but it's out of the scope here.

Apropos scope: I try to narrow the scope down to "replace 
MethodAccessorGenerator with accessors that delegate to MethodHandles".
Once this is done, then additional improvements can be made - including 
some that take loom into account. Or adding some @Stable/@ForceInline 
stuff so the JIT can better optimize reflective calls.

But currently (didn't look into the loom source) there are only two 
strategies: Native accessor (bad for loom) or generated (bytecode 
spinning, doesn't work with hidden classes). So, with loom and hidden 
classes you get the worst of both worlds. MethodHandles solve that.

- Johannes


More information about the core-libs-dev mailing list