JVM: Optimize isPrimitiveBoxing and isPrimitiveUnboxing
Precompute internal names and method descriptors instead of computing on every access.
This commit is contained in:
committed by
Space Team
parent
3246b0a6bd
commit
e333716fbe
+3
-9
@@ -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) {
|
||||
|
||||
+13
-5
@@ -34,27 +34,35 @@ public enum JvmPrimitiveType {
|
||||
DOUBLE(PrimitiveType.DOUBLE, "double", "D", "java.lang.Double"),
|
||||
;
|
||||
|
||||
private static final Set<FqName> WRAPPERS_CLASS_NAMES;
|
||||
private static final Map<String, JvmPrimitiveType> TYPE_BY_NAME;
|
||||
private static final Map<PrimitiveType, JvmPrimitiveType> TYPE_BY_PRIMITIVE_TYPE;
|
||||
private static final Map<String, JvmPrimitiveType> TYPE_BY_DESC;
|
||||
private static final Set<String> WRAPPER_CLASS_INTERNAL_NAMES;
|
||||
private static final Map<String, String> OWNER_TO_BOXING_METHOD_DESCRIPTOR;
|
||||
|
||||
static {
|
||||
WRAPPERS_CLASS_NAMES = new HashSet<FqName>();
|
||||
TYPE_BY_NAME = new HashMap<String, JvmPrimitiveType>();
|
||||
TYPE_BY_PRIMITIVE_TYPE = new EnumMap<PrimitiveType, JvmPrimitiveType>(PrimitiveType.class);
|
||||
TYPE_BY_DESC = new HashMap<String, JvmPrimitiveType>();
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user