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