Slightly cleanup coroutine codegen and utilities

Reformat, fix inspections, remove some minor leftovers after dropping
experimentail coroutines.
This commit is contained in:
Alexander Udalov
2021-09-02 02:47:14 +02:00
parent 0a10cec579
commit 8cb9a5ff67
5 changed files with 30 additions and 71 deletions
@@ -64,24 +64,23 @@ abstract class AbstractCoroutineCodegen(
protected val classDescriptor = closureContext.contextDescriptor protected val classDescriptor = closureContext.contextDescriptor
protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
protected val methodToImplement = protected val methodToImplement: FunctionDescriptor =
createImplMethod(
INVOKE_SUSPEND_METHOD_NAME,
SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
)
private fun createImplMethod(name: String, vararg parameters: Pair<String, KotlinType>) =
SimpleFunctionDescriptorImpl.create( SimpleFunctionDescriptorImpl.create(
classDescriptor, Annotations.EMPTY, Name.identifier(name), CallableMemberDescriptor.Kind.DECLARATION, classDescriptor, Annotations.EMPTY, Name.identifier(INVOKE_SUSPEND_METHOD_NAME), CallableMemberDescriptor.Kind.DECLARATION,
funDescriptor.source funDescriptor.source
).apply { ).apply {
initialize( initialize(
null, null,
classDescriptor.thisAsReceiverParameter, classDescriptor.thisAsReceiverParameter,
emptyList(), emptyList(),
parameters.withIndex().map { (index, nameAndType) -> listOf(
createValueParameterForDoResume(Name.identifier(nameAndType.first), nameAndType.second, index) ValueParameterDescriptorImpl(
}, this, null, 0, Annotations.EMPTY, Name.identifier(SUSPEND_CALL_RESULT_NAME),
classDescriptor.module.getResult(classDescriptor.builtIns.anyType),
declaresDefaultValue = false, isCrossinline = false, isNoinline = false, varargElementType = null,
SourceElement.NO_SOURCE
)
),
builtIns.nullableAnyType, builtIns.nullableAnyType,
Modality.FINAL, Modality.FINAL,
DescriptorVisibilities.PUBLIC, DescriptorVisibilities.PUBLIC,
@@ -89,15 +88,6 @@ abstract class AbstractCoroutineCodegen(
) )
} }
private fun FunctionDescriptor.createValueParameterForDoResume(name: Name, type: KotlinType, index: Int) =
ValueParameterDescriptorImpl(
this, null, index, Annotations.EMPTY, name,
type,
declaresDefaultValue = false, isCrossinline = false,
isNoinline = false,
varargElementType = null, source = SourceElement.NO_SOURCE
)
override fun generateConstructor(): Method { override fun generateConstructor(): Method {
val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType) val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType)
val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray() val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray()
@@ -119,7 +109,7 @@ abstract class AbstractCoroutineCodegen(
iv.iconst(funDescriptor.arity) iv.iconst(funDescriptor.arity)
} }
iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE) iv.load(argTypes.sumOf { it.size }, AsmTypes.OBJECT_TYPE)
val parameters = val parameters =
if (passArityToSuperClass) if (passArityToSuperClass)
@@ -392,7 +382,7 @@ class CoroutineCodegenForLambda private constructor(
if (generateErasedCreate) { if (generateErasedCreate) {
load(allFunctionParameters().size + 1, AsmTypes.OBJECT_TYPE) load(allFunctionParameters().size + 1, AsmTypes.OBJECT_TYPE)
} else { } else {
load(allFunctionParameters().map { typeMapper.mapType(it.type).size }.sum() + 1, AsmTypes.OBJECT_TYPE) load(allFunctionParameters().sumOf { typeMapper.mapType(it.type).size } + 1, AsmTypes.OBJECT_TYPE)
} }
} }
@@ -482,7 +472,9 @@ class CoroutineCodegenForLambda private constructor(
val name = val name =
if (parameter is ReceiverParameterDescriptor) if (parameter is ReceiverParameterDescriptor)
DescriptorAsmUtil.getNameForReceiverParameter(originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings) DescriptorAsmUtil.getNameForReceiverParameter(
originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings
)
else else
(getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString()) (getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString())
val label = Label() val label = Label()
@@ -705,38 +697,6 @@ class CoroutineCodegenForNamedFunction private constructor(
) )
} }
private fun generateGetLabelMethod() {
val mv = v.newMethod(
JvmDeclarationOrigin.NO_ORIGIN,
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
null,
null
)
mv.visitCode()
labelFieldStackValue.put(Type.INT_TYPE, InstructionAdapter(mv))
mv.visitInsn(Opcodes.IRETURN)
mv.visitEnd()
}
private fun generateSetLabelMethod() {
val mv = v.newMethod(
JvmDeclarationOrigin.NO_ORIGIN,
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
"setLabel",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
null,
null
)
mv.visitCode()
labelFieldStackValue.store(StackValue.local(1, Type.INT_TYPE), InstructionAdapter(mv))
mv.visitInsn(Opcodes.RETURN)
mv.visitEnd()
}
override fun generateKotlinMetadataAnnotation() { override fun generateKotlinMetadataAnnotation() {
val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor) val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor)
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av -> writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av ->
@@ -1110,7 +1110,7 @@ inline fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnLis
return tmpMethodNode.instructions return tmpMethodNode.instructions
} }
fun Type.normalize() = fun Type.normalize(): Type =
when (sort) { when (sort) {
Type.ARRAY, Type.OBJECT -> AsmTypes.OBJECT_TYPE Type.ARRAY, Type.OBJECT -> AsmTypes.OBJECT_TYPE
else -> this else -> this
@@ -1156,7 +1156,7 @@ internal operator fun List<SuspensionPoint>.contains(insn: AbstractInsnNode): Bo
any { insn in it } any { insn in it }
internal fun getLastParameterIndex(desc: String, access: Int) = internal fun getLastParameterIndex(desc: String, access: Int) =
Type.getArgumentTypes(desc).dropLast(1).map { it.size }.sum() + (if (!isStatic(access)) 1 else 0) Type.getArgumentTypes(desc).dropLast(1).sumOf { it.size } + (if (!isStatic(access)) 1 else 0)
private fun getParameterTypesForCoroutineConstructor(desc: String, hasDispatchReceiver: Boolean, thisName: String) = private fun getParameterTypesForCoroutineConstructor(desc: String, hasDispatchReceiver: Boolean, thisName: String) =
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() + listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
@@ -1192,6 +1192,7 @@ internal fun replaceFakeContinuationsWithRealOnes(methodNode: MethodNode, contin
} }
} }
@Suppress("unused")
private fun MethodNode.nodeTextWithLiveness(liveness: List<VariableLivenessFrame>): String = private fun MethodNode.nodeTextWithLiveness(liveness: List<VariableLivenessFrame>): String =
liveness.zip(this.instructions.asSequence().toList()).joinToString("\n") { (a, b) -> "$a|${b.insnText}" } liveness.zip(this.instructions.asSequence().toList()).joinToString("\n") { (a, b) -> "$a|${b.insnText}" }
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMar
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.codegen.inline.preprocessSuspendMarkers import org.jetbrains.kotlin.codegen.inline.preprocessSuspendMarkers
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
@@ -37,9 +35,7 @@ class SuspendFunctionGenerationStrategy(
private val containingClassInternalName: String, private val containingClassInternalName: String,
private val functionCodegen: FunctionCodegen private val functionCodegen: FunctionCodegen
) : FunctionGenerationStrategy.CodegenBased(state) { ) : FunctionGenerationStrategy.CodegenBased(state) {
private lateinit var codegen: ExpressionCodegen private lateinit var codegen: ExpressionCodegen
private val languageVersionSettings: LanguageVersionSettings = state.configuration.languageVersionSettings
private val classBuilderForCoroutineState by lazy { private val classBuilderForCoroutineState by lazy {
state.factory.newVisitor( state.factory.newVisitor(
@@ -61,7 +57,9 @@ class SuspendFunctionGenerationStrategy(
} }
val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc) val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc)
if (originalSuspendDescriptor.isInline) { if (originalSuspendDescriptor.isInline) {
return SuspendForInlineCopyingMethodVisitor(stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false) return SuspendForInlineCopyingMethodVisitor(
stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false
)
} }
if (state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true) { if (state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true) {
return AddConstructorCallForCoroutineRegeneration( return AddConstructorCallForCoroutineRegeneration(
@@ -70,7 +68,6 @@ class SuspendFunctionGenerationStrategy(
containingClassInternalName, containingClassInternalName,
originalSuspendDescriptor.dispatchReceiverParameter != null, originalSuspendDescriptor.dispatchReceiverParameter != null,
containingClassInternalNameOrNull(), containingClassInternalNameOrNull(),
languageVersionSettings
) )
} }
return stateMachineBuilder return stateMachineBuilder
@@ -136,7 +133,6 @@ class SuspendFunctionGenerationStrategy(
private val containingClassInternalName: String, private val containingClassInternalName: String,
private val needDispatchReceiver: Boolean, private val needDispatchReceiver: Boolean,
private val internalNameForDispatchReceiver: String?, private val internalNameForDispatchReceiver: String?,
private val languageVersionSettings: LanguageVersionSettings
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) { ) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState) private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
override fun performTransformations(methodNode: MethodNode) { override fun performTransformations(methodNode: MethodNode) {
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.coroutines.isSuspendLambda import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -146,9 +145,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
ExpressionValueArgument(arguments) ExpressionValueArgument(arguments)
) )
val newTypeArguments = newCandidateDescriptor.typeParameters.map { val newTypeArguments = newCandidateDescriptor.typeParameters.associateWith {
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()) typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()
}.toMap() }
newCall.setSubstitutor( newCall.setSubstitutor(
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor() TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
@@ -440,7 +439,9 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when
else -> false else -> false
} }
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda() = isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda(): Boolean =
isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
@JvmField @JvmField
val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType() val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
@@ -451,4 +452,4 @@ fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean {
name.asString() != INVOKE_SUSPEND_METHOD_NAME name.asString() != INVOKE_SUSPEND_METHOD_NAME
) return false ) return false
return containingDeclaration is SyntheticClassDescriptorForLambda return containingDeclaration is SyntheticClassDescriptorForLambda
} }
@@ -30,6 +30,7 @@ class CoroutineTransformer(
private val superClassName: String private val superClassName: String
) { ) {
private val state = inliningContext.state private val state = inliningContext.state
// If we inline into inline function, we should generate both method with state-machine for Java interop and method without // If we inline into inline function, we should generate both method with state-machine for Java interop and method without
// state-machine for further transformation/inlining. // state-machine for further transformation/inlining.
private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline
@@ -152,7 +153,7 @@ class CoroutineTransformer(
context.continuationBuilders[continuationClassName] = classBuilder context.continuationBuilders[continuationClassName] = classBuilder
} }
fun unregisterClassBuilder(continuationClassName: String) = private fun unregisterClassBuilder(continuationClassName: String): ClassBuilder? =
(inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName) (inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName)
// If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method // If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method