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)
|
isWrapperClassName(internalClassName) || internalClassName == Type.getInternalName(Number::class.java)
|
||||||
|
|
||||||
private fun isWrapperClassName(internalClassName: String) =
|
private fun isWrapperClassName(internalClassName: String) =
|
||||||
JvmPrimitiveType.isWrapperClassName(buildFqNameByInternal(internalClassName))
|
JvmPrimitiveType.isWrapperClassInternalName(internalClassName)
|
||||||
|
|
||||||
|
|
||||||
private fun buildFqNameByInternal(internalClassName: String) =
|
|
||||||
FqName(Type.getObjectType(internalClassName).className)
|
|
||||||
|
|
||||||
private fun isUnboxingMethodName(name: String) =
|
private fun isUnboxingMethodName(name: String) =
|
||||||
UNBOXING_METHOD_NAMES.contains(name)
|
UNBOXING_METHOD_NAMES.contains(name)
|
||||||
@@ -275,10 +271,8 @@ fun AbstractInsnNode.isCoroutinePrimitiveBoxing(): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MethodInsnNode.isBoxingMethodDescriptor(): Boolean {
|
private fun MethodInsnNode.isBoxingMethodDescriptor() =
|
||||||
val ownerType = Type.getObjectType(owner)
|
JvmPrimitiveType.isBoxingMethodDescriptor(owner, desc)
|
||||||
return desc == Type.getMethodDescriptor(ownerType, AsmUtil.unboxType(ownerType))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun AbstractInsnNode.isJavaLangClassBoxing() =
|
fun AbstractInsnNode.isJavaLangClassBoxing() =
|
||||||
isMethodInsnWith(Opcodes.INVOKESTATIC) {
|
isMethodInsnWith(Opcodes.INVOKESTATIC) {
|
||||||
|
|||||||
+13
-5
@@ -34,27 +34,35 @@ public enum JvmPrimitiveType {
|
|||||||
DOUBLE(PrimitiveType.DOUBLE, "double", "D", "java.lang.Double"),
|
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<String, JvmPrimitiveType> TYPE_BY_NAME;
|
||||||
private static final Map<PrimitiveType, JvmPrimitiveType> TYPE_BY_PRIMITIVE_TYPE;
|
private static final Map<PrimitiveType, JvmPrimitiveType> TYPE_BY_PRIMITIVE_TYPE;
|
||||||
private static final Map<String, JvmPrimitiveType> TYPE_BY_DESC;
|
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 {
|
static {
|
||||||
WRAPPERS_CLASS_NAMES = new HashSet<FqName>();
|
|
||||||
TYPE_BY_NAME = new HashMap<String, JvmPrimitiveType>();
|
TYPE_BY_NAME = new HashMap<String, JvmPrimitiveType>();
|
||||||
TYPE_BY_PRIMITIVE_TYPE = new EnumMap<PrimitiveType, JvmPrimitiveType>(PrimitiveType.class);
|
TYPE_BY_PRIMITIVE_TYPE = new EnumMap<PrimitiveType, JvmPrimitiveType>(PrimitiveType.class);
|
||||||
TYPE_BY_DESC = new HashMap<String, JvmPrimitiveType>();
|
TYPE_BY_DESC = new HashMap<String, JvmPrimitiveType>();
|
||||||
|
WRAPPER_CLASS_INTERNAL_NAMES = new HashSet<>();
|
||||||
|
OWNER_TO_BOXING_METHOD_DESCRIPTOR = new HashMap<>();
|
||||||
|
|
||||||
for (JvmPrimitiveType type : values()) {
|
for (JvmPrimitiveType type : values()) {
|
||||||
WRAPPERS_CLASS_NAMES.add(type.getWrapperFqName());
|
|
||||||
TYPE_BY_NAME.put(type.getJavaKeywordName(), type);
|
TYPE_BY_NAME.put(type.getJavaKeywordName(), type);
|
||||||
TYPE_BY_PRIMITIVE_TYPE.put(type.getPrimitiveType(), type);
|
TYPE_BY_PRIMITIVE_TYPE.put(type.getPrimitiveType(), type);
|
||||||
TYPE_BY_DESC.put(type.getDesc(), 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) {
|
public static boolean isWrapperClassInternalName(@NotNull String internalName) {
|
||||||
return WRAPPERS_CLASS_NAMES.contains(className);
|
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
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user