From 92bcf3b2d5b9b9cc4506ccf48eeb8d058d7b9ffc Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 22 Jun 2023 10:53:20 +0200 Subject: [PATCH] [psi] packageCache: avoid pair as a key supposedly, when search for package is performed, it's performed multiple times with different names but for the same scope. In this situation, extracting scope from key brings a lot of memory. For IJ, it reduces load from 7Mb -> 4Mb --- .../resolve/jvm/KotlinJavaPsiFacade.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java index 42e6dcd489e..d19e6d2c1f0 100644 --- a/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java +++ b/compiler/resolution.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java @@ -22,7 +22,6 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.PackageIndex; import com.intellij.openapi.util.LowMemoryWatcher; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; @@ -62,10 +61,10 @@ public class KotlinJavaPsiFacade implements Disposable { private static class PackageCache { // long term cache - final ConcurrentMap, PsiPackage> packageInLibScopeCache = new ConcurrentHashMap<>(); + final ConcurrentMap> packageInLibScopeCache = new ConcurrentHashMap<>(); // short term caches - final ConcurrentMap, PsiPackage> packageInScopeCache = new ConcurrentHashMap<>(); + final ConcurrentMap> packageInScopeCache = new ConcurrentHashMap<>(); final ConcurrentMap hasPackageInAllScopeCache = new ConcurrentHashMap<>(); void clear() { @@ -340,12 +339,13 @@ public class KotlinJavaPsiFacade implements Disposable { Boolean packageFoundInAllScope = cache.hasPackageInAllScopeCache.get(qualifiedName); if (packageFoundInAllScope != null && !packageFoundInAllScope.booleanValue()) return null; - Pair key = new Pair<>(qualifiedName, searchScope); - PsiPackage pkg = cache.packageInLibScopeCache.get(key); + ConcurrentMap packageInLibScope = cache.packageInLibScopeCache.get(searchScope); + PsiPackage pkg = packageInLibScope != null ? packageInLibScope.get(qualifiedName) : null; if (pkg != null) { return unwrap(pkg); } - pkg = cache.packageInScopeCache.get(key); + ConcurrentMap packageInScope = cache.packageInScopeCache.get(searchScope); + pkg = packageInScope != null ? packageInScope.get(qualifiedName) : null; if (pkg != null) { return unwrap(pkg); } @@ -356,7 +356,7 @@ public class KotlinJavaPsiFacade implements Disposable { { // store found package in a long term cache if package is found in library search scope - ConcurrentMap, PsiPackage> existedPackageInScopeCache = + ConcurrentMap> existedPackageInScopeCache = isALibrarySearchScope ? cache.packageInLibScopeCache : cache.packageInScopeCache; KotlinPsiElementFinderWrapper[] finders = filteredFinders(); @@ -367,7 +367,9 @@ public class KotlinJavaPsiFacade implements Disposable { if (!finder.isSameResultForAnyScope()) { PsiPackage aPackage = finder.findPackage(qualifiedName, searchScope); if (aPackage != null) { - return unwrap(ConcurrencyUtil.cacheOrGet(existedPackageInScopeCache, key, aPackage)); + ConcurrentMap concurrentMap = + ConcurrencyUtil.cacheOrGet(existedPackageInScopeCache, searchScope, new ConcurrentHashMap<>()); + return unwrap(ConcurrencyUtil.cacheOrGet(concurrentMap, qualifiedName, aPackage)); } } } @@ -377,7 +379,9 @@ public class KotlinJavaPsiFacade implements Disposable { PsiPackage aPackage = finder.findPackage(qualifiedName, searchScope); if (aPackage != null) { - return unwrap(ConcurrencyUtil.cacheOrGet(existedPackageInScopeCache, key, aPackage)); + ConcurrentMap concurrentMap = + ConcurrencyUtil.cacheOrGet(existedPackageInScopeCache, searchScope, new ConcurrentHashMap<>()); + return unwrap(ConcurrencyUtil.cacheOrGet(concurrentMap, qualifiedName, aPackage)); } } @@ -397,7 +401,7 @@ public class KotlinJavaPsiFacade implements Disposable { } } - ConcurrentMap, PsiPackage> notFoundPackageInScopeCache; + ConcurrentMap> notFoundPackageInScopeCache; switch (notFoundCacheType) { case LIB_SCOPE: notFoundPackageInScopeCache = cache.packageInLibScopeCache; @@ -411,7 +415,9 @@ public class KotlinJavaPsiFacade implements Disposable { throw new IllegalStateException("Impossible enum value: " + notFoundCacheType.toString()); } - return unwrap(ConcurrencyUtil.cacheOrGet(notFoundPackageInScopeCache, key, NULL_PACKAGE)); + ConcurrentMap concurrentMap = + ConcurrencyUtil.cacheOrGet(notFoundPackageInScopeCache, searchScope, new ConcurrentHashMap<>()); + return unwrap(ConcurrencyUtil.cacheOrGet(concurrentMap, qualifiedName, NULL_PACKAGE)); } private PackageCache obtainPackageCache() {