IR KT-50039 don't initialize outer 'this' in delegating constructor
This commit is contained in:
+6
@@ -22317,6 +22317,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
+14
-2
@@ -68,8 +68,11 @@ class InnerClassesLowering(val context: BackendContext, private val innerClasses
|
||||
if (blockBody !is IrBlockBody) throw AssertionError("Unexpected constructor body: ${irConstructor.body}")
|
||||
|
||||
loweredConstructor.body = context.irFactory.createBlockBody(blockBody.startOffset, blockBody.endOffset) {
|
||||
context.createIrBuilder(irConstructor.symbol, irConstructor.startOffset, irConstructor.endOffset).apply {
|
||||
statements.add(0, irSetField(irGet(irClass.thisReceiver!!), parentThisField, irGet(outerThisParameter)))
|
||||
|
||||
if (irConstructor.shouldInitializeOuterThis()) {
|
||||
context.createIrBuilder(irConstructor.symbol, irConstructor.startOffset, irConstructor.endOffset).apply {
|
||||
statements.add(0, irSetField(irGet(irClass.thisReceiver!!), parentThisField, irGet(outerThisParameter)))
|
||||
}
|
||||
}
|
||||
|
||||
statements.addAll(blockBody.statements)
|
||||
@@ -90,6 +93,15 @@ class InnerClassesLowering(val context: BackendContext, private val innerClasses
|
||||
return loweredConstructor
|
||||
}
|
||||
|
||||
private fun IrConstructor.shouldInitializeOuterThis(): Boolean {
|
||||
val irBlockBody = body as? IrBlockBody ?: return false
|
||||
// Constructors are either delegating to a constructor of super class (and initializing an instance of this class),
|
||||
// or delegating to a constructor of this class.
|
||||
// Don't initialize outer 'this' in constructor delegating to this,
|
||||
// otherwise final 'this$0' field will be initialized twice (in delegating constructor and in original constructor),
|
||||
// which is legal, but causes a performance regression on JVM (KT-50039).
|
||||
return irBlockBody.statements.any { it is IrInstanceInitializerCall }
|
||||
}
|
||||
}
|
||||
|
||||
private fun InnerClassesSupport.primaryConstructorParameterMap(originalConstructor: IrConstructor): Map<IrValueParameter, IrValueParameter> {
|
||||
|
||||
Vendored
+5
@@ -10,3 +10,8 @@ class A {
|
||||
}
|
||||
|
||||
fun box() = A().box()
|
||||
|
||||
// CHECK_BYTECODE_TEXT
|
||||
// 1 PUTFIELD A\$Inner\.this\$0 : LA;
|
||||
// ^ A$Inner.this$0 SHOULD be written in primary constructor of A$Inner,
|
||||
// and SHOULD NOT be written in corresponding default arguments stub.
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Outer(val outer: String) {
|
||||
open inner class Inner(val inner: String) {
|
||||
constructor() : this("K")
|
||||
|
||||
fun test() = outer + inner
|
||||
}
|
||||
|
||||
fun obj(): Inner =
|
||||
object : Inner() {}
|
||||
}
|
||||
|
||||
fun box() = Outer("O").obj().test()
|
||||
|
||||
// CHECK_BYTECODE_TEXT
|
||||
// 1 PUTFIELD Outer\$Inner\.this\$0 : LOuter;
|
||||
// ^ Outer$Inner.this$0 SHOULD be written in primary constructor of Outer$Inner,
|
||||
// and SHOULD NOT be written in delegating constructor.
|
||||
+6
@@ -21945,6 +21945,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
+6
@@ -22317,6 +22317,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
+5
@@ -18360,6 +18360,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsLocalCaptureInSuperCall.kt");
|
||||
|
||||
+6
@@ -17507,6 +17507,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
+6
@@ -17471,6 +17471,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
+5
@@ -14807,6 +14807,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsLocalCaptureInSuperCall.kt");
|
||||
|
||||
+6
@@ -18390,6 +18390,12 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsInnerWithDelegatingConstructor.kt")
|
||||
public void testObjectExtendsInnerWithDelegatingConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/innerNested/superConstructorCall/objectExtendsInnerWithDelegatingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectExtendsLocalCaptureInSuperCall.kt")
|
||||
public void testObjectExtendsLocalCaptureInSuperCall() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user