K2: Introduce FirCachingCompositeSymbolProvider

The main idea is pre-computing the sets of names that might be
met there, that helps to decrease the sizes of the backing maps
(by avoiding irrelevant keys)

Totally, this branch with previous commits speeds up MT Full Kotlin
approximately on 3 seconds (~5%)
This commit is contained in:
Denis.Zharkov
2023-01-06 17:29:44 +01:00
committed by Space Team
parent 6705d211a6
commit 9c988fd8d8
18 changed files with 437 additions and 44 deletions
@@ -124,7 +124,25 @@ abstract class AbstractFirDeserializedSymbolProvider(
// This method should only be used for sake of optimization to avoid having too many empty-list/null values in our caches
protected abstract fun computePackageSetWithNonClassDeclarations(): Set<String>
protected abstract fun mayHaveTopLevelClass(classId: ClassId): Boolean
override fun computePackageSetWithTopLevelCallables(): Set<String> = computePackageSetWithNonClassDeclarations()
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = allNamesByPackage.getValue(packageFqName)
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? {
val classesInPackage = knownTopLevelClassesInPackage(packageFqName) ?: return null
if (packageFqName.asString() !in packageNamesForNonClassDeclarations) return classesInPackage
val typeAliasNames = typeAliasesNamesByPackage.getValue(packageFqName)
if (typeAliasNames.isEmpty()) return classesInPackage
return buildSet {
addAll(classesInPackage)
typeAliasNames.mapTo(this) { it.asString() }
}
}
protected abstract fun knownTopLevelClassesInPackage(packageFqName: FqName): Set<String>?
protected abstract fun extractClassMetadata(
classId: ClassId,
@@ -240,6 +258,11 @@ abstract class AbstractFirDeserializedSymbolProvider(
return classCache.getValue(classId, parentContext)
}
private fun mayHaveTopLevelClass(topLevelClassId: ClassId): Boolean {
val knownClassNames = knownTopLevelClassifiersInPackage(topLevelClassId.packageFqName) ?: return true
return topLevelClassId.shortClassName.asString() in knownClassNames
}
private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? {
if (!classId.relativeClassName.isOneSegmentFQN()) return null
@@ -77,6 +77,18 @@ open class FirBuiltinSymbolProvider(
} ?: syntheticFunctionalInterfaceCache.tryGetSyntheticFunctionalInterface(classId)
}
override fun computePackageSetWithTopLevelCallables(): Set<String> =
allPackageFragments.keys.mapTo(mutableSetOf()) { it.asString() }
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> =
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) { fragment ->
fragment.classDataFinder.allClassIds.map { it.shortClassName.asString() }
}.orEmpty()
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> =
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) {
it.getTopLevelCallableNames()
}.orEmpty()
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
@@ -154,6 +166,9 @@ open class FirBuiltinSymbolProvider(
return getTopLevelFunctionSymbols(name)
}
fun getTopLevelCallableNames(): Collection<Name> =
packageProto.`package`.functionList.map { nameResolver.getName(it.name) }
fun getTopLevelFunctionSymbols(name: Name): List<FirNamedFunctionSymbol> {
return packageProto.`package`.functionList.filter { nameResolver.getName(it.name) == name }.map {
memberDeserializer.loadFunction(it).symbol