IR: move defaultParameterDeclarationsCache access up one level

to avoid recomputing overriddenSymbols for fake overrides of default
stubs on repeated calls to generateDefaultsFunction.
This commit is contained in:
pyos
2019-11-14 13:40:03 +01:00
committed by Georgy Bronnikov
parent 70f09a7531
commit a235dd2891
@@ -312,11 +312,13 @@ private fun IrFunction.generateDefaultsFunction(
context: CommonBackendContext, context: CommonBackendContext,
skipInlineMethods: Boolean, skipInlineMethods: Boolean,
skipExternalMethods: Boolean skipExternalMethods: Boolean
): IrFunction? = when { ): IrFunction? = context.ir.defaultParameterDeclarationsCache[this] ?: when {
skipInlineMethods && isInline -> null skipInlineMethods && isInline -> null
skipExternalMethods && isExternalOrInheritedFromExternal() -> null skipExternalMethods && isExternalOrInheritedFromExternal() -> null
valueParameters.any { it.defaultValue != null } -> valueParameters.any { it.defaultValue != null } ->
generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER).also {
context.ir.defaultParameterDeclarationsCache[this] = it
}
this is IrSimpleFunction -> { this is IrSimpleFunction -> {
// If this is an override of a function with default arguments, produce a fake override of a default stub. // If this is an override of a function with default arguments, produce a fake override of a default stub.
val overriddenStubs = overriddenSymbols.mapNotNull { val overriddenStubs = overriddenSymbols.mapNotNull {
@@ -325,6 +327,7 @@ private fun IrFunction.generateDefaultsFunction(
if (overriddenStubs.isNotEmpty()) if (overriddenStubs.isNotEmpty())
generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE).also { generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE).also {
(it as IrSimpleFunction).overriddenSymbols.addAll(overriddenStubs) (it as IrSimpleFunction).overriddenSymbols.addAll(overriddenStubs)
context.ir.defaultParameterDeclarationsCache[this] = it
} }
else else
null null
@@ -332,52 +335,51 @@ private fun IrFunction.generateDefaultsFunction(
else -> null else -> null
} }
private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContext, newOrigin: IrDeclarationOrigin): IrFunction = private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContext, newOrigin: IrDeclarationOrigin): IrFunction {
context.ir.defaultParameterDeclarationsCache.getOrPut(this) { val newFunction = when (this) {
val newFunction = when (this) { is IrConstructor ->
is IrConstructor -> buildConstructor {
buildConstructor { updateFrom(this@generateDefaultsFunctionImpl)
updateFrom(this@generateDefaultsFunctionImpl) origin = newOrigin
origin = newOrigin isExternal = false
isExternal = false isPrimary = false
isPrimary = false isExpect = false
isExpect = false }
} is IrSimpleFunction ->
is IrSimpleFunction -> buildFunWithDescriptorForInlining(descriptor) {
buildFunWithDescriptorForInlining(descriptor) { updateFrom(this@generateDefaultsFunctionImpl)
updateFrom(this@generateDefaultsFunctionImpl) name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default")
name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default") origin = newOrigin
origin = newOrigin modality = Modality.FINAL
modality = Modality.FINAL isExternal = false
isExternal = false isTailrec = false
isTailrec = false }
} else -> throw IllegalStateException("Unknown function type")
else -> throw IllegalStateException("Unknown function type")
}
newFunction.copyTypeParametersFrom(this)
newFunction.parent = parent
newFunction.returnType = returnType.remapTypeParameters(classIfConstructor, newFunction.classIfConstructor)
newFunction.dispatchReceiverParameter = dispatchReceiverParameter?.copyTo(newFunction)
newFunction.extensionReceiverParameter = extensionReceiverParameter?.copyTo(newFunction)
valueParameters.mapTo(newFunction.valueParameters) {
val newType = it.type.remapTypeParameters(classIfConstructor, newFunction.classIfConstructor)
val makeNullable = it.defaultValue != null &&
(context.ir.unfoldInlineClassType(it.type) ?: it.type) !in context.irBuiltIns.primitiveIrTypes
it.copyTo(newFunction, type = if (makeNullable) newType.makeNullable() else newType, defaultValue = null)
}
for (i in 0 until (valueParameters.size + 31) / 32) {
newFunction.addValueParameter("mask$i".synthesizedString, context.irBuiltIns.intType)
}
if (this is IrConstructor) {
val markerType = context.ir.symbols.defaultConstructorMarker.owner.defaultType.makeNullable()
newFunction.addValueParameter("marker".synthesizedString, markerType)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
newFunction.addValueParameter("handler".synthesizedString, context.irBuiltIns.anyNType)
}
// TODO some annotations are needed (e.g. @JvmStatic), others need different values (e.g. @JvmName), the rest are redundant.
annotations.mapTo(newFunction.annotations) { it.deepCopyWithSymbols() }
newFunction
} }
newFunction.copyTypeParametersFrom(this)
newFunction.parent = parent
newFunction.returnType = returnType.remapTypeParameters(classIfConstructor, newFunction.classIfConstructor)
newFunction.dispatchReceiverParameter = dispatchReceiverParameter?.copyTo(newFunction)
newFunction.extensionReceiverParameter = extensionReceiverParameter?.copyTo(newFunction)
valueParameters.mapTo(newFunction.valueParameters) {
val newType = it.type.remapTypeParameters(classIfConstructor, newFunction.classIfConstructor)
val makeNullable = it.defaultValue != null &&
(context.ir.unfoldInlineClassType(it.type) ?: it.type) !in context.irBuiltIns.primitiveIrTypes
it.copyTo(newFunction, type = if (makeNullable) newType.makeNullable() else newType, defaultValue = null)
}
for (i in 0 until (valueParameters.size + 31) / 32) {
newFunction.addValueParameter("mask$i".synthesizedString, context.irBuiltIns.intType)
}
if (this is IrConstructor) {
val markerType = context.ir.symbols.defaultConstructorMarker.owner.defaultType.makeNullable()
newFunction.addValueParameter("marker".synthesizedString, markerType)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
newFunction.addValueParameter("handler".synthesizedString, context.irBuiltIns.anyNType)
}
// TODO some annotations are needed (e.g. @JvmStatic), others need different values (e.g. @JvmName), the rest are redundant.
annotations.mapTo(newFunction.annotations) { it.deepCopyWithSymbols() }
return newFunction
}