Do not generate the field for unused parameters in suspend lambdas

This commit is contained in:
Iaroslav Postovalov
2020-12-09 22:43:06 +07:00
committed by Ilmir Usmanov
parent f49cf2d5ca
commit 6f34f00c61
6 changed files with 45 additions and 4 deletions
+7
View File
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ASMIdeaPluginConfiguration">
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ClientPropertiesManager">
<properties class="javax.swing.JPanel">
<property name="BorderFactoryClass" class="java.lang.String" />
@@ -82,6 +86,9 @@
</set>
</option>
</component>
<component name="SuppressKotlinCodeStyleNotification">
<option name="disableForAll" value="true" />
</component>
<component name="WebServicesPlugin" addRequiredLibraries="true" />
<component name="com.sixrr.metrics.MetricsReloaded">
<option name="selectedProfile" value="" />
@@ -1525,6 +1525,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
}
@TestMetadata("unusedParamNotSpill.kt")
public void testUnusedParamNotSpill() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
@@ -29,11 +30,11 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
@@ -138,6 +139,7 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
}
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
private fun generateContinuationClassForLambda(reference: IrFunctionReference, parent: IrDeclarationParent): IrClass =
context.irFactory.buildClass {
name = SpecialNames.NO_NAME_PROVIDED
@@ -163,10 +165,22 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
+ context.irBuiltIns.anyNType
)
superTypes = listOf(suspendLambda.defaultType, functionNType)
val usedParams = mutableListOf<IrSymbolOwner>()
// marking the parameters referenced in the function
function.acceptChildrenVoid(
object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) =
if (element is IrDeclarationReference && element.symbol is IrValueParameterSymbol && element.symbol.owner in function.explicitParameters)
usedParams += element.symbol.owner
else
Unit
},
)
addField(COROUTINE_LABEL_FIELD_NAME, context.irBuiltIns.intType, JavaDescriptorVisibilities.PACKAGE_VISIBILITY)
val parametersFields = function.explicitParameters.map {
val parametersFields = function.explicitParameters.filter { it in usedParams }.map {
addField {
// Rename `$this` to avoid being caught by inlineCodegenUtils.isCapturedFieldName()
name = if (it.index < 0) Name.identifier("p\$") else it.name
@@ -0,0 +1,5 @@
val f: suspend (Int) -> Unit = { unused ->
}
// 0 GETFIELD p\$0
// 0 PUTFIELD p\$0
@@ -1515,6 +1515,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
}
@TestMetadata("unusedParamNotSpill.kt")
public void testUnusedParamNotSpill() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");
@@ -1525,6 +1525,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
}
@TestMetadata("unusedParamNotSpill.kt")
public void testUnusedParamNotSpill() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");