Do not generate fields for unused suspend lambda parameters
This also allows us to not spill them in the lambda. But, disable this optimization for local named functions. #KT-16222 In progress
This commit is contained in:
@@ -52,7 +52,6 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -77,6 +76,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.cfg.index
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -229,6 +231,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
|
||||
override fun generateClosureBody() {
|
||||
for (parameter in allFunctionParameters()) {
|
||||
if (parameter.isUnused()) continue
|
||||
val fieldInfo = parameter.getFieldInfoForCoroutineLambdaParameter()
|
||||
v.newField(
|
||||
OtherOrigin(parameter),
|
||||
@@ -241,6 +244,10 @@ class CoroutineCodegenForLambda private constructor(
|
||||
generateResumeImpl()
|
||||
}
|
||||
|
||||
private fun ParameterDescriptor.isUnused(): Boolean =
|
||||
originalSuspendFunctionDescriptor is AnonymousFunctionDescriptor &&
|
||||
bindingContext[BindingContext.SUSPEND_LAMBDA_PARAMETER_USED, originalSuspendFunctionDescriptor to index()] != true
|
||||
|
||||
private val generateErasedCreate: Boolean = allFunctionParameters().size <= 1
|
||||
|
||||
private val doNotGenerateInvokeBridge: Boolean = !originalSuspendFunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda()
|
||||
@@ -398,39 +405,41 @@ class CoroutineCodegenForLambda private constructor(
|
||||
var index = 1
|
||||
for (parameter in allFunctionParameters()) {
|
||||
val fieldInfoForCoroutineLambdaParameter = parameter.getFieldInfoForCoroutineLambdaParameter()
|
||||
if (isBigArity) {
|
||||
load(cloneIndex, fieldInfoForCoroutineLambdaParameter.ownerType)
|
||||
load(1, AsmTypes.OBJECT_TYPE)
|
||||
iconst(index - 1)
|
||||
aload(AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
putfield(
|
||||
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType.descriptor
|
||||
)
|
||||
} else {
|
||||
if (generateErasedCreate) {
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
if (!parameter.isUnused()) {
|
||||
if (isBigArity) {
|
||||
load(cloneIndex, fieldInfoForCoroutineLambdaParameter.ownerType)
|
||||
load(1, AsmTypes.OBJECT_TYPE)
|
||||
iconst(index - 1)
|
||||
aload(AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
putfield(
|
||||
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType.descriptor
|
||||
)
|
||||
} else {
|
||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||
if (generateErasedCreate) {
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
} else {
|
||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||
}
|
||||
AsmUtil.genAssignInstanceFieldFromParam(
|
||||
fieldInfoForCoroutineLambdaParameter,
|
||||
index,
|
||||
this,
|
||||
cloneIndex,
|
||||
generateErasedCreate
|
||||
)
|
||||
}
|
||||
AsmUtil.genAssignInstanceFieldFromParam(
|
||||
fieldInfoForCoroutineLambdaParameter,
|
||||
index,
|
||||
this,
|
||||
cloneIndex,
|
||||
generateErasedCreate
|
||||
)
|
||||
}
|
||||
index += if (isBigArity || generateErasedCreate) 1 else fieldInfoForCoroutineLambdaParameter.fieldType.size
|
||||
}
|
||||
@@ -442,6 +451,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
|
||||
private fun ExpressionCodegen.initializeCoroutineParameters() {
|
||||
for (parameter in allFunctionParameters()) {
|
||||
if (parameter.isUnused()) continue
|
||||
val fieldStackValue =
|
||||
StackValue.field(
|
||||
parameter.getFieldInfoForCoroutineLambdaParameter(), generateThisOrOuter(context.thisDescriptor, false)
|
||||
@@ -463,7 +473,11 @@ class CoroutineCodegenForLambda private constructor(
|
||||
v.visitLocalVariable(name, mappedType.descriptor, null, label, endLabel, newIndex)
|
||||
}
|
||||
|
||||
initializeVariablesForDestructuredLambdaParameters(this, originalSuspendFunctionDescriptor.valueParameters, endLabel)
|
||||
initializeVariablesForDestructuredLambdaParameters(
|
||||
this,
|
||||
originalSuspendFunctionDescriptor.valueParameters.filter { !it.isUnused() },
|
||||
endLabel
|
||||
)
|
||||
}
|
||||
|
||||
private fun allFunctionParameters(): List<ParameterDescriptor> =
|
||||
|
||||
Reference in New Issue
Block a user