diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index bdf0ab39f65..fdd4ab73e77 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -117,7 +117,6 @@ class JvmBackendContext( val continuationClassBuilders = mutableMapOf() val suspendFunctionOriginalToView = mutableMapOf() val suspendFunctionOriginalToStub = mutableMapOf() - val suspendTailCallsWithUnitReplacement = mutableSetOf() val fakeContinuation: IrExpression = createFakeContinuation(this) val staticDefaultStubs = mutableMapOf() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 17d51e07370..0d08c9fe4c7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -476,28 +476,22 @@ class ExpressionCodegen( } } - private fun IrFunctionAccessExpression.isSuspensionPoint(): Boolean { - val owner = symbol.owner - return when { - // Only suspend functions are suspension points - !owner.isSuspend -> false - // But not inside continuation classes and bridges - irFunction.shouldNotContainSuspendMarkers() -> false - // Noinline function are always suspension points - !owner.isInline -> true - // The suspend intrinsics are, albeit inline, also suspension points - owner.fqNameForIrSerialization == FqName("kotlin.coroutines.intrinsics.IntrinsicsKt.suspendCoroutineUninterceptedOrReturn") -> true - // Inside $$forInline functions crossinline calls are (usually) not suspension points, otherwise, flow will be pessimized - (dispatchReceiver as? IrGetField)?.symbol?.owner?.origin == - LocalDeclarationsLowering.DECLARATION_ORIGIN_FIELD_FOR_CROSSINLINE_CAPTURED_VALUE -> - irFunction.origin != FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE - // The same goes for inline lambdas - (dispatchReceiver as? IrGetValue)?.let { - it.origin == IrStatementOrigin.VARIABLE_AS_FUNCTION && (it.symbol.owner as? IrValueParameter)?.isNoinline != true - } == true -> irFunction.origin != FOR_INLINE_STATE_MACHINE_TEMPLATE - // Otherwise, this is normal inline call, ergo not a suspension point - else -> false - } + private fun IrFunctionAccessExpression.isInvokeOfInlineLambda(): Boolean = when (val receiver = dispatchReceiver) { + is IrGetField -> receiver.symbol.owner.origin == LocalDeclarationsLowering.DECLARATION_ORIGIN_FIELD_FOR_CROSSINLINE_CAPTURED_VALUE + is IrGetValue -> receiver.origin == IrStatementOrigin.VARIABLE_AS_FUNCTION && + (receiver.symbol.owner as? IrValueParameter)?.isNoinline == false + else -> false + } + + private fun IrFunctionAccessExpression.isSuspensionPoint(): Boolean = when { + !symbol.owner.isSuspend || irFunction.shouldNotContainSuspendMarkers() -> false + // Copy-pasted bytecode blocks are not suspension points. + symbol.owner.isInline -> + symbol.owner.fqNameForIrSerialization == FqName("kotlin.coroutines.intrinsics.IntrinsicsKt.suspendCoroutineUninterceptedOrReturn") + // This includes inline lambdas, but only in functions intended for the inliner; in others, they stay as `f.invoke()`. + isInvokeOfInlineLambda() -> + irFunction.origin != FOR_INLINE_STATE_MACHINE_TEMPLATE && irFunction.origin != FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE + else -> true } override fun visitVariable(declaration: IrVariable, data: BlockInfo): PromisedValue { @@ -661,13 +655,6 @@ class ExpressionCodegen( val returnType = if (owner == irFunction) signature.returnType else methodSignatureMapper.mapReturnType(owner) val afterReturnLabel = Label() expression.value.accept(this, data).coerce(returnType, owner.returnType).materialize() - // We replaced COERTION_TO_UNIT with IrReturn during TailCallOptimizationLowering. - // Generate POP GETSTATIC kotlin/Unit.INSTANCE now. - // Otherwise, tail-call optimization will not work. See tailSuspendUnitFun.kt test. - if (expression in context.suspendTailCallsWithUnitReplacement) { - mv.pop() - mv.getstatic("kotlin/Unit", "INSTANCE", "Lkotlin/Unit;") - } generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data) expression.markLineNumber(startOffset = true) if (isNonLocalReturn) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index 930f8d5510e..397d62ae759 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -22,11 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.toKotlinType -import org.jetbrains.kotlin.ir.util.dump -import org.jetbrains.kotlin.ir.util.getArgumentsWithIr -import org.jetbrains.kotlin.ir.util.isSuspend -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.Type @@ -87,11 +83,9 @@ class IrInlineCodegen( super.genValueAndPut(irValueParameter, argumentExpression, parameterType, codegen, blockInfo) } - if (irValueParameter.isInlineParameter( - /*after transformation inlinable lambda parameter with default value would have nullable type: check default value type first*/ - irValueParameter.defaultValue?.expression?.type ?: irValueParameter.type - ) && isInlineIrExpression(argumentExpression) - ) { + // after transformation inlinable lambda parameter with default value would have nullable type: check default value type first + val isInlineParameter = irValueParameter.isInlineParameter(irValueParameter.defaultValue?.expression?.type ?: irValueParameter.type) + if (isInlineParameter && isInlineIrExpression(argumentExpression)) { val irReference: IrFunctionReference = (argumentExpression as IrBlock).statements.filterIsInstance().single() val boundReceiver = argumentExpression.statements.filterIsInstance().singleOrNull() @@ -107,9 +101,14 @@ class IrInlineCodegen( val kind = when (irValueParameter.origin) { IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION -> ValueKind.DEFAULT_MASK IrDeclarationOrigin.METHOD_HANDLER_IN_DEFAULT_FUNCTION -> ValueKind.METHOD_HANDLE_IN_DEFAULT - else -> if (argumentExpression is IrContainerExpression && argumentExpression.origin == IrStatementOrigin.DEFAULT_VALUE) - ValueKind.DEFAULT_PARAMETER - else ValueKind.CAPTURED + else -> when { + argumentExpression is IrContainerExpression && argumentExpression.origin == IrStatementOrigin.DEFAULT_VALUE -> + ValueKind.DEFAULT_PARAMETER + // TODO ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND? + isInlineParameter && irValueParameter.type.isSuspendFunctionTypeOrSubtype() -> + ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER + else -> ValueKind.GENERAL + } } val onStack = when { @@ -130,11 +129,7 @@ class IrInlineCodegen( //TODO support default argument erasure - if (!processDefaultMaskOrMethodHandler( - onStack, - kind - ) - ) { + if (!processDefaultMaskOrMethodHandler(onStack, kind)) { val expectedType = JvmKotlinType(parameterType, irValueParameter.type.toKotlinType()) putArgumentOrCapturedToLocalVal(expectedType, onStack, -1, irValueParameter.index, kind) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index accdf2d0676..fd21df8c533 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -89,8 +89,8 @@ class IrSourceCompilerForInline( root.classCodegen.type.internalName, root.signature.asmMethod.name, root.signature.asmMethod.descriptor, - compilationContextFunctionDescriptor.isInlineOrInsideInline(), - compilationContextFunctionDescriptor.isSuspend, + root.irFunction.descriptor.isInlineOrInsideInline(), + root.irFunction.isSuspend, findElement()?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0 ) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TailCallOptimizationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TailCallOptimizationLowering.kt index 69c809c84c4..1ebac975746 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TailCallOptimizationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TailCallOptimizationLowering.kt @@ -11,21 +11,18 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.codegen.anyOfOverriddenFunctionsReturnsNonUnit import org.jetbrains.kotlin.backend.jvm.codegen.isKnownToBeTailCall -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.isSuspend import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -35,72 +32,60 @@ internal val tailCallOptimizationPhase = makeIrFilePhase( "Add or move returns to suspension points on tail-call positions" ) -// TODO: Make this lowering common -private class TailCallOptimizationLowering(private val context: JvmBackendContext) : IrElementVisitorVoid, FileLoweringPass { +// Find all tail-calls inside suspend function. We should add IrReturn before them, so the codegen will generate +// code which is understandable by old BE's tail-call optimizer. +private class TailCallOptimizationLowering(private val context: JvmBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) { - visitFile(irFile) - } + irFile.transformChildren(object : IrElementTransformer { + override fun visitFunction(declaration: IrFunction, data: TailCallOptimizationData?) = + super.visitFunction(declaration, TailCallOptimizationData(declaration)) - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitFunction(function: IrFunction) { - if (!function.isSuspend || function.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || function.isKnownToBeTailCall()) return - // Disable tail-call optimization for functions, returning Unit and overriding function, returning non-unit. - if (function.returnType.isUnit() && function.anyOfOverriddenFunctionsReturnsNonUnit()) return - - val tailCalls = mutableSetOf() - - // Find all tail-calls inside suspend function. - // We should add IrReturn before them, so the codegen will generate code, which is understandable by old BE's tail-call optimizer. - // This function collect all possible tail-calls, if they are not prepended by IrReturns, so we can prepend them. - // If the call has IrReturn before it, we do not need to add another one. - // If the call is inside a branch of `when` statement (or `if`, which is lowered to `when`), go through the branches and - // find tail-calls there. - fun findCallsOnTailPositionWithoutImmediateReturn(statement: IrStatement, immediateReturn: Boolean = false) { - when (statement) { - is IrCall -> if (statement.isSuspend && !immediateReturn) { - tailCalls += statement - } - is IrBlock -> findCallsOnTailPositionWithoutImmediateReturn( - statement.statements.findTailCall(function.returnType.isUnit()) ?: return + override fun visitCall(expression: IrCall, data: TailCallOptimizationData?): IrExpression { + val transformed = super.visitCall(expression, data) as IrExpression + return if (data == null || expression !in data.tailCalls) transformed else IrReturnImpl( + expression.startOffset, expression.endOffset, context.irBuiltIns.nothingType, data.function.symbol, + if (data.returnsUnit) transformed.coerceToUnit() else transformed ) - is IrWhen -> for (branch in statement.branches) { - findCallsOnTailPositionWithoutImmediateReturn(branch.result) - } - is IrReturn -> findCallsOnTailPositionWithoutImmediateReturn(statement.value, immediateReturn = true) - is IrTypeOperatorCall -> if (statement.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { - findCallsOnTailPositionWithoutImmediateReturn(statement.argument) - } - else -> { - // Not a call, or something containing a tail-call, break - // TODO: Support binary logical operations and elvis, though. KT-23826 and KT-23825 - } + } + }, null) + } + + private fun IrExpression.coerceToUnit() = IrTypeOperatorCallImpl( + startOffset, endOffset, context.irBuiltIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.irBuiltIns.unitType, this + ) +} + +private class TailCallOptimizationData(val function: IrFunction) { + val returnsUnit = function.returnType.isUnit() + val tailCalls = mutableSetOf() + + // Collect all tail calls, including those nested in `when`s, which are not arguments to `return`s. + private fun findCallsOnTailPositionWithoutImmediateReturn(statement: IrStatement, immediateReturn: Boolean = false) { + when { + statement is IrCall && statement.isSuspend && !immediateReturn && (returnsUnit || statement.type == function.returnType) -> + tailCalls += statement + statement is IrBlock -> + statement.statements.findTailCall(returnsUnit)?.let(::findCallsOnTailPositionWithoutImmediateReturn) + statement is IrWhen -> + statement.branches.forEach { findCallsOnTailPositionWithoutImmediateReturn(it.result) } + statement is IrReturn -> + findCallsOnTailPositionWithoutImmediateReturn(statement.value, immediateReturn = true) + statement is IrTypeOperatorCall && statement.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> + findCallsOnTailPositionWithoutImmediateReturn(statement.argument) + // TODO: Support binary logical operations and elvis, though. KT-23826 and KT-23825 + } + } + + init { + if (function.isSuspend && function.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA && !function.isKnownToBeTailCall() && + // See `disableTailCallOptimizationForFunctionReturningUnit` in `generateStateMachineForNamedFunction`: + !(returnsUnit && function.anyOfOverriddenFunctionsReturnsNonUnit()) + ) { + when (val body = function.body) { + is IrBlockBody -> body.statements.findTailCall(returnsUnit)?.let(::findCallsOnTailPositionWithoutImmediateReturn) + is IrExpressionBody -> findCallsOnTailPositionWithoutImmediateReturn(body.expression) } } - - when (val body = function.body) { - null -> return - is IrBlockBody -> findCallsOnTailPositionWithoutImmediateReturn( - body.statements.findTailCall(function.returnType.isUnit()) ?: return - ) - is IrExpressionBody -> findCallsOnTailPositionWithoutImmediateReturn(body.expression) - else -> error("Unexpected $body") - } - - function.transformChildrenVoid(object : IrElementTransformerVoid() { - override fun visitCall(call: IrCall): IrExpression { - if (call !in tailCalls) return call - if (!function.returnType.isUnit() && call.type != function.returnType) return call - // Replace ARETURN with { POP, GETSTATIC kotlin/Unit.INSTANCE, ARETURN } during codegen later. - // Otherwise, additional CHECKCAST will break tail-call optimization - if (function.returnType.isUnit()) { - context.suspendTailCallsWithUnitReplacement += call.attributeOwnerId - } - return IrReturnImpl(call.startOffset, call.endOffset, context.irBuiltIns.nothingType, function.symbol, call) - } - }) } } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt index 6538475e7bb..eb7055d2a28 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt @@ -33,7 +33,6 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 { inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 public method (p0: Sink): void public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void - public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } @@ -42,7 +41,6 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 { synthetic final field $this$inlined: SourceCrossinline inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 public method (p0: SourceCrossinline): void - public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } @@ -66,7 +64,6 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 { inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 public method (p0: kotlin.jvm.internal.Ref$ObjectRef): void public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void - public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } @@ -326,7 +323,6 @@ public final class CrossinlineKt$range$$inlined$source$1 { synthetic final field $start$inlined: int inner class CrossinlineKt$range$$inlined$source$1 public method (p0: int, p1: int): void - public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt index 9308395d3aa..00bd9ddffcc 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt @@ -19,63 +19,25 @@ final class flow/InnerObjectRetransformationKt$box$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.Metadata -final class flow/InnerObjectRetransformationKt$check$$inlined$collect$1$1 { - field label: int - @org.jetbrains.annotations.NotNull field result: java.lang.Object - synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$collect$1 - public method (p0: flow.InnerObjectRetransformationKt$check$$inlined$collect$1, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - @kotlin.Metadata public final class flow/InnerObjectRetransformationKt$check$$inlined$collect$1 { inner class flow/InnerObjectRetransformationKt$check$$inlined$collect$1 public method (): void - public @org.jetbrains.annotations.Nullable method emit$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method emit(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field label: int - @org.jetbrains.annotations.NotNull field result: java.lang.Object - synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flow$1 - public method (p0: flow.InnerObjectRetransformationKt$check$$inlined$flow$1, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - @kotlin.Metadata public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 { inner class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 public method (): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field label: int - @org.jetbrains.annotations.NotNull field result: java.lang.Object - synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1 - public method (p0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - @kotlin.Metadata public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 { synthetic final field $this$inlined: flow.Flow inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 public method (p0: flow.Flow): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } @@ -134,11 +96,7 @@ public final class flow/InnerObjectRetransformationKt$flow$1 { } @kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object field label: int @org.jetbrains.annotations.NotNull field result: java.lang.Object synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$1 @@ -157,11 +115,7 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 { } @kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object field label: int @org.jetbrains.annotations.NotNull field result: java.lang.Object synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2 diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt index 790d43792c2..b1451bf5504 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt @@ -3,17 +3,6 @@ public interface Base { public abstract @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -final class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1$1 { - field L$0: java.lang.Object - field label: int - @org.jetbrains.annotations.NotNull field result: java.lang.Object - synthetic final field this$0: Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1 - public method (p0: Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - @kotlin.Metadata public final class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1$2 { inner class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1 @@ -28,7 +17,6 @@ public final class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1 { inner class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1 inner class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1$2 public method (): void - public @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object public @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/boxInline/suspend/inlineSuspendContinuation.kt b/compiler/testData/codegen/boxInline/suspend/inlineSuspendContinuation.kt index e41b69da449..6797a429499 100644 --- a/compiler/testData/codegen/boxInline/suspend/inlineSuspendContinuation.kt +++ b/compiler/testData/codegen/boxInline/suspend/inlineSuspendContinuation.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // FILE: test.kt // COMMON_COROUTINES_TEST // WITH_RUNTIME