[KLIB] Make fake override resolver garbage free as much as possible

- reduce memory pollution during FO resolve
This commit is contained in:
Roman Artemev
2020-07-31 15:38:39 +03:00
committed by romanart
parent 876ee265f2
commit 4f73e08704
3 changed files with 28 additions and 38 deletions
@@ -15,19 +15,13 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
// This is basicly modelled after the inliner copier. // This is basicly modelled after the inliner copier.
class DeepCopyIrTreeWithSymbolsForFakeOverrides( class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParameterSymbol, IrType>) {
val typeArguments: Map<IrTypeParameterSymbol, IrType>,
val superType: IrType,
val parent: IrClass
) {
fun copy(irElement: IrElement): IrElement { fun copy(irElement: IrElement, parent: IrClass): IrElement {
// Create new symbols. // Create new symbols.
irElement.acceptVoid(symbolRemapper) irElement.acceptVoid(symbolRemapper)
// Make symbol remapper aware of the callsite's type arguments. // Make symbol remapper aware of the callsite's type arguments.
symbolRemapper.typeArguments = typeArguments
// Copy IR. // Copy IR.
val result = irElement.transform(copier, data = null) val result = irElement.transform(copier, data = null)
@@ -76,16 +70,12 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(
} }
} }
private class FakeOverrideSymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper) : private class FakeOverrideSymbolRemapperImpl(
private val typeArguments: Map<IrTypeParameterSymbol, IrType>,
descriptorsRemapper: DescriptorsRemapper
) :
DeepCopySymbolRemapper(descriptorsRemapper) { DeepCopySymbolRemapper(descriptorsRemapper) {
var typeArguments = mapOf<IrTypeParameterSymbol, IrType>()
set(value) {
field = value.asSequence().associate {
(getReferencedClassifier(it.key) as IrTypeParameterSymbol) to it.value
}
}
override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol { override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol {
val result = super.getReferencedClassifier(symbol) val result = super.getReferencedClassifier(symbol)
if (result !is IrTypeParameterSymbol) if (result !is IrTypeParameterSymbol)
@@ -94,9 +84,8 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(
} }
} }
private val symbolRemapper = FakeOverrideSymbolRemapperImpl(DescriptorsToIrRemapper) private val symbolRemapper = FakeOverrideSymbolRemapperImpl(typeArguments, DescriptorsToIrRemapper)
private val copier = private val copier = FakeOverrideCopier(
FakeOverrideCopier(
symbolRemapper, symbolRemapper,
FakeOverrideTypeRemapper(symbolRemapper, typeArguments), FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
SymbolRenamer.DEFAULT SymbolRenamer.DEFAULT
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
@@ -68,22 +69,24 @@ class FakeOverrideBuilder(
val classifier = superType.classifier val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" } require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner).map { it.symbol } val typeParameters = extractTypeParameters(classifier.owner)
val typeArguments = superType.arguments.map { val superArguments = superType.arguments
require(it is IrTypeProjection) { "Unexpected super type argument: $it" } assert(typeParameters.size == superArguments.size) {
assert(it.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${it.variance}" } "typeParameters = $typeParameters size != typeArguments = $superArguments size "
it.type
} }
assert(typeParameters.size == typeArguments.size) { val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
"typeParameters = $typeParameters size != typeArguments = $typeArguments size "
for (i in typeParameters.indices) {
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: $ta @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
} }
val substitutionMap = typeParameters.zip(typeArguments).toMap() val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val copier = val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap, superType, clazz)
val deepCopyFakeOverride = copier.copy(member) as IrOverridableMember
deepCopyFakeOverride.parent = clazz deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride return deepCopyFakeOverride
@@ -100,18 +100,16 @@ class IrOverridingUtil(
fun buildFakeOverridesForClass(clazz: IrClass) { fun buildFakeOverridesForClass(clazz: IrClass) {
val superTypes = allPublicApiSuperTypesOrAny(clazz) val superTypes = allPublicApiSuperTypesOrAny(clazz)
val fromCurrent = clazz.declarations val fromCurrent = clazz.declarations.filter { it is IrOverridableMember && it.symbol.isPublicApi } as List<IrOverridableMember>
.filterIsInstance<IrOverridableMember>()
.filter { it.symbol.isPublicApi }
val allFromSuper = superTypes.flatMap { superType -> val allFromSuper = superTypes.flatMap { superType ->
val superClass = superType.getClass() ?: error("Unexpected super type: $superType") val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations superClass.declarations
.filterIsInstance<IrOverridableMember>() .filter { it is IrOverridableMember && it.symbol.isPublicApi }
.filter { it.symbol.isPublicApi }
.map { .map {
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, it, clazz) val overridenMember = it as IrOverridableMember
originals[fakeOverride] = it val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overridenMember, clazz)
originals[fakeOverride] = overridenMember
originalSuperTypes[fakeOverride] = superType originalSuperTypes[fakeOverride] = superType
fakeOverride fakeOverride
} }