[JVM] Extend boxing/unboxing optimizations to coroutine boxing.

This commit is contained in:
Mads Ager
2021-05-06 11:21:26 +02:00
committed by Ilmir Usmanov
parent 4994cb3774
commit afa1b8bfdc
5 changed files with 102 additions and 1 deletions
@@ -18,12 +18,16 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.coroutines.RELEASE_COROUTINES_VERSION_SETTINGS
import org.jetbrains.kotlin.codegen.coroutines.coroutinesJvmInternalPackageFqName
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -174,7 +178,7 @@ fun AbstractInsnNode.isUnboxing(state: GenerationState) =
isPrimitiveUnboxing() || isJavaLangClassUnboxing() || isInlineClassUnboxing(state)
fun AbstractInsnNode.isBoxing(state: GenerationState) =
isPrimitiveBoxing() || isJavaLangClassBoxing() || isInlineClassBoxing(state)
isPrimitiveBoxing() || isJavaLangClassBoxing() || isInlineClassBoxing(state) || isCoroutinePrimitiveBoxing()
fun AbstractInsnNode.isPrimitiveUnboxing() =
isMethodInsnWith(Opcodes.INVOKEVIRTUAL) {
@@ -211,6 +215,19 @@ fun AbstractInsnNode.isPrimitiveBoxing() =
isBoxingMethodDescriptor()
}
private val BOXING_CLASS_INTERNAL_NAME =
RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName().child(Name.identifier("Boxing")).topLevelClassInternalName()
private fun isJvmPrimitiveName(name: String) = JvmPrimitiveType.values().any { it.javaKeywordName == name }
fun AbstractInsnNode.isCoroutinePrimitiveBoxing(): Boolean {
return isMethodInsnWith(Opcodes.INVOKESTATIC) {
owner == BOXING_CLASS_INTERNAL_NAME &&
name.startsWith("box") &&
isJvmPrimitiveName(name.substring(3).lowercase())
}
}
private fun MethodInsnNode.isBoxingMethodDescriptor(): Boolean {
val ownerType = Type.getObjectType(owner)
return desc == Type.getMethodDescriptor(ownerType, AsmUtil.unboxType(ownerType))