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")