Cache NameResolver and KlibMetadataClassDataFinder.
^KT-80438
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/MetadataLibraryBasedSymbolProvider.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/MetadataLibraryBasedSymbolProvider.kt
index 058f67f..993e324 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/MetadataLibraryBasedSymbolProvider.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/MetadataLibraryBasedSymbolProvider.kt
@@ -30,6 +30,7 @@
import org.jetbrains.kotlin.resolve.KlibCompilerDeserializationConfiguration
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.serialization.deserialization.getClassId
+import java.util.IdentityHashMap
abstract class MetadataLibraryBasedSymbolProvider<L : MetadataLibrary>(
session: FirSession,
@@ -53,6 +54,8 @@
protected val deserializationConfiguration: KlibCompilerDeserializationConfiguration =
KlibCompilerDeserializationConfiguration(session.languageVersionSettings)
private val cachedFragments: MutableMap<L, MutableMap<Pair<String, String>, ProtoBuf.PackageFragment>> = mutableMapOf()
+ private val fragmentToNameResolver = IdentityHashMap<ProtoBuf.PackageFragment, NameResolver>()
+ private val fragmentToKlibMetadataClassDataFinder = IdentityHashMap<ProtoBuf.PackageFragment, KlibMetadataClassDataFinder>()
private fun getPackageFragment(
resolvedLibrary: L, packageStringName: String, packageMetadataPart: String
@@ -64,6 +67,22 @@
}
}
+ private fun getNameResolver(fragment: ProtoBuf.PackageFragment): NameResolver {
+ return fragmentToNameResolver.getOrPut(fragment) {
+ NameResolverImpl(
+ fragment.strings,
+ fragment.qualifiedNames,
+ )
+ }
+ }
+
+ private fun getFinder(fragment: ProtoBuf.PackageFragment, resolver: NameResolver): KlibMetadataClassDataFinder {
+ return fragmentToKlibMetadataClassDataFinder.getOrPut(fragment) {
+ // Assumes the fact that the nameResolver depends only on the fragment.
+ KlibMetadataClassDataFinder(fragment, resolver)
+ }
+ }
+
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
val packageStringName = if (packageFqName.isRoot) "" else packageFqName.asString()
@@ -78,10 +97,7 @@
val packageProto = fragment.`package`
- val nameResolver = NameResolverImpl(
- fragment.strings,
- fragment.qualifiedNames,
- )
+ val nameResolver = getNameResolver(fragment)
PackagePartsCacheData(
packageProto,
@@ -112,7 +128,7 @@
@OptIn(SymbolInternals::class)
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
forEachFragmentInPackage(classId.packageFqName) { resolvedLibrary, fragment, nameResolver ->
- val finder = KlibMetadataClassDataFinder(fragment, nameResolver)
+ val finder = getFinder(fragment, nameResolver)
val classProto = finder.findClassData(classId)?.classProto ?: return@forEachFragmentInPackage
val moduleData = moduleData(resolvedLibrary) ?: return null
@@ -167,10 +183,7 @@
val fragment = getPackageFragment(resolvedLibrary, packageStringName, packageMetadataPart)
- val nameResolver = NameResolverImpl(
- fragment.strings,
- fragment.qualifiedNames,
- )
+ val nameResolver = getNameResolver(fragment)
f(resolvedLibrary, fragment, nameResolver)
}
diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataClassDataFinder.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataClassDataFinder.kt
index 306e2c1..ae9ff6f 100644
--- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataClassDataFinder.kt
+++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataClassDataFinder.kt
@@ -22,12 +22,13 @@
) : ClassDataFinder {
val nameList = fragment.getExtension(KlibMetadataProtoBuf.className).orEmpty()
+ val classIdToIndex: Map<ClassId, Int> = buildMap {
+ nameList.forEachIndexed { index, value -> this[nameResolver.getClassId(value)] = index }
+ }
+
override fun findClassData(classId: ClassId): ClassData? {
- val index = nameList.indexOfFirst { nameResolver.getClassId(it) == classId }
- if (index == -1) {
- return null
- }
+ val index = classIdToIndex[classId] ?: return null
val foundClass = fragment.getClass_(index) ?: error("Could not find data for serialized class $classId")