mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8271820: Implementation of JEP 416: Reimplement Core Reflection with Method Handle
8013527: calling MethodHandles.lookup on itself leads to errors Co-authored-by: Peter Levart <plevart@openjdk.org> Co-authored-by: Claes Redestad <redestad@openjdk.org> Co-authored-by: Mandy Chung <mchung@openjdk.org> Reviewed-by: mcimadamore, plevart, egahlin, redestad, cjplummer, alanb
This commit is contained in:
parent
5a768f75c9
commit
c6339cb8a2
78 changed files with 6118 additions and 544 deletions
|
@ -26,7 +26,9 @@
|
|||
package java.lang.reflect;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.CallerSensitiveAdapter;
|
||||
import jdk.internal.reflect.MethodAccessor;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
|
@ -67,24 +69,22 @@ import java.util.StringJoiner;
|
|||
* @since 1.1
|
||||
*/
|
||||
public final class Method extends Executable {
|
||||
@Stable
|
||||
private Class<?> clazz;
|
||||
private int slot;
|
||||
private final Class<?> clazz;
|
||||
private final int slot;
|
||||
// This is guaranteed to be interned by the VM in the 1.4
|
||||
// reflection implementation
|
||||
private String name;
|
||||
private Class<?> returnType;
|
||||
private Class<?>[] parameterTypes;
|
||||
private Class<?>[] exceptionTypes;
|
||||
@Stable
|
||||
private int modifiers;
|
||||
private final String name;
|
||||
private final Class<?> returnType;
|
||||
private final Class<?>[] parameterTypes;
|
||||
private final Class<?>[] exceptionTypes;
|
||||
private final int modifiers;
|
||||
// Generics and annotations support
|
||||
private transient String signature;
|
||||
private final transient String signature;
|
||||
// generic info repository; lazily initialized
|
||||
private transient MethodRepository genericInfo;
|
||||
private byte[] annotations;
|
||||
private byte[] parameterAnnotations;
|
||||
private byte[] annotationDefault;
|
||||
private final byte[] annotations;
|
||||
private final byte[] parameterAnnotations;
|
||||
private final byte[] annotationDefault;
|
||||
@Stable
|
||||
private MethodAccessor methodAccessor;
|
||||
// For sharing of MethodAccessors. This branching structure is
|
||||
|
@ -553,20 +553,64 @@ public final class Method extends Executable {
|
|||
@ForceInline // to ensure Reflection.getCallerClass optimization
|
||||
@IntrinsicCandidate
|
||||
public Object invoke(Object obj, Object... args)
|
||||
throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
throws IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
boolean callerSensitive = isCallerSensitive();
|
||||
Class<?> caller = null;
|
||||
if (!override || callerSensitive) {
|
||||
caller = Reflection.getCallerClass();
|
||||
}
|
||||
|
||||
// Reflection::getCallerClass filters all subclasses of
|
||||
// jdk.internal.reflect.MethodAccessorImpl and Method::invoke(Object, Object[])
|
||||
// Should not call Method::invoke(Object, Object[], Class) here
|
||||
if (!override) {
|
||||
checkAccess(caller, clazz,
|
||||
Modifier.isStatic(modifiers) ? null : obj.getClass(),
|
||||
modifiers);
|
||||
}
|
||||
MethodAccessor ma = methodAccessor; // read @Stable
|
||||
if (ma == null) {
|
||||
ma = acquireMethodAccessor();
|
||||
}
|
||||
|
||||
return callerSensitive ? ma.invoke(obj, args, caller) : ma.invoke(obj, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is to support MethodHandle calling caller-sensitive Method::invoke
|
||||
* that may invoke a caller-sensitive method in order to get the original caller
|
||||
* class (not the injected invoker).
|
||||
*
|
||||
* If this adapter is not presented, MethodHandle invoking Method::invoke
|
||||
* will get an invoker class, a hidden nestmate of the original caller class,
|
||||
* that becomes the caller class invoking Method::invoke.
|
||||
*/
|
||||
@CallerSensitiveAdapter
|
||||
private Object invoke(Object obj, Object[] args, Class<?> caller)
|
||||
throws IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
boolean callerSensitive = isCallerSensitive();
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz,
|
||||
Modifier.isStatic(modifiers) ? null : obj.getClass(),
|
||||
modifiers);
|
||||
}
|
||||
MethodAccessor ma = methodAccessor; // read volatile
|
||||
MethodAccessor ma = methodAccessor; // read @Stable
|
||||
if (ma == null) {
|
||||
ma = acquireMethodAccessor();
|
||||
}
|
||||
return ma.invoke(obj, args);
|
||||
|
||||
return callerSensitive ? ma.invoke(obj, args, caller) : ma.invoke(obj, args);
|
||||
}
|
||||
|
||||
@Stable private Boolean callerSensitive; // lazily initialize
|
||||
private boolean isCallerSensitive() {
|
||||
Boolean cs = callerSensitive;
|
||||
if (cs == null) {
|
||||
callerSensitive = cs = Reflection.isCallerSensitive(this);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -672,8 +716,10 @@ public final class Method extends Executable {
|
|||
methodAccessor = tmp;
|
||||
} else {
|
||||
// Otherwise fabricate one and propagate it up to the root
|
||||
tmp = reflectionFactory.newMethodAccessor(this);
|
||||
setMethodAccessor(tmp);
|
||||
tmp = reflectionFactory.newMethodAccessor(this, isCallerSensitive());
|
||||
// set the method accessor only if it's not using native implementation
|
||||
if (VM.isJavaLangInvokeInited())
|
||||
setMethodAccessor(tmp);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue