8341755: Optimize argNames in InnerClassLambdaMetafactory

Co-authored-by: Chen Liang <liach@openjdk.org>
Reviewed-by: liach, redestad
This commit is contained in:
Shaojin Wen 2024-10-09 23:50:18 +00:00
parent 172f74466f
commit c850ecb20a

View File

@ -34,12 +34,10 @@ import java.io.Serializable;
import java.lang.classfile.ClassBuilder; import java.lang.classfile.ClassBuilder;
import java.lang.classfile.ClassFile; import java.lang.classfile.ClassFile;
import java.lang.classfile.CodeBuilder; import java.lang.classfile.CodeBuilder;
import java.lang.classfile.FieldBuilder;
import java.lang.classfile.MethodBuilder; import java.lang.classfile.MethodBuilder;
import java.lang.classfile.Opcode; import java.lang.classfile.Opcode;
import java.lang.classfile.TypeKind; import java.lang.classfile.TypeKind;
import java.lang.constant.ClassDesc; import java.lang.constant.ClassDesc;
import java.lang.constant.DynamicConstantDesc;
import java.lang.constant.MethodTypeDesc; import java.lang.constant.MethodTypeDesc;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -51,16 +49,15 @@ import static java.lang.classfile.ClassFile.*;
import java.lang.classfile.attribute.ExceptionsAttribute; import java.lang.classfile.attribute.ExceptionsAttribute;
import java.lang.classfile.constantpool.ClassEntry; import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.MethodRefEntry;
import static java.lang.constant.ConstantDescs.*; import static java.lang.constant.ConstantDescs.*;
import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS; import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK; import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
import static java.lang.invoke.MethodHandles.Lookup.ClassOption.STRONG;
import static java.lang.invoke.MethodType.methodType; import static java.lang.invoke.MethodType.methodType;
import jdk.internal.constant.ConstantUtils; import jdk.internal.constant.ConstantUtils;
import jdk.internal.constant.MethodTypeDescImpl; import jdk.internal.constant.MethodTypeDescImpl;
import jdk.internal.constant.ReferenceClassDescImpl; import jdk.internal.constant.ReferenceClassDescImpl;
import jdk.internal.vm.annotation.Stable;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
/** /**
@ -71,7 +68,7 @@ import sun.invoke.util.Wrapper;
*/ */
/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory { /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
private static final String LAMBDA_INSTANCE_FIELD = "LAMBDA_INSTANCE$"; private static final String LAMBDA_INSTANCE_FIELD = "LAMBDA_INSTANCE$";
private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final @Stable String[] ARG_NAME_CACHE = {"arg$1", "arg$2", "arg$3", "arg$4", "arg$5", "arg$6", "arg$7", "arg$8"};
private static final ClassDesc[] EMPTY_CLASSDESC_ARRAY = ConstantUtils.EMPTY_CLASSDESC; private static final ClassDesc[] EMPTY_CLASSDESC_ARRAY = ConstantUtils.EMPTY_CLASSDESC;
// For dumping generated classes to disk, for debugging purposes // For dumping generated classes to disk, for debugging purposes
@ -96,7 +93,6 @@ import sun.invoke.util.Wrapper;
private final MethodTypeDesc implMethodDesc; // Type descriptor for implementation methods "(I)Ljava/lang/String;" private final MethodTypeDesc implMethodDesc; // Type descriptor for implementation methods "(I)Ljava/lang/String;"
private final MethodType constructorType; // Generated class constructor type "(CC)void" private final MethodType constructorType; // Generated class constructor type "(CC)void"
private final MethodTypeDesc constructorTypeDesc;// Type descriptor for the generated class constructor type "(CC)void" private final MethodTypeDesc constructorTypeDesc;// Type descriptor for the generated class constructor type "(CC)void"
private final String[] argNames; // Generated names for the constructor arguments
private final ClassDesc[] argDescs; // Type descriptors for the constructor arguments private final ClassDesc[] argDescs; // Type descriptors for the constructor arguments
private final String lambdaClassName; // Generated name for the generated class "X$$Lambda$1" private final String lambdaClassName; // Generated name for the generated class "X$$Lambda$1"
private final ConstantPoolBuilder pool = ConstantPoolBuilder.of(); private final ConstantPoolBuilder pool = ConstantPoolBuilder.of();
@ -174,18 +170,24 @@ import sun.invoke.util.Wrapper;
implKind == MethodHandleInfo.REF_invokeSpecial || implKind == MethodHandleInfo.REF_invokeSpecial ||
implKind == MethodHandleInfo.REF_invokeStatic && implClass.isHidden(); implKind == MethodHandleInfo.REF_invokeStatic && implClass.isHidden();
int parameterCount = factoryType.parameterCount(); int parameterCount = factoryType.parameterCount();
ClassDesc[] argDescs;
MethodTypeDesc constructorTypeDesc;
if (parameterCount > 0) { if (parameterCount > 0) {
argNames = new String[parameterCount];
argDescs = new ClassDesc[parameterCount]; argDescs = new ClassDesc[parameterCount];
for (int i = 0; i < parameterCount; i++) { for (int i = 0; i < parameterCount; i++) {
argNames[i] = "arg$" + (i + 1);
argDescs[i] = classDesc(factoryType.parameterType(i)); argDescs[i] = classDesc(factoryType.parameterType(i));
} }
} else {
argNames = EMPTY_STRING_ARRAY;
argDescs = EMPTY_CLASSDESC_ARRAY;
}
constructorTypeDesc = MethodTypeDescImpl.ofValidated(CD_void, argDescs); constructorTypeDesc = MethodTypeDescImpl.ofValidated(CD_void, argDescs);
} else {
argDescs = EMPTY_CLASSDESC_ARRAY;
constructorTypeDesc = MTD_void;
}
this.argDescs = argDescs;
this.constructorTypeDesc = constructorTypeDesc;
}
private static String argName(int i) {
return i < ARG_NAME_CACHE.length ? ARG_NAME_CACHE[i] : "arg$" + (i + 1);
} }
private static String lambdaClassName(Class<?> targetClass) { private static String lambdaClassName(Class<?> targetClass) {
@ -313,7 +315,7 @@ import sun.invoke.util.Wrapper;
.withInterfaceSymbols(interfaces); .withInterfaceSymbols(interfaces);
// Generate final fields to be filled in by constructor // Generate final fields to be filled in by constructor
for (int i = 0; i < argDescs.length; i++) { for (int i = 0; i < argDescs.length; i++) {
clb.withField(argNames[i], argDescs[i], ACC_PRIVATE | ACC_FINAL); clb.withField(argName(i), argDescs[i], ACC_PRIVATE | ACC_FINAL);
} }
generateConstructor(clb); generateConstructor(clb);
@ -396,7 +398,7 @@ import sun.invoke.util.Wrapper;
for (int i = 0; i < parameterCount; i++) { for (int i = 0; i < parameterCount; i++) {
cob.aload(0) cob.aload(0)
.loadLocal(TypeKind.from(factoryType.parameterType(i)), cob.parameterSlot(i)) .loadLocal(TypeKind.from(factoryType.parameterType(i)), cob.parameterSlot(i))
.putfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argNames[i], argDescs[i]))); .putfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argName(i), argDescs[i])));
} }
cob.return_(); cob.return_();
} }
@ -448,7 +450,7 @@ import sun.invoke.util.Wrapper;
cob.dup() cob.dup()
.loadConstant(i) .loadConstant(i)
.aload(0) .aload(0)
.getfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argNames[i], argDescs[i]))); .getfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argName(i), argDescs[i])));
TypeConvertingMethodAdapter.boxIfTypePrimitive(cob, TypeKind.from(argDescs[i])); TypeConvertingMethodAdapter.boxIfTypePrimitive(cob, TypeKind.from(argDescs[i]));
cob.aastore(); cob.aastore();
} }
@ -505,9 +507,9 @@ import sun.invoke.util.Wrapper;
cob.ldc(cp.constantDynamicEntry(cp.bsmEntry(cp.methodHandleEntry(BSM_CLASS_DATA), List.of()), cob.ldc(cp.constantDynamicEntry(cp.bsmEntry(cp.methodHandleEntry(BSM_CLASS_DATA), List.of()),
cp.nameAndTypeEntry(DEFAULT_NAME, CD_MethodHandle))); cp.nameAndTypeEntry(DEFAULT_NAME, CD_MethodHandle)));
} }
for (int i = 0; i < argNames.length; i++) { for (int i = 0; i < argDescs.length; i++) {
cob.aload(0) cob.aload(0)
.getfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argNames[i], argDescs[i]))); .getfield(pool.fieldRefEntry(lambdaClassEntry, pool.nameAndTypeEntry(argName(i), argDescs[i])));
} }
convertArgumentTypes(cob, methodType); convertArgumentTypes(cob, methodType);