Avoid eager deserialization of array classes in ArrayConstructorLowering

This commit is contained in:
Steven Schäfer
2019-07-25 14:16:21 +02:00
committed by max-kammerer
parent 2910d8e9b2
commit 3ce731cf7c
@@ -27,13 +27,15 @@ class ArrayConstructorLowering(val context: CommonBackendContext) : IrElementTra
} }
// Array(size, init) -> Array(size) // Array(size, init) -> Array(size)
private val arrayInlineToSizeCtor: Map<IrFunctionSymbol, IrFunctionSymbol> = private fun arrayInlineToSizeConstructor(irConstructor: IrConstructor): IrFunctionSymbol? {
(context.irBuiltIns.primitiveArrays + context.irBuiltIns.arrayClass).associate { arrayClass -> val clazz = irConstructor.constructedClass.symbol
val fromInit = arrayClass.constructors.single { it.owner.valueParameters.size == 2 } return when {
val fromSize = arrayClass.constructors.find { it.owner.valueParameters.size == 1 } irConstructor.valueParameters.size != 2 -> null
?: context.ir.symbols.arrayOfNulls // Array<T> has no unary constructor: it can only exist for Array<T?> clazz == context.irBuiltIns.arrayClass -> context.ir.symbols.arrayOfNulls // Array<T> has no unary constructor: it can only exist for Array<T?>
fromInit to fromSize context.irBuiltIns.primitiveArrays.contains(clazz) -> clazz.constructors.single { it.owner.valueParameters.size == 1 }
else -> null
} }
}
private fun IrExpression.asSingleArgumentLambda(): IrSimpleFunction? { private fun IrExpression.asSingleArgumentLambda(): IrSimpleFunction? {
// A lambda is represented as a block with a function declaration and a reference to it. // A lambda is represented as a block with a function declaration and a reference to it.
@@ -50,7 +52,7 @@ class ArrayConstructorLowering(val context: CommonBackendContext) : IrElementTra
} }
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
val sizeConstructor = arrayInlineToSizeCtor[expression.symbol] val sizeConstructor = arrayInlineToSizeConstructor(expression.symbol.owner)
?: return super.visitConstructorCall(expression) ?: return super.visitConstructorCall(expression)
// inline fun <reified T> Array(size: Int, invokable: (Int) -> T): Array<T> { // inline fun <reified T> Array(size: Int, invokable: (Int) -> T): Array<T> {
// val result = arrayOfNulls<T>(size) // val result = arrayOfNulls<T>(size)