8331264: Reduce java.lang.constant initialization overhead

Reviewed-by: liach, mchung
This commit is contained in:
Claes Redestad 2024-04-30 08:27:38 +00:00
parent 60b61e588c
commit 0630bb02eb
7 changed files with 69 additions and 67 deletions

View file

@ -270,7 +270,7 @@ public sealed interface ClassDesc
* @return whether this {@linkplain ClassDesc} describes an array type
*/
default boolean isArray() {
return descriptorString().startsWith("[");
return descriptorString().charAt(0) == '[';
}
/**
@ -288,7 +288,7 @@ public sealed interface ClassDesc
* @return whether this {@linkplain ClassDesc} describes a class or interface type
*/
default boolean isClassOrInterface() {
return descriptorString().startsWith("L");
return descriptorString().charAt(0) == 'L';
}
/**

View file

@ -64,125 +64,125 @@ public final class ConstantDescs {
// Don't change the order of these declarations!
/** {@link ClassDesc} representing {@link Object} */
public static final ClassDesc CD_Object = ClassDesc.of("java.lang.Object");
public static final ClassDesc CD_Object = new ReferenceClassDescImpl("Ljava/lang/Object;");
/** {@link ClassDesc} representing {@link String} */
public static final ClassDesc CD_String = ClassDesc.of("java.lang.String");
public static final ClassDesc CD_String = new ReferenceClassDescImpl("Ljava/lang/String;");
/** {@link ClassDesc} representing {@link Class} */
public static final ClassDesc CD_Class = ClassDesc.of("java.lang.Class");
public static final ClassDesc CD_Class = new ReferenceClassDescImpl("Ljava/lang/Class;");
/** {@link ClassDesc} representing {@link Number} */
public static final ClassDesc CD_Number = ClassDesc.of("java.lang.Number");
public static final ClassDesc CD_Number = new ReferenceClassDescImpl("Ljava/lang/Number;");
/** {@link ClassDesc} representing {@link Integer} */
public static final ClassDesc CD_Integer = ClassDesc.of("java.lang.Integer");
public static final ClassDesc CD_Integer = new ReferenceClassDescImpl("Ljava/lang/Integer;");
/** {@link ClassDesc} representing {@link Long} */
public static final ClassDesc CD_Long = ClassDesc.of("java.lang.Long");
public static final ClassDesc CD_Long = new ReferenceClassDescImpl("Ljava/lang/Long;");
/** {@link ClassDesc} representing {@link Float} */
public static final ClassDesc CD_Float = ClassDesc.of("java.lang.Float");
public static final ClassDesc CD_Float = new ReferenceClassDescImpl("Ljava/lang/Float;");
/** {@link ClassDesc} representing {@link Double} */
public static final ClassDesc CD_Double = ClassDesc.of("java.lang.Double");
public static final ClassDesc CD_Double = new ReferenceClassDescImpl("Ljava/lang/Double;");
/** {@link ClassDesc} representing {@link Short} */
public static final ClassDesc CD_Short = ClassDesc.of("java.lang.Short");
public static final ClassDesc CD_Short = new ReferenceClassDescImpl("Ljava/lang/Short;");
/** {@link ClassDesc} representing {@link Byte} */
public static final ClassDesc CD_Byte = ClassDesc.of("java.lang.Byte");
public static final ClassDesc CD_Byte = new ReferenceClassDescImpl("Ljava/lang/Byte;");
/** {@link ClassDesc} representing {@link Character} */
public static final ClassDesc CD_Character = ClassDesc.of("java.lang.Character");
public static final ClassDesc CD_Character = new ReferenceClassDescImpl("Ljava/lang/Character;");
/** {@link ClassDesc} representing {@link Boolean} */
public static final ClassDesc CD_Boolean = ClassDesc.of("java.lang.Boolean");
public static final ClassDesc CD_Boolean = new ReferenceClassDescImpl("Ljava/lang/Boolean;");
/** {@link ClassDesc} representing {@link Void} */
public static final ClassDesc CD_Void = ClassDesc.of("java.lang.Void");
public static final ClassDesc CD_Void = new ReferenceClassDescImpl("Ljava/lang/Void;");
/** {@link ClassDesc} representing {@link Throwable} */
public static final ClassDesc CD_Throwable = ClassDesc.of("java.lang.Throwable");
public static final ClassDesc CD_Throwable = new ReferenceClassDescImpl("Ljava/lang/Throwable;");
/** {@link ClassDesc} representing {@link Exception} */
public static final ClassDesc CD_Exception = ClassDesc.of("java.lang.Exception");
public static final ClassDesc CD_Exception = new ReferenceClassDescImpl("Ljava/lang/Exception;");
/** {@link ClassDesc} representing {@link Enum} */
public static final ClassDesc CD_Enum = ClassDesc.of("java.lang.Enum");
public static final ClassDesc CD_Enum = new ReferenceClassDescImpl("Ljava/lang/Enum;");
/** {@link ClassDesc} representing {@link VarHandle} */
public static final ClassDesc CD_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle");
public static final ClassDesc CD_VarHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle;");
/** {@link ClassDesc} representing {@link MethodHandles} */
public static final ClassDesc CD_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles");
public static final ClassDesc CD_MethodHandles = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles;");
/** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
public static final ClassDesc CD_MethodHandles_Lookup = CD_MethodHandles.nested("Lookup");
public static final ClassDesc CD_MethodHandles_Lookup = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles$Lookup;");
/** {@link ClassDesc} representing {@link MethodHandle} */
public static final ClassDesc CD_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle");
public static final ClassDesc CD_MethodHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandle;");
/** {@link ClassDesc} representing {@link MethodType} */
public static final ClassDesc CD_MethodType = ClassDesc.of("java.lang.invoke.MethodType");
public static final ClassDesc CD_MethodType = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodType;");
/** {@link ClassDesc} representing {@link CallSite} */
public static final ClassDesc CD_CallSite = ClassDesc.of("java.lang.invoke.CallSite");
public static final ClassDesc CD_CallSite = new ReferenceClassDescImpl("Ljava/lang/invoke/CallSite;");
/** {@link ClassDesc} representing {@link Collection} */
public static final ClassDesc CD_Collection = ClassDesc.of("java.util.Collection");
public static final ClassDesc CD_Collection = new ReferenceClassDescImpl("Ljava/util/Collection;");
/** {@link ClassDesc} representing {@link List} */
public static final ClassDesc CD_List = ClassDesc.of("java.util.List");
public static final ClassDesc CD_List = new ReferenceClassDescImpl("Ljava/util/List;");
/** {@link ClassDesc} representing {@link Set} */
public static final ClassDesc CD_Set = ClassDesc.of("java.util.Set");
public static final ClassDesc CD_Set = new ReferenceClassDescImpl("Ljava/util/Set;");
/** {@link ClassDesc} representing {@link Map} */
public static final ClassDesc CD_Map = ClassDesc.of("java.util.Map");
public static final ClassDesc CD_Map = new ReferenceClassDescImpl("Ljava/util/Map;");
/** {@link ClassDesc} representing {@link ConstantDesc} */
public static final ClassDesc CD_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc");
public static final ClassDesc CD_ConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ConstantDesc;");
/** {@link ClassDesc} representing {@link ClassDesc} */
public static final ClassDesc CD_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc");
public static final ClassDesc CD_ClassDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ClassDesc;");
/** {@link ClassDesc} representing {@link EnumDesc} */
public static final ClassDesc CD_EnumDesc = CD_Enum.nested("EnumDesc");
public static final ClassDesc CD_EnumDesc = new ReferenceClassDescImpl("Ljava/lang/Enum$EnumDesc;");
/** {@link ClassDesc} representing {@link MethodTypeDesc} */
public static final ClassDesc CD_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc");
public static final ClassDesc CD_MethodTypeDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodTypeDesc;");
/** {@link ClassDesc} representing {@link MethodHandleDesc} */
public static final ClassDesc CD_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc");
public static final ClassDesc CD_MethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodHandleDesc;");
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc} */
public static final ClassDesc CD_DirectMethodHandleDesc = ClassDesc.of("java.lang.constant.DirectMethodHandleDesc");
public static final ClassDesc CD_DirectMethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc;");
/** {@link ClassDesc} representing {@link VarHandleDesc} */
public static final ClassDesc CD_VarHandleDesc = CD_VarHandle.nested("VarHandleDesc");
public static final ClassDesc CD_VarHandleDesc = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle$VarHandleDesc;");
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */
public static final ClassDesc CD_MethodHandleDesc_Kind = CD_DirectMethodHandleDesc.nested("Kind");
public static final ClassDesc CD_MethodHandleDesc_Kind = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc$Kind;");
/** {@link ClassDesc} representing {@link DynamicConstantDesc} */
public static final ClassDesc CD_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc");
public static final ClassDesc CD_DynamicConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicConstantDesc;");
/** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
public static final ClassDesc CD_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc");
public static final ClassDesc CD_DynamicCallSiteDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicCallSiteDesc;");
/** {@link ClassDesc} representing {@link ConstantBootstraps} */
public static final ClassDesc CD_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
public static final ClassDesc CD_ConstantBootstraps = new ReferenceClassDescImpl("Ljava/lang/invoke/ConstantBootstraps;");
private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
ConstantDescs.CD_MethodHandles_Lookup,
ConstantDescs.CD_String,
ConstantDescs.CD_MethodType};
CD_MethodHandles_Lookup,
CD_String,
CD_MethodType};
private static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
ConstantDescs.CD_MethodHandles_Lookup,
ConstantDescs.CD_String,
ConstantDescs.CD_Class};
CD_MethodHandles_Lookup,
CD_String,
CD_Class};
/** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class) ConstantBootstraps.primitiveClass} */
public static final DirectMethodHandleDesc BSM_PRIMITIVE_CLASS

View file

@ -146,7 +146,6 @@ class ConstantUtils {
* @throws IllegalArgumentException if the member name is invalid
*/
public static String validateMemberName(String name, boolean method) {
requireNonNull(name);
if (name.length() == 0)
throw new IllegalArgumentException("zero-length member name");
for (int i=0; i<name.length(); i++) {

View file

@ -67,8 +67,8 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
name = "<init>";
requireNonNull(kind);
validateClassOrInterface(requireNonNull(owner));
validateMemberName(requireNonNull(name), true);
validateClassOrInterface(owner);
validateMemberName(name, true);
requireNonNull(type);
switch (kind) {

View file

@ -87,12 +87,9 @@ public abstract non-sealed class DynamicConstantDesc<T>
ClassDesc constantType,
ConstantDesc... bootstrapArgs) {
this.bootstrapMethod = requireNonNull(bootstrapMethod);
this.constantName = validateMemberName(requireNonNull(constantName), true);
this.constantName = validateMemberName(constantName, true);
this.constantType = requireNonNull(constantType);
this.bootstrapArgs = requireNonNull(bootstrapArgs).clone();
if (constantName.length() == 0)
throw new IllegalArgumentException("Illegal invocation name: " + constantName);
this.bootstrapArgs = bootstrapArgs.length == 0 ? EMPTY_CONSTANTDESC : bootstrapArgs.clone();
}
/**

View file

@ -54,8 +54,8 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
* @param validatedArgTypes {@link ClassDesc}s describing the trusted and validated parameter types
*/
private MethodTypeDescImpl(ClassDesc returnType, ClassDesc[] validatedArgTypes) {
this.returnType = requireNonNull(returnType);
this.argTypes = requireNonNull(validatedArgTypes);
this.returnType = returnType;
this.argTypes = validatedArgTypes;
}
/**
@ -66,12 +66,12 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
* @param trustedArgTypes {@link ClassDesc}s describing the trusted parameter types
*/
static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArgTypes) {
Objects.requireNonNull(returnType);
requireNonNull(returnType);
if (trustedArgTypes.length == 0) // implicit null check
return new MethodTypeDescImpl(returnType, ConstantUtils.EMPTY_CLASSDESC);
for (ClassDesc cd : trustedArgTypes)
if (cd.isPrimitive() && cd.descriptorString().charAt(0) == 'V') // implicit null check
if (cd.descriptorString().charAt(0) == 'V') // implicit null check
throw new IllegalArgumentException("Void parameters not permitted");
return new MethodTypeDescImpl(returnType, trustedArgTypes);
@ -127,7 +127,7 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
@Override
public MethodTypeDesc changeReturnType(ClassDesc returnType) {
return new MethodTypeDescImpl(returnType, argTypes);
return new MethodTypeDescImpl(requireNonNull(returnType), argTypes);
}
@Override
@ -143,8 +143,12 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
Objects.checkFromToIndex(start, end, argTypes.length);
ClassDesc[] newArgs = new ClassDesc[argTypes.length - (end - start)];
if (start > 0) {
System.arraycopy(argTypes, 0, newArgs, 0, start);
}
if (end < argTypes.length) {
System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
}
return ofTrusted(returnType, newArgs);
}
@ -154,10 +158,13 @@ final class MethodTypeDescImpl implements MethodTypeDesc {
throw new IndexOutOfBoundsException(pos);
ClassDesc[] newArgs = new ClassDesc[argTypes.length + paramTypes.length];
if (pos > 0) {
System.arraycopy(argTypes, 0, newArgs, 0, pos);
}
System.arraycopy(paramTypes, 0, newArgs, pos, paramTypes.length);
System.arraycopy(argTypes, pos, newArgs, pos+paramTypes.length, argTypes.length - pos);
if (pos < argTypes.length) {
System.arraycopy(argTypes, pos, newArgs, pos + paramTypes.length, argTypes.length - pos);
}
return ofTrusted(returnType, newArgs);
}

View file

@ -47,10 +47,9 @@ final class ReferenceClassDescImpl implements ClassDesc {
* @jvms 4.3.2 Field Descriptors
*/
ReferenceClassDescImpl(String descriptor) {
requireNonNull(descriptor);
int len = ConstantUtils.skipOverFieldSignature(descriptor, 0, descriptor.length(), false);
if (len == 0 || len == 1
|| len != descriptor.length())
int dLen = descriptor.length();
int len = ConstantUtils.skipOverFieldSignature(descriptor, 0, dLen, false);
if (len <= 1 || len != dLen)
throw new IllegalArgumentException(String.format("not a valid reference type descriptor: %s", descriptor));
this.descriptor = descriptor;
}