[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
// This is basicly modelled after the inliner copier.
class DeepCopyIrTreeWithSymbolsForFakeOverrides(
val typeArguments: Map<IrTypeParameterSymbol, IrType>,
val superType: IrType,
val parent: IrClass
) {
class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParameterSymbol, IrType>) {
fun copy(irElement: IrElement): IrElement {
fun copy(irElement: IrElement, parent: IrClass): IrElement {
// Create new symbols.
irElement.acceptVoid(symbolRemapper)
// Make symbol remapper aware of the callsite's type arguments.
symbolRemapper.typeArguments = typeArguments
// Copy IR.
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) {
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 {
val result = super.getReferencedClassifier(symbol)
if (result !is IrTypeParameterSymbol)
@@ -94,9 +84,8 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(
}
}
private val symbolRemapper = FakeOverrideSymbolRemapperImpl(DescriptorsToIrRemapper)
private val copier =
FakeOverrideCopier(
private val symbolRemapper = FakeOverrideSymbolRemapperImpl(typeArguments, DescriptorsToIrRemapper)
private val copier = FakeOverrideCopier(
symbolRemapper,
FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
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.symbols.IrClassSymbol
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.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
@@ -68,22 +69,24 @@ class FakeOverrideBuilder(
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner).map { it.symbol }
val typeArguments = superType.arguments.map {
require(it is IrTypeProjection) { "Unexpected super type argument: $it" }
assert(it.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${it.variance}" }
it.type
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
assert(typeParameters.size == typeArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $typeArguments size "
val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
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, superType, clazz)
val deepCopyFakeOverride = copier.copy(member) as IrOverridableMember
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride
@@ -100,18 +100,16 @@ class IrOverridingUtil(
fun buildFakeOverridesForClass(clazz: IrClass) {
val superTypes = allPublicApiSuperTypesOrAny(clazz)
val fromCurrent = clazz.declarations
.filterIsInstance<IrOverridableMember>()
.filter { it.symbol.isPublicApi }
val fromCurrent = clazz.declarations.filter { it is IrOverridableMember && it.symbol.isPublicApi } as List<IrOverridableMember>
val allFromSuper = superTypes.flatMap { superType ->
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations
.filterIsInstance<IrOverridableMember>()
.filter { it.symbol.isPublicApi }
.filter { it is IrOverridableMember && it.symbol.isPublicApi }
.map {
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, it, clazz)
originals[fakeOverride] = it
val overridenMember = it as IrOverridableMember
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overridenMember, clazz)
originals[fakeOverride] = overridenMember
originalSuperTypes[fakeOverride] = superType
fakeOverride
}