Cache KotlinCliJavaFileManagerImpl.findClass
diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt index a53cdaa..e3dd35b 100644 --- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt +++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt
@@ -41,6 +41,22 @@ import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager import org.jetbrains.kotlin.util.PerformanceCounter import org.jetbrains.kotlin.utils.addIfNotNull +import java.util.concurrent.ConcurrentHashMap + +/*private var totalRequests = 0 +private var requestHits = 0 +private var resultHits = 0 +private val findClassRequests: MutableMap<FindClassCacheKey, JavaClass?> = hashMapOf() +private val findClassResults: MutableMap<FindClassCacheKey, JavaClass?> = hashMapOf() + +private data class FindClassCacheKey( + val classId: ClassId, + @Suppress("ArrayInDataClass") + val previouslyFoundClassFileContent: ByteArray?, + val outerClass: JavaClass?, + val searchScope: GlobalSearchScope, + val result: JavaClass?, +)*/ // TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices // Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage, @@ -58,7 +74,7 @@ index: JvmDependenciesIndex, packagePartProviders: List<JvmPackagePartProvider>, singleJavaFileRootsIndex: SingleJavaFileRootsIndex, - usePsiClassFilesReading: Boolean + usePsiClassFilesReading: Boolean, ) { this.index = index this.packagePartProviders = packagePartProviders @@ -101,7 +117,34 @@ fun findClass(classId: ClassId, searchScope: GlobalSearchScope) = findClass(JavaClassFinder.Request(classId), searchScope) + private val findClassCache: MutableMap<FindClassCacheKey, JavaClass?> = hashMapOf() + + private data class FindClassCacheKey( + val classId: ClassId, + @Suppress("ArrayInDataClass") + val previouslyFoundClassFileContent: ByteArray?, + val outerClass: JavaClass?, + val searchScope: GlobalSearchScope, + ) + override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? { + /*totalRequests++ + val result = doFindClass(request, searchScope) + + val reqKey = FindClassCacheKey(request.classId, request.previouslyFoundClassFileContent, request.outerClass, searchScope, null) + val resKey = FindClassCacheKey(request.classId, request.previouslyFoundClassFileContent, request.outerClass, searchScope, result) + if (findClassRequests.putIfAbsent(reqKey, result) != null) { + requestHits++ + } + if (findClassResults.putIfAbsent(resKey, result) != null) { + resultHits++ + }*/ + + val key = FindClassCacheKey(request.classId, request.previouslyFoundClassFileContent, request.outerClass, searchScope) + return findClassCache.getOrPut(key) { doFindClass(request, searchScope) } + } + + private fun doFindClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? { val (classId, classFileContentFromRequest, outerClassFromRequest) = request val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null @@ -239,7 +282,7 @@ private fun findVirtualFileGivenPackage( packageDir: VirtualFile, classNameWithInnerClasses: String, - rootType: JavaRoot.RootType + rootType: JavaRoot.RootType, ): VirtualFile? { val topLevelClassName = classNameWithInnerClasses.substringBefore('.') @@ -334,3 +377,4 @@ private fun String.toSafeFqName(): FqName? = safely { FqName(this) } private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) } +