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:
committed by
Space Team
parent
6705d211a6
commit
9c988fd8d8
+24
-1
@@ -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
|
||||
|
||||
|
||||
+15
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user