JDK-6824466 java.lang.reflect.Method should use java.lang.invoke.MethodHandle
Johannes Kuhn
info at j-kuhn.de
Tue Feb 2 10:52:12 UTC 2021
Thanks Alan.
For using MethodHandles and @CS methods: As far as I remember,
MethodHandle is also skipped on a stack walk for security. In my
prototype (where I did always use MethodHandles for Method.invoke)
MethodHandles.class.findStatic("lookup").invoke(null) did return a
Lookup with the right lookup class.
So, MethodHandles as implementation works - if all classes on the stack
extend MethodAccessorImpl or MethodHandle.
I did a prototype in the past to use an overload for @CS methods [1]
While C2 could link to the overload directly, this is not needed in my
prototype.
The roadblock I hit was that Method.invoke is itself @CS, so either the
Method.invoke overload will have to inject a frame for the caller or all
@CS methods need to have their overload. (And the overload for
Method.invoke needs it's own intrinsic, so it's skipped during security
stack walk.)
The other problem with regard to @CS is Thread.getContextClassLoader().
This method can be virtually called. But a private overload would bypass
the any override.
Currently, java.lang.invoke will bind the caller if the called method is
named "getContextClassLoader" and the method is in an interface.
Things get interesting if you consider this interface:
interface GetCCLObject {Object getContextClassLoader();}
javac will now add a bridge method if you extend Thread and implement
this interface - which calls the @CS method. And that class is now the
caller.
Not exactly sure what my conclusion is, but I tend to "if you implement
such an interface, you are out of luck".
(That's the point my head starts to hurt.)
In the end - Loom has an other implementation of JDK-6824466. Makes 4.
Interesting is that they all have been born out of different
requirements - so it seems indeed to be a good idea.
In my prototype I did fell into the trap that I tried too much at once.
And @CS is a really complex topic that might be attractive to somehow
squeeze into JDK-6824466. But I'm not convinced that this is a good idea.
- Johannes
[1]:
https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-January/073184.html
On 02-Feb-21 11:07, Alan Bateman wrote:
> On 01/02/2021 15:19, Johannes Kuhn wrote:
>> :
>>
>> 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.
> As things stands, virtual threads don't call through the VM because of
> the potential for blocking with a native trampoline frame on the stack.
> The bytecode generator is still used for @CS methods but otherwise it
> uses method handles. Hidden classes should be okay although we don't
> have tests for that yet. In any case, this will all be replaced once
> Mandy's work is further along. Core reflection usages during initPhase2
> can be dealt it by deferral until the module system is fully initialized
> (as Mandy suggests) as using invoke count would be too fragile. For @CS
> methods you will see linked issues where the suggestion to link to an
> overloaded method that takes the caller class has been suggested. I also
> suspect there will be some C2 work needed.
>
> -Alan
More information about the core-libs-dev
mailing list