From e333716fbe4cfa1735a7063f7de55d658cac9205 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Tue, 22 Aug 2023 11:57:11 +0200 Subject: [PATCH] JVM: Optimize isPrimitiveBoxing and isPrimitiveUnboxing Precompute internal names and method descriptors instead of computing on every access. --- .../optimization/boxing/BoxingInterpreter.kt | 12 +++--------- .../kotlin/resolve/jvm/JvmPrimitiveType.java | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt index c4eaac73577..1337ec5d438 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt @@ -246,11 +246,7 @@ private fun isWrapperClassNameOrNumber(internalClassName: String) = isWrapperClassName(internalClassName) || internalClassName == Type.getInternalName(Number::class.java) private fun isWrapperClassName(internalClassName: String) = - JvmPrimitiveType.isWrapperClassName(buildFqNameByInternal(internalClassName)) - - -private fun buildFqNameByInternal(internalClassName: String) = - FqName(Type.getObjectType(internalClassName).className) + JvmPrimitiveType.isWrapperClassInternalName(internalClassName) private fun isUnboxingMethodName(name: String) = UNBOXING_METHOD_NAMES.contains(name) @@ -275,10 +271,8 @@ fun AbstractInsnNode.isCoroutinePrimitiveBoxing(): Boolean { } } -private fun MethodInsnNode.isBoxingMethodDescriptor(): Boolean { - val ownerType = Type.getObjectType(owner) - return desc == Type.getMethodDescriptor(ownerType, AsmUtil.unboxType(ownerType)) -} +private fun MethodInsnNode.isBoxingMethodDescriptor() = + JvmPrimitiveType.isBoxingMethodDescriptor(owner, desc) fun AbstractInsnNode.isJavaLangClassBoxing() = isMethodInsnWith(Opcodes.INVOKESTATIC) { diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java b/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java index 49b388637b4..1d7b7ba0b0e 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java @@ -34,27 +34,35 @@ public enum JvmPrimitiveType { DOUBLE(PrimitiveType.DOUBLE, "double", "D", "java.lang.Double"), ; - private static final Set WRAPPERS_CLASS_NAMES; private static final Map TYPE_BY_NAME; private static final Map TYPE_BY_PRIMITIVE_TYPE; private static final Map TYPE_BY_DESC; + private static final Set WRAPPER_CLASS_INTERNAL_NAMES; + private static final Map OWNER_TO_BOXING_METHOD_DESCRIPTOR; static { - WRAPPERS_CLASS_NAMES = new HashSet(); TYPE_BY_NAME = new HashMap(); TYPE_BY_PRIMITIVE_TYPE = new EnumMap(PrimitiveType.class); TYPE_BY_DESC = new HashMap(); + WRAPPER_CLASS_INTERNAL_NAMES = new HashSet<>(); + OWNER_TO_BOXING_METHOD_DESCRIPTOR = new HashMap<>(); for (JvmPrimitiveType type : values()) { - WRAPPERS_CLASS_NAMES.add(type.getWrapperFqName()); TYPE_BY_NAME.put(type.getJavaKeywordName(), type); TYPE_BY_PRIMITIVE_TYPE.put(type.getPrimitiveType(), type); TYPE_BY_DESC.put(type.getDesc(), type); + String internalName = type.wrapperFqName.asString().replace('.', '/'); + WRAPPER_CLASS_INTERNAL_NAMES.add(internalName); + OWNER_TO_BOXING_METHOD_DESCRIPTOR.put(internalName, "(" + type.desc + ")L" + internalName + ";"); } } - public static boolean isWrapperClassName(@NotNull FqName className) { - return WRAPPERS_CLASS_NAMES.contains(className); + public static boolean isWrapperClassInternalName(@NotNull String internalName) { + return WRAPPER_CLASS_INTERNAL_NAMES.contains(internalName); + } + + public static boolean isBoxingMethodDescriptor(@NotNull String owner, @NotNull String methodDescriptor) { + return methodDescriptor.equals(OWNER_TO_BOXING_METHOD_DESCRIPTOR.get(owner)); } @NotNull