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 languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
protected val methodToImplement =
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>) =
protected val methodToImplement: FunctionDescriptor =
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
).apply {
initialize(
null,
classDescriptor.thisAsReceiverParameter,
emptyList(),
parameters.withIndex().map { (index, nameAndType) ->
createValueParameterForDoResume(Name.identifier(nameAndType.first), nameAndType.second, index)
},
listOf(
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,
Modality.FINAL,
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 {
val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType)
val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray()
@@ -119,7 +109,7 @@ abstract class AbstractCoroutineCodegen(
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 =
if (passArityToSuperClass)
@@ -392,7 +382,7 @@ class CoroutineCodegenForLambda private constructor(
if (generateErasedCreate) {
load(allFunctionParameters().size + 1, AsmTypes.OBJECT_TYPE)
} 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 =
if (parameter is ReceiverParameterDescriptor)
DescriptorAsmUtil.getNameForReceiverParameter(originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings)
DescriptorAsmUtil.getNameForReceiverParameter(
originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings
)
else
(getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString())
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() {
val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor)
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av ->
@@ -1110,7 +1110,7 @@ inline fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnLis
return tmpMethodNode.instructions
}
fun Type.normalize() =
fun Type.normalize(): Type =
when (sort) {
Type.ARRAY, Type.OBJECT -> AsmTypes.OBJECT_TYPE
else -> this
@@ -1156,7 +1156,7 @@ internal operator fun List<SuspensionPoint>.contains(insn: AbstractInsnNode): Bo
any { insn in it }
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) =
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 =
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.preprocessSuspendMarkers
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.FunctionDescriptor
import org.jetbrains.kotlin.psi.KtFunction
@@ -37,9 +35,7 @@ class SuspendFunctionGenerationStrategy(
private val containingClassInternalName: String,
private val functionCodegen: FunctionCodegen
) : FunctionGenerationStrategy.CodegenBased(state) {
private lateinit var codegen: ExpressionCodegen
private val languageVersionSettings: LanguageVersionSettings = state.configuration.languageVersionSettings
private val classBuilderForCoroutineState by lazy {
state.factory.newVisitor(
@@ -61,7 +57,9 @@ class SuspendFunctionGenerationStrategy(
}
val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc)
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) {
return AddConstructorCallForCoroutineRegeneration(
@@ -70,7 +68,6 @@ class SuspendFunctionGenerationStrategy(
containingClassInternalName,
originalSuspendDescriptor.dispatchReceiverParameter != null,
containingClassInternalNameOrNull(),
languageVersionSettings
)
}
return stateMachineBuilder
@@ -136,7 +133,6 @@ class SuspendFunctionGenerationStrategy(
private val containingClassInternalName: String,
private val needDispatchReceiver: Boolean,
private val internalNameForDispatchReceiver: String?,
private val languageVersionSettings: LanguageVersionSettings
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
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.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -146,9 +145,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
ExpressionValueArgument(arguments)
)
val newTypeArguments = newCandidateDescriptor.typeParameters.map {
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
}.toMap()
val newTypeArguments = newCandidateDescriptor.typeParameters.associateWith {
typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()
}
newCall.setSubstitutor(
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
@@ -440,7 +439,9 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when
else -> false
}
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda() = isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda(): Boolean =
isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
@JvmField
val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
@@ -451,4 +452,4 @@ fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean {
name.asString() != INVOKE_SUSPEND_METHOD_NAME
) return false
return containingDeclaration is SyntheticClassDescriptorForLambda
}
}
@@ -30,6 +30,7 @@ class CoroutineTransformer(
private val superClassName: String
) {
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
// state-machine for further transformation/inlining.
private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline
@@ -152,7 +153,7 @@ class CoroutineTransformer(
context.continuationBuilders[continuationClassName] = classBuilder
}
fun unregisterClassBuilder(continuationClassName: String) =
private fun unregisterClassBuilder(continuationClassName: String): ClassBuilder? =
(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