Trying to fix JDK-8013527 - 1st Prototype
info at j-kuhn.de
Sun Jan 17 17:02:01 UTC 2021
JDK-8013527 has somehow become the umbrella bug for "Using
MethodHandles to call caller sensitive methods leads to interesting
To recap: A caller sensitive method knows about who called it, and can
behave differently when called from an other context.
Examples are: Class.forName, MethodHandles.lookup, Method.invoke...
A MethodHandle on the other hand should not be caller sensitive.
To archive this, a MethodHandle will "bind" the lookup class as caller
for caller sensitive methods.
This is currently done by injecting a hidden class (InjectedInvoker"
that acts as a trampoline for calling caller sensitive methods.
This injected invoker shares many properties of the original caller:
Same ClassLoader, same Module, same Package, same ProtectionDomain, but
it's not the same class or a nestmate of it.
For caller sensitive methods that do look at more than just the injected
invoker, this leads to "unexpected" results when called through a
* MethodHandles.lookup() returns a full privileged lookup for the
* jlr.Field.get*/set*, jlr.Constructor.newInstance, jlr.Method.invoke
may fail with an IllegalAccessException if the target is private. See
After reading one of John Rose's comments, I thought that this might
be a way to solve this general problem.
So I implemented some of it here.
The basic idea is that there is a private overload of the caller
sensitive method which accepts the caller as a tailing argument.
The good news:
* tier1 Tests pass.
* ((Lookup) lookup.findStatic(MethodHandles.class, "lookup",
* JDK-8257874 can't be reproduced with Field.* or Constructor.
* Performance is likely better. (InjectedInvoker collects all arguments
into an Object.)
The bad news:
* If you use a MethodHandle to call Method.invoke for a caller sensitive
method, then you can still observe the injected invoker.
Moving forward, there are 3 ways:
1. Do nothing. Won't fix any bug.
2. Use the current prototype, and accept Method.invoke is odd when
calling it through a MethodHandle.
3. Go all in:
* Require **every** caller sensitive method to have a private overload.
* Method.invoke will also use that private overload.
The problems with the 3rd approach are:
* What about methods that can be called virtually?
* Requires a few changes to MethodAccessor. Maybe implementing
* What about methods that do stack walks?
I have to think more about the problems listed above - but maybe you
have some input that could help me on that.
More information about the core-libs-dev