From 0630bb02eb760081ddd612ccb1b12d57d43aab5e Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Tue, 30 Apr 2024 08:27:38 +0000 Subject: [PATCH] 8331264: Reduce java.lang.constant initialization overhead Reviewed-by: liach, mchung --- .../classes/java/lang/constant/ClassDesc.java | 4 +- .../java/lang/constant/ConstantDescs.java | 86 +++++++++---------- .../java/lang/constant/ConstantUtils.java | 1 - .../constant/DirectMethodHandleDescImpl.java | 4 +- .../lang/constant/DynamicConstantDesc.java | 7 +- .../lang/constant/MethodTypeDescImpl.java | 27 +++--- .../lang/constant/ReferenceClassDescImpl.java | 7 +- 7 files changed, 69 insertions(+), 67 deletions(-) diff --git a/src/java.base/share/classes/java/lang/constant/ClassDesc.java b/src/java.base/share/classes/java/lang/constant/ClassDesc.java index 767fa953e97..89be851dbf5 100644 --- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java +++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java @@ -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'; } /** diff --git a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java index de895fc7af5..a67a16643c3 100644 --- a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java +++ b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java @@ -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 diff --git a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java index d975eaa1d0c..d8a1ccd543b 100644 --- a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java +++ b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java @@ -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 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(); } /** diff --git a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java index a2d06615e5d..7ee0995439a 100644 --- a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java +++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java @@ -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)]; - System.arraycopy(argTypes, 0, newArgs, 0, start); - System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end); + 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]; - System.arraycopy(argTypes, 0, newArgs, 0, pos); + 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); } diff --git a/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java b/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java index 4cc77b1851d..5e2aaa98442 100644 --- a/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java +++ b/src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java @@ -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; }