IR KT-50039 don't initialize outer 'this' in delegating constructor
This commit is contained in:
+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> {
|
||||
|
||||
Reference in New Issue
Block a user