mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
JVM_IR: do not inline reads of constructor arguments into accessors
This commit is contained in:
@@ -13316,6 +13316,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToGenericJavaProperty.kt")
|
||||
public void testDelegateToGenericJavaProperty() throws Exception {
|
||||
|
||||
@@ -59,7 +59,7 @@ val IrDeclaration.parentsWithSelf: Sequence<IrDeclarationParent>
|
||||
get() = generateSequence(this as? IrDeclarationParent) { (it as? IrDeclaration)?.parent }
|
||||
|
||||
val IrDeclaration.parents: Sequence<IrDeclarationParent>
|
||||
get() = parentsWithSelf.drop(1)
|
||||
get() = generateSequence(parent) { (it as? IrDeclaration)?.parent }
|
||||
|
||||
object BOUND_VALUE_PARAMETER : IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
|
||||
@@ -85,14 +86,16 @@ private class PropertyReferenceDelegationTransformer(val context: JvmBackendCont
|
||||
private val IrStatement.isStdlibCall: Boolean
|
||||
get() = this is IrCall && symbol.owner.getPackageFragment()?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME
|
||||
|
||||
// Constants, object accesses, reads of immutable variables, and reads of immutable properties in the same file
|
||||
// don't need to be cached in a field; reads of mutable properties have to be as we should ignore further assignments
|
||||
// to those, and immutable properties in other files might become mutable without breaking ABI.
|
||||
private fun IrExpression.canInline(currentFile: IrFile): Boolean = when (this) {
|
||||
is IrGetValue -> !symbol.owner.let { it is IrVariable && it.isVar }
|
||||
is IrGetField -> symbol.owner.let { it.isFinal && it.fileParent == currentFile } && receiver?.canInline(currentFile) != false
|
||||
is IrCall -> symbol.owner.let { it.isFinalDefaultValGetter && it.fileParent == currentFile } &&
|
||||
dispatchReceiver?.canInline(currentFile) != false && extensionReceiver?.canInline(currentFile) != false
|
||||
// Some receivers don't need to be stored in fields and can be reevaluated every time an accessor is called:
|
||||
private fun IrExpression.canInline(visibleScopes: Set<IrDeclarationParent>): Boolean = when (this) {
|
||||
// Reads of immutable variables are stable, but value parameters of the constructor are not in scope:
|
||||
is IrGetValue -> symbol.owner.let { !(it is IrVariable && it.isVar) && it.parent in visibleScopes }
|
||||
// Reads of final fields of stable values are stable, but fields in other files can become non-final:
|
||||
is IrGetField -> symbol.owner.let { it.isFinal && it.fileParent in visibleScopes } && receiver?.canInline(visibleScopes) != false
|
||||
// Same applies to reads of properties with default getters, but non-final properties may be overridden by `var`s:
|
||||
is IrCall -> symbol.owner.let { it.isFinalDefaultValGetter && it.fileParent in visibleScopes } &&
|
||||
dispatchReceiver?.canInline(visibleScopes) != false && extensionReceiver?.canInline(visibleScopes) != false
|
||||
// Constants and singleton object accesses are always stable:
|
||||
else -> isTrivial()
|
||||
}
|
||||
|
||||
@@ -134,7 +137,7 @@ private class PropertyReferenceDelegationTransformer(val context: JvmBackendCont
|
||||
|
||||
val receiver = (delegate.dispatchReceiver ?: delegate.extensionReceiver)
|
||||
?.transform(this@PropertyReferenceDelegationTransformer, null)
|
||||
backingField = receiver?.takeIf { !it.canInline(fileParent) }?.let {
|
||||
backingField = receiver?.takeIf { !it.canInline(parents.toSet()) }?.let {
|
||||
context.irFactory.buildField {
|
||||
updateFrom(oldField)
|
||||
name = Name.identifier("${this@transform.name}\$receiver")
|
||||
|
||||
8
compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt
vendored
Normal file
8
compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
class C(val x: String)
|
||||
|
||||
class D(c: C) {
|
||||
val x by c::x
|
||||
}
|
||||
|
||||
fun box(): String = D(C("OK")).x
|
||||
@@ -13256,6 +13256,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToGenericJavaProperty.kt")
|
||||
public void testDelegateToGenericJavaProperty() throws Exception {
|
||||
|
||||
@@ -13316,6 +13316,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegateToGenericJavaProperty.kt")
|
||||
public void testDelegateToGenericJavaProperty() throws Exception {
|
||||
|
||||
@@ -10775,6 +10775,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToGenericJavaProperty.kt")
|
||||
public void testDelegateToGenericJavaProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToGenericJavaProperty.kt");
|
||||
|
||||
@@ -9584,6 +9584,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToOpenProperty.kt")
|
||||
public void testDelegateToOpenProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt");
|
||||
|
||||
@@ -8990,6 +8990,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToOpenProperty.kt")
|
||||
public void testDelegateToOpenProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt");
|
||||
|
||||
@@ -8990,6 +8990,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToAnotherWithSideEffects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToConstructorParameter.kt")
|
||||
public void testDelegateToConstructorParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToConstructorParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegateToOpenProperty.kt")
|
||||
public void testDelegateToOpenProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToOpenProperty.kt");
|
||||
|
||||
Reference in New Issue
Block a user