[FIR] Cache deserialized builtin functions

Apparently `FirBuiltinSymbolProvider` cached deserialized classes but
  created new fir functions for each invocation

^KT-61637
This commit is contained in:
Dmitriy Novozhilov
2023-09-01 16:00:17 +03:00
committed by Space Team
parent 36cb869ac2
commit 3f3c839c48
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.caches.firCachesFactory import org.jetbrains.kotlin.fir.caches.*
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer
import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer
@@ -150,7 +150,7 @@ open class FirBuiltinSymbolProvider(
).memberDeserializer ).memberDeserializer
} }
private val lookup = moduleData.session.firCachesFactory.createCacheWithPostCompute( private val classCache = moduleData.session.firCachesFactory.createCacheWithPostCompute(
{ classId: ClassId, context: FirDeserializationContext? -> FirRegularClassSymbol(classId) to context } { classId: ClassId, context: FirDeserializationContext? -> FirRegularClassSymbol(classId) to context }
) { classId, symbol, parentContext -> ) { classId, symbol, parentContext ->
val classData = classDataFinder.findClassData(classId)!! val classData = classDataFinder.findClassData(classId)!!
@@ -165,6 +165,17 @@ open class FirBuiltinSymbolProvider(
) )
} }
private val functionCache: FirCache<Name, List<FirNamedFunctionSymbol>, Nothing?> =
moduleData.session.firCachesFactory.createCache { name ->
packageProto.`package`.functionList.filter { nameResolver.getName(it.name) == name }.map {
memberDeserializer.loadFunction(it).symbol
}
}
private val functionsNameCache: FirLazyValue<List<Name>> = moduleData.session.firCachesFactory.createLazyValue {
packageProto.`package`.functionList.map { nameResolver.getName(it.name) }
}
fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? = fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? =
findAndDeserializeClass(classId) findAndDeserializeClass(classId)
@@ -174,20 +185,19 @@ open class FirBuiltinSymbolProvider(
): FirRegularClassSymbol? { ): FirRegularClassSymbol? {
val classIdExists = classId in classDataFinder.allClassIds val classIdExists = classId in classDataFinder.allClassIds
if (!classIdExists) return null if (!classIdExists) return null
return lookup.getValue(classId, parentContext) return classCache.getValue(classId, parentContext)
} }
fun getTopLevelCallableSymbols(name: Name): List<FirCallableSymbol<*>> { fun getTopLevelCallableSymbols(name: Name): List<FirCallableSymbol<*>> {
return getTopLevelFunctionSymbols(name) return getTopLevelFunctionSymbols(name)
} }
fun getTopLevelCallableNames(): Collection<Name> = fun getTopLevelCallableNames(): Collection<Name> {
packageProto.`package`.functionList.map { nameResolver.getName(it.name) } return functionsNameCache.getValue()
}
fun getTopLevelFunctionSymbols(name: Name): List<FirNamedFunctionSymbol> { fun getTopLevelFunctionSymbols(name: Name): List<FirNamedFunctionSymbol> {
return packageProto.`package`.functionList.filter { nameResolver.getName(it.name) == name }.map { return functionCache.getValue(name)
memberDeserializer.loadFunction(it).symbol
}
} }
} }
} }