JVM_IR: do not box inline classes in suspend synthetic accessors

This commit is contained in:
pyos
2021-04-22 10:19:45 +02:00
committed by Ilmir Usmanov
parent 857bee6ced
commit 7d95943b8b
11 changed files with 90 additions and 24 deletions
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -142,16 +141,19 @@ private fun IrFunction.isStaticInlineClassReplacementDelegatingCall(): Boolean =
parentAsClass.declarations.find { it is IrAttributeContainer && it.attributeOwnerId == attributeOwnerId && it !== this }
?.isStaticInlineClassReplacement == true
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspendOfContinuation() &&
// These are tail-call bridges and do not require any bytecode modifications.
origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
origin != JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR &&
origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE &&
origin != IrDeclarationOrigin.BRIDGE &&
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
internal val BRIDGE_ORIGINS = setOf(
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR,
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
IrDeclarationOrigin.BRIDGE,
IrDeclarationOrigin.BRIDGE_SPECIAL,
)
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = origin !in BRIDGE_ORIGINS &&
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
!isInvokeSuspendOfContinuation() &&
!isMultifileBridge() &&
!isInvokeOfSuspendCallableReference() &&
!isBridgeToSuspendImplMethod() &&
@@ -229,20 +229,17 @@ class ExpressionCodegen(
if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) {
irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary)
}
if (irFunction.isSuspend && irFunction.origin == IrDeclarationOrigin.BRIDGE) {
mv.areturn(OBJECT_TYPE)
val unboxedInlineClass =
irFunction.suspendFunctionOriginal().originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
if (unboxedInlineClass != null && irFunction.origin !in BRIDGE_ORIGINS) {
result.materializeAt(unboxedInlineClass.asmType, unboxedInlineClass)
} else {
var returnType = signature.returnType
var returnIrType = if (irFunction !is IrConstructor) irFunction.returnType else context.irBuiltIns.unitType
val unboxedInlineClass =
irFunction.suspendFunctionOriginal().originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
if (unboxedInlineClass != null) {
returnIrType = unboxedInlineClass
returnType = unboxedInlineClass.asmType
}
result.materializeAt(returnType, returnIrType)
mv.areturn(returnType)
val returnIrType = if (irFunction !is IrConstructor) irFunction.returnType else context.irBuiltIns.unitType
result.materializeAt(signature.returnType, returnIrType)
}
// `signature.returnType` is valid here even if the return value of a suspend function was unboxed,
// as it's still a reference type.
mv.areturn(signature.returnType)
}
val endLabel = markNewLabel()
writeLocalVariablesInTable(info, endLabel)
@@ -508,7 +505,7 @@ class ExpressionCodegen(
wrapJavaClassesIntoKClasses(mv)
MaterialValue(this, AsmTypes.K_CLASS_ARRAY_TYPE, expression.type)
}
unboxedInlineClassIrType != null && !irFunction.isInvokeSuspendOfContinuation() ->
unboxedInlineClassIrType != null && !irFunction.isInvokeSuspendOfContinuation() && irFunction.origin !in BRIDGE_ORIGINS ->
object : PromisedValue(this, unboxedInlineClassIrType.asmType, unboxedInlineClassIrType) {
override fun materializeAt(target: Type, irTarget: IrType, castForReified: Boolean) {
mv.checkcast(unboxedInlineClassIrType.asmType)
@@ -416,7 +416,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
isSuspend = source.isSuspend // synthetic accessors of suspend functions are handled in codegen
}.also { accessor ->
accessor.parent = parent
accessor.copyAttributes(source)
accessor.copyTypeParametersFrom(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, dispatchReceiverType)
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)