JVM_IR: do not optimize suspend$$forInline functions

`$$forInline` functions do not pass through the state machine generator,
and optimizing `Ref`s before that changes how assignments inside lambdas
passed to `suspendCoroutine`, etc. behave: without a `Ref`, the
assignment is not reflected in the continuation object, so the variable
has old value on resumption.

These functions will be optimized later, after they are inlined
somewhere and the state machine is generated.

^KT-52198 Fixed
This commit is contained in:
pyos
2022-04-29 13:29:42 +02:00
committed by Ilmir Usmanov
parent 153f878df4
commit effd21d074
14 changed files with 109 additions and 7 deletions
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.org.objectweb.asm.MethodVisitor
class OptimizationClassBuilder(private val delegate: ClassBuilder, private val generationState: GenerationState) :
@@ -36,6 +37,7 @@ class OptimizationClassBuilder(private val delegate: ClassBuilder, private val g
): MethodVisitor {
return OptimizationMethodVisitor(
super.newMethod(origin, access, name, desc, signature, exceptions),
origin.originKind == JvmDeclarationOriginKind.INLINE_VERSION_OF_SUSPEND_FUN,
generationState, access, name, desc, signature, exceptions
)
}
@@ -34,6 +34,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
class OptimizationMethodVisitor(
delegate: MethodVisitor,
private val mandatoryTransformationsOnly: Boolean,
private val generationState: GenerationState,
access: Int,
name: String,
@@ -67,7 +68,7 @@ class OptimizationMethodVisitor(
normalizationMethodTransformer.transform("fake", methodNode)
UninitializedStoresProcessor(methodNode).run()
if (canBeOptimized(methodNode) && !generationState.disableOptimization) {
if (!mandatoryTransformationsOnly && canBeOptimized(methodNode) && !generationState.disableOptimization) {
optimizationTransformer.transform("fake", methodNode)
}