mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8340456: Reduce overhead of proxying Object methods in ProxyGenerator
Reviewed-by: liach
This commit is contained in:
parent
5d611c0377
commit
a50440fadc
3 changed files with 55 additions and 75 deletions
|
@ -114,11 +114,18 @@ final class ProxyGenerator {
|
|||
private static final Method OBJECT_EQUALS_METHOD;
|
||||
private static final Method OBJECT_TO_STRING_METHOD;
|
||||
|
||||
private static final String OBJECT_HASH_CODE_SIG;
|
||||
private static final String OBJECT_EQUALS_SIG;
|
||||
private static final String OBJECT_TO_STRING_SIG;
|
||||
|
||||
static {
|
||||
try {
|
||||
OBJECT_HASH_CODE_METHOD = Object.class.getMethod("hashCode");
|
||||
OBJECT_HASH_CODE_SIG = OBJECT_HASH_CODE_METHOD.toShortSignature();
|
||||
OBJECT_EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
|
||||
OBJECT_EQUALS_SIG = OBJECT_EQUALS_METHOD.toShortSignature();
|
||||
OBJECT_TO_STRING_METHOD = Object.class.getMethod("toString");
|
||||
OBJECT_TO_STRING_SIG = OBJECT_TO_STRING_METHOD.toShortSignature();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new NoSuchMethodError(e.getMessage());
|
||||
}
|
||||
|
@ -446,9 +453,9 @@ final class ProxyGenerator {
|
|||
* java.lang.Object take precedence over duplicate methods in the
|
||||
* proxy interfaces.
|
||||
*/
|
||||
addProxyMethod(new ProxyMethod(OBJECT_HASH_CODE_METHOD, "m0"));
|
||||
addProxyMethod(new ProxyMethod(OBJECT_EQUALS_METHOD, "m1"));
|
||||
addProxyMethod(new ProxyMethod(OBJECT_TO_STRING_METHOD, "m2"));
|
||||
addProxyMethod(new ProxyMethod(OBJECT_HASH_CODE_METHOD, OBJECT_HASH_CODE_SIG, "m0"));
|
||||
addProxyMethod(new ProxyMethod(OBJECT_EQUALS_METHOD, OBJECT_EQUALS_SIG, "m1"));
|
||||
addProxyMethod(new ProxyMethod(OBJECT_TO_STRING_METHOD, OBJECT_TO_STRING_SIG, "m2"));
|
||||
|
||||
/*
|
||||
* Accumulate all of the methods from the proxy interfaces.
|
||||
|
@ -526,7 +533,7 @@ final class ProxyGenerator {
|
|||
return;
|
||||
}
|
||||
}
|
||||
sigmethods.add(new ProxyMethod(m, sig, m.getSharedParameterTypes(), returnType,
|
||||
sigmethods.add(new ProxyMethod(m, sig, returnType,
|
||||
exceptionTypes, fromClass, "m" + proxyMethodCount++));
|
||||
}
|
||||
|
||||
|
@ -617,11 +624,11 @@ final class ProxyGenerator {
|
|||
Label failLabel = cob.newLabel();
|
||||
ClassEntry mhl = cp.classEntry(CD_MethodHandles_Lookup);
|
||||
ClassEntry iae = cp.classEntry(CD_IllegalAccessException);
|
||||
cob.aload(cob.parameterSlot(0))
|
||||
cob.aload(0)
|
||||
.invokevirtual(cp.methodRefEntry(mhl, cp.nameAndTypeEntry("lookupClass", MTD_Class)))
|
||||
.ldc(proxyCE)
|
||||
.if_acmpne(failLabel)
|
||||
.aload(cob.parameterSlot(0))
|
||||
.aload(0)
|
||||
.invokevirtual(cp.methodRefEntry(mhl, cp.nameAndTypeEntry("hasFullPrivilegeAccess", MTD_boolean)))
|
||||
.ifeq(failLabel)
|
||||
.invokestatic(CD_MethodHandles, "lookup", MTD_MethodHandles$Lookup)
|
||||
|
@ -629,7 +636,7 @@ final class ProxyGenerator {
|
|||
.labelBinding(failLabel)
|
||||
.new_(iae)
|
||||
.dup()
|
||||
.aload(cob.parameterSlot(0))
|
||||
.aload(0)
|
||||
.invokevirtual(cp.methodRefEntry(mhl, cp.nameAndTypeEntry("toString", MTD_String)))
|
||||
.invokespecial(cp.methodRefEntry(iae, exInit))
|
||||
.athrow()
|
||||
|
@ -650,18 +657,16 @@ final class ProxyGenerator {
|
|||
private final Method method;
|
||||
private final String shortSignature;
|
||||
private final Class<?> fromClass;
|
||||
private final Class<?>[] parameterTypes;
|
||||
private final Class<?> returnType;
|
||||
private final String methodFieldName;
|
||||
private Class<?>[] exceptionTypes;
|
||||
private final FieldRefEntry methodField;
|
||||
|
||||
private ProxyMethod(Method method, String sig, Class<?>[] parameterTypes,
|
||||
private ProxyMethod(Method method, String sig,
|
||||
Class<?> returnType, Class<?>[] exceptionTypes,
|
||||
Class<?> fromClass, String methodFieldName) {
|
||||
this.method = method;
|
||||
this.shortSignature = sig;
|
||||
this.parameterTypes = parameterTypes;
|
||||
this.returnType = returnType;
|
||||
this.exceptionTypes = exceptionTypes;
|
||||
this.fromClass = fromClass;
|
||||
|
@ -670,14 +675,17 @@ final class ProxyGenerator {
|
|||
cp.nameAndTypeEntry(methodFieldName, CD_Method));
|
||||
}
|
||||
|
||||
private Class<?>[] parameterTypes() {
|
||||
return method.getSharedParameterTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new specific ProxyMethod with a specific field name
|
||||
*
|
||||
* @param method The method for which to create a proxy
|
||||
*/
|
||||
private ProxyMethod(Method method, String methodFieldName) {
|
||||
this(method, method.toShortSignature(),
|
||||
method.getSharedParameterTypes(), method.getReturnType(),
|
||||
private ProxyMethod(Method method, String sig, String methodFieldName) {
|
||||
this(method, sig, method.getReturnType(),
|
||||
method.getSharedExceptionTypes(), method.getDeclaringClass(), methodFieldName);
|
||||
}
|
||||
|
||||
|
@ -685,17 +693,18 @@ final class ProxyGenerator {
|
|||
* Generate this method, including the code and exception table entry.
|
||||
*/
|
||||
private void generateMethod(ClassBuilder clb) {
|
||||
var desc = methodTypeDesc(returnType, parameterTypes);
|
||||
var desc = methodTypeDesc(returnType, parameterTypes());
|
||||
int accessFlags = (method.isVarArgs()) ? ACC_VARARGS | ACC_PUBLIC | ACC_FINAL
|
||||
: ACC_PUBLIC | ACC_FINAL;
|
||||
var catchList = computeUniqueCatchList(exceptionTypes);
|
||||
clb.withMethod(method.getName(), desc, accessFlags, mb ->
|
||||
mb.with(ExceptionsAttribute.of(toClassEntries(cp, List.of(exceptionTypes))))
|
||||
.withCode(cob -> {
|
||||
var catchList = computeUniqueCatchList(exceptionTypes);
|
||||
cob.aload(cob.receiverSlot())
|
||||
.getfield(handlerField)
|
||||
.aload(cob.receiverSlot())
|
||||
.getstatic(methodField);
|
||||
Class<?>[] parameterTypes = parameterTypes();
|
||||
if (parameterTypes.length > 0) {
|
||||
// Create an array and fill with the parameters converting primitives to wrappers
|
||||
cob.loadConstant(parameterTypes.length)
|
||||
|
@ -784,6 +793,7 @@ final class ProxyGenerator {
|
|||
var cp = cob.constantPool();
|
||||
codeClassForName(cob, fromClass);
|
||||
|
||||
Class<?>[] parameterTypes = parameterTypes();
|
||||
cob.ldc(method.getName())
|
||||
.loadConstant(parameterTypes.length)
|
||||
.anewarray(classCE);
|
||||
|
@ -817,10 +827,14 @@ final class ProxyGenerator {
|
|||
* loader is anticipated at local variable index 0.
|
||||
*/
|
||||
private void codeClassForName(CodeBuilder cob, Class<?> cl) {
|
||||
cob.ldc(cl.getName())
|
||||
.iconst_0() // false
|
||||
.aload(0)// classLoader
|
||||
.invokestatic(classForName);
|
||||
if (cl == Object.class) {
|
||||
cob.ldc(objectCE);
|
||||
} else {
|
||||
cob.ldc(cl.getName())
|
||||
.iconst_0() // false
|
||||
.aload(0)// classLoader
|
||||
.invokestatic(classForName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue