JVM_IR: do not inherit delegated property trackers
This is no longer needed now that lambdas are generated before `$$delegatedProperties`.
This commit is contained in:
compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxInlineCodegenTestGenerated.java
Generated
+5
@@ -1739,6 +1739,11 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
+17
-18
@@ -91,9 +91,12 @@ class ClassCodegen private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: the order of entries in this set depends on the order in which methods are generated; this means it is unstable
|
||||
// under incremental compilation, as calls to `inline fun`s declared in this class cause them to be generated out of order.
|
||||
private val innerClasses = linkedSetOf<IrClass>()
|
||||
|
||||
private var regeneratedObjectNameGenerators = mutableMapOf<String, NameGenerator>()
|
||||
// TODO: the names produced by generators in this map depend on the order in which methods are generated; see above.
|
||||
private val regeneratedObjectNameGenerators = mutableMapOf<String, NameGenerator>()
|
||||
|
||||
fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator {
|
||||
val name = if (function.name.isSpecial) "special" else function.name.asString()
|
||||
@@ -104,19 +107,15 @@ class ClassCodegen private constructor(
|
||||
|
||||
private var generated = false
|
||||
|
||||
fun generate(parentDelegatedPropertyTracker: DelegatedPropertyOptimizer? = null) {
|
||||
fun generate() {
|
||||
// TODO: reject repeated generate() calls; currently, these can happen for objects in finally
|
||||
// blocks since they are `accept`ed once per each CFG edge out of the try-finally.
|
||||
if (generated) return
|
||||
generated = true
|
||||
|
||||
// We remove unused cached KProperties.
|
||||
val classDelegatedPropertiesArray = irClass.fields.singleOrNull {
|
||||
it.origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE
|
||||
}
|
||||
val delegatedPropertyTracker =
|
||||
if (classDelegatedPropertiesArray != null) DelegatedPropertyOptimizer() else parentDelegatedPropertyTracker
|
||||
|
||||
// We remove reads of `$$delegatedProperties` (and the field itself) if they are not in fact used for anything.
|
||||
val delegatedProperties = irClass.fields.singleOrNull { it.origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE }
|
||||
val delegatedPropertyOptimizer = if (delegatedProperties != null) DelegatedPropertyOptimizer() else null
|
||||
// Generating a method node may cause the addition of a field with an initializer if an inline function
|
||||
// call uses `assert` and the JVM assertions mode is enabled. To avoid concurrent modification errors,
|
||||
// there is a very specific generation order.
|
||||
@@ -124,14 +123,14 @@ class ClassCodegen private constructor(
|
||||
// 1. Any method other than `<clinit>` can add a field and a `<clinit>` statement:
|
||||
for (method in irClass.declarations.filterIsInstance<IrFunction>()) {
|
||||
if (method.name.asString() != "<clinit>") {
|
||||
generateMethod(method, smap, delegatedPropertyTracker)
|
||||
generateMethod(method, smap, delegatedPropertyOptimizer)
|
||||
}
|
||||
}
|
||||
// 2. `<clinit>` itself can add a field, but the statement is generated via the `return init` hack:
|
||||
irClass.functions.find { it.name.asString() == "<clinit>" }?.let { generateMethod(it, smap, delegatedPropertyTracker) }
|
||||
irClass.functions.find { it.name.asString() == "<clinit>" }?.let { generateMethod(it, smap, delegatedPropertyOptimizer) }
|
||||
// 3. Now we have all the fields (`$$delegatedProperties` might be redundant if all reads were optimized out):
|
||||
for (field in irClass.fields) {
|
||||
if (field !== classDelegatedPropertiesArray || delegatedPropertyTracker?.needsDelegatedProperties == true) {
|
||||
if (field !== delegatedProperties || delegatedPropertyOptimizer?.needsDelegatedProperties == true) {
|
||||
generateField(field)
|
||||
}
|
||||
}
|
||||
@@ -139,7 +138,7 @@ class ClassCodegen private constructor(
|
||||
// everything moved to the outer class has already been recorded in `globalSerializationBindings`.
|
||||
for (declaration in irClass.declarations) {
|
||||
if (declaration is IrClass) {
|
||||
getOrCreate(declaration, context).generate(delegatedPropertyTracker)
|
||||
getOrCreate(declaration, context).generate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,14 +312,14 @@ class ClassCodegen private constructor(
|
||||
|
||||
private val generatedInlineMethods = mutableMapOf<IrFunction, SMAPAndMethodNode>()
|
||||
|
||||
fun generateMethodNode(method: IrFunction, delegatedPropertyOptimizer: DelegatedPropertyOptimizer?): SMAPAndMethodNode {
|
||||
fun generateMethodNode(method: IrFunction): SMAPAndMethodNode {
|
||||
if (!method.isInline && !method.isSuspend) {
|
||||
// Inline methods can be used multiple times by `IrSourceCompilerForInline`, suspend methods
|
||||
// could be used twice if they capture crossinline lambdas, and everything else is only
|
||||
// generated by `generateMethod` below so does not need caching.
|
||||
return FunctionCodegen(method, this).generate(delegatedPropertyOptimizer)
|
||||
return FunctionCodegen(method, this).generate()
|
||||
}
|
||||
val (node, smap) = generatedInlineMethods.getOrPut(method) { FunctionCodegen(method, this).generate(delegatedPropertyOptimizer) }
|
||||
val (node, smap) = generatedInlineMethods.getOrPut(method) { FunctionCodegen(method, this).generate() }
|
||||
val copy = with(node) { MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions.toTypedArray()) }
|
||||
node.instructions.resetLabels()
|
||||
node.accept(copy)
|
||||
@@ -333,7 +332,7 @@ class ClassCodegen private constructor(
|
||||
return
|
||||
}
|
||||
|
||||
val (node, smap) = generateMethodNode(method, delegatedPropertyOptimizer)
|
||||
val (node, smap) = generateMethodNode(method)
|
||||
if (delegatedPropertyOptimizer != null) {
|
||||
delegatedPropertyOptimizer.transform(node)
|
||||
if (method.name.asString() == "<clinit>") {
|
||||
@@ -358,7 +357,7 @@ class ClassCodegen private constructor(
|
||||
if (method.isSuspend) continuationClassCodegen.value.visitor else visitor
|
||||
}
|
||||
if (continuationClassCodegen.isInitialized() || method.alwaysNeedsContinuation()) {
|
||||
continuationClassCodegen.value.generate(delegatedPropertyOptimizer)
|
||||
continuationClassCodegen.value.generate()
|
||||
}
|
||||
} else {
|
||||
node.accept(smapCopyingVisitor)
|
||||
|
||||
+1
-2
@@ -111,7 +111,6 @@ class ExpressionCodegen(
|
||||
val classCodegen: ClassCodegen,
|
||||
val inlinedInto: ExpressionCodegen?,
|
||||
val smap: SourceMapper,
|
||||
val delegatedPropertyOptimizer: DelegatedPropertyOptimizer?,
|
||||
) : IrElementVisitor<PromisedValue, BlockInfo>, BaseExpressionCodegen {
|
||||
|
||||
var finallyDepth = 0
|
||||
@@ -793,7 +792,7 @@ class ExpressionCodegen(
|
||||
override fun visitClass(declaration: IrClass, data: BlockInfo): PromisedValue {
|
||||
if (declaration.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS) {
|
||||
val childCodegen = ClassCodegen.getOrCreate(declaration, context, generateSequence(this) { it.inlinedInto }.last().irFunction)
|
||||
childCodegen.generate(delegatedPropertyOptimizer)
|
||||
childCodegen.generate()
|
||||
closureReifiedMarkers[declaration] = childCodegen.reifiedTypeParametersUsages
|
||||
}
|
||||
return unitValue
|
||||
|
||||
+5
-14
@@ -46,14 +46,14 @@ class FunctionCodegen(
|
||||
) {
|
||||
private val context = classCodegen.context
|
||||
|
||||
fun generate(delegatedPropertyOptimizer: DelegatedPropertyOptimizer?): SMAPAndMethodNode =
|
||||
fun generate(): SMAPAndMethodNode =
|
||||
try {
|
||||
doGenerate(delegatedPropertyOptimizer)
|
||||
doGenerate()
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("Exception while generating code for:\n${irFunction.dump()}", e)
|
||||
}
|
||||
|
||||
private fun doGenerate(delegatedPropertyOptimizer: DelegatedPropertyOptimizer?): SMAPAndMethodNode {
|
||||
private fun doGenerate(): SMAPAndMethodNode {
|
||||
val signature = context.methodSignatureMapper.mapSignatureWithGeneric(irFunction)
|
||||
val flags = irFunction.calculateMethodFlags()
|
||||
val methodNode = MethodNode(
|
||||
@@ -104,7 +104,7 @@ class FunctionCodegen(
|
||||
generateAnnotationDefaultValueIfNeeded(methodVisitor)
|
||||
SMAP(listOf())
|
||||
} else if (notForInline != null) {
|
||||
val (originalNode, smap) = classCodegen.generateMethodNode(notForInline, delegatedPropertyOptimizer)
|
||||
val (originalNode, smap) = classCodegen.generateMethodNode(notForInline)
|
||||
originalNode.accept(MethodBodyVisitor(methodVisitor))
|
||||
smap
|
||||
} else {
|
||||
@@ -113,16 +113,7 @@ class FunctionCodegen(
|
||||
context.state.globalInlineContext.enterDeclaration(irFunction.suspendFunctionOriginal().toIrBasedDescriptor())
|
||||
try {
|
||||
val adapter = InstructionAdapter(methodVisitor)
|
||||
ExpressionCodegen(
|
||||
irFunction,
|
||||
signature,
|
||||
frameMap,
|
||||
adapter,
|
||||
classCodegen,
|
||||
inlinedInto,
|
||||
sourceMapper,
|
||||
delegatedPropertyOptimizer,
|
||||
).generate()
|
||||
ExpressionCodegen(irFunction, signature, frameMap, adapter, classCodegen, inlinedInto, sourceMapper).generate()
|
||||
} finally {
|
||||
context.state.globalInlineContext.exitDeclaration()
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ object IrInlineDefaultCodegen : IrInlineCallGenerator {
|
||||
isInsideIfCondition: Boolean
|
||||
) {
|
||||
val function = expression.symbol.owner
|
||||
val nodeAndSmap = codegen.classCodegen.generateMethodNode(function, codegen.delegatedPropertyOptimizer)
|
||||
val nodeAndSmap = codegen.classCodegen.generateMethodNode(function)
|
||||
val childSourceMapper = SourceMapCopier(codegen.smap, nodeAndSmap.classSMAP)
|
||||
|
||||
val argsSize =
|
||||
|
||||
+4
-5
@@ -94,16 +94,15 @@ class IrSourceCompilerForInline(
|
||||
get() = codegen.smap
|
||||
|
||||
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode =
|
||||
FunctionCodegen((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, codegen).generate(codegen.delegatedPropertyOptimizer)
|
||||
FunctionCodegen((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, codegen).generate()
|
||||
|
||||
override fun doCreateMethodNodeFromSource(
|
||||
callableDescriptor: FunctionDescriptor,
|
||||
jvmSignature: JvmMethodSignature,
|
||||
callDefault: Boolean,
|
||||
asmMethod: Method
|
||||
): SMAPAndMethodNode {
|
||||
return ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee, null)
|
||||
}
|
||||
): SMAPAndMethodNode =
|
||||
ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee)
|
||||
|
||||
override fun hasFinallyBlocks() = data.hasFinallyBlocks()
|
||||
|
||||
@@ -115,7 +114,7 @@ class IrSourceCompilerForInline(
|
||||
override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) =
|
||||
ExpressionCodegen(
|
||||
codegen.irFunction, codegen.signature, codegen.frameMap, InstructionAdapter(finallyNode), codegen.classCodegen,
|
||||
codegen.inlinedInto, codegen.smap, codegen.delegatedPropertyOptimizer
|
||||
codegen.inlinedInto, codegen.smap
|
||||
).also {
|
||||
it.finallyDepth = curFinallyDepth
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||
// FILE: test.kt
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
inline operator fun String.getValue(t:Any?, p: KProperty<*>): String = p.name + this
|
||||
|
||||
object C {
|
||||
inline fun inlineFun() = {
|
||||
val O by "K"
|
||||
O
|
||||
}()
|
||||
}
|
||||
|
||||
// FILE: box.kt
|
||||
import test.*
|
||||
|
||||
fun box(): String = C.inlineFun()
|
||||
+5
@@ -1739,6 +1739,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
Generated
+5
@@ -1739,6 +1739,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
+5
@@ -1739,6 +1739,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
Generated
+5
@@ -1739,6 +1739,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
+5
@@ -1739,6 +1739,11 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
+5
@@ -1739,6 +1739,11 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
Generated
+5
@@ -1574,6 +1574,11 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
Generated
+5
@@ -1574,6 +1574,11 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
+5
@@ -1574,6 +1574,11 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclaredInLambda.kt")
|
||||
public void testLocalDeclaredInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localDeclaredInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInAnonymousObject.kt")
|
||||
public void testLocalInAnonymousObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/delegatedProperty/localInAnonymousObject.kt");
|
||||
|
||||
Reference in New Issue
Block a user