From 8e1b0c5ab7ec7b144b004806d7ece169102278a0 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Sat, 28 Apr 2018 13:00:33 +0300 Subject: [PATCH] Optimize memory footprint for PartialBodyResolveFilter There is a single PartialBodyResolveFilter instance per module and each of them were containing just the same sets of available in project Nothing-typed functions (including duplicating String instances), in case of Kotlin project it might sum up to 27M of heap. The solution is to share the global sets between all modules in a project --- .../resolve/lazy/PartialBodyResolveFilter.kt | 15 +++++---- .../lazy/ProbablyNothingCallableNames.kt | 7 ++++ .../ProbablyNothingCallableNamesImpl.kt | 33 +++++++++++++++++++ .../idea/project/ResolveElementCache.kt | 9 ----- idea/src/META-INF/plugin.xml | 5 ++- idea/src/META-INF/plugin.xml.172 | 5 ++- idea/src/META-INF/plugin.xml.173 | 5 ++- idea/src/META-INF/plugin.xml.182 | 5 ++- idea/src/META-INF/plugin.xml.as31 | 5 ++- idea/src/META-INF/plugin.xml.as32 | 5 ++- 10 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProbablyNothingCallableNamesImpl.kt diff --git a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/PartialBodyResolveFilter.kt b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/PartialBodyResolveFilter.kt index 013146183d9..4526ff61d06 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/PartialBodyResolveFilter.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/PartialBodyResolveFilter.kt @@ -32,14 +32,15 @@ import java.util.* class PartialBodyResolveFilter( elementsToResolve: Collection, private val declaration: KtDeclaration, - probablyNothingCallableNames: ProbablyNothingCallableNames, forCompletion: Boolean ) : StatementFilter() { private val statementMarks = StatementMarks() - private val nothingFunctionNames = HashSet(probablyNothingCallableNames.functionNames()) - private val nothingVariableNames = HashSet(probablyNothingCallableNames.propertyNames()) + private val globalProbablyNothingCallableNames = ProbablyNothingCallableNames.getInstance(declaration.project) + + private val contextNothingFunctionNames = HashSet() + private val contextNothingVariableNames = HashSet() override val filter: ((KtExpression) -> Boolean)? = { statementMarks.statementMark(it) != MarkLevel.NONE } @@ -55,10 +56,10 @@ class PartialBodyResolveFilter( val name = declaration.name if (name != null) { if (declaration is KtNamedFunction) { - nothingFunctionNames.add(name) + contextNothingFunctionNames.add(name) } else { - nothingVariableNames.add(name) + contextNothingVariableNames.add(name) } } } @@ -399,7 +400,7 @@ class PartialBodyResolveFilter( override fun visitCallExpression(expression: KtCallExpression) { val name = (expression.calleeExpression as? KtSimpleNameExpression)?.getReferencedName() - if (name != null && name in nothingFunctionNames) { + if (name != null && (name in globalProbablyNothingCallableNames.functionNames() || name in contextNothingFunctionNames)) { result.add(expression) } super.visitCallExpression(expression) @@ -407,7 +408,7 @@ class PartialBodyResolveFilter( override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { val name = expression.getReferencedName() - if (name in nothingVariableNames) { + if (name in globalProbablyNothingCallableNames.propertyNames() || name in contextNothingVariableNames) { result.add(expression) } } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ProbablyNothingCallableNames.kt b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ProbablyNothingCallableNames.kt index bef813d1b43..8a3cf2b2578 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ProbablyNothingCallableNames.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ProbablyNothingCallableNames.kt @@ -16,7 +16,14 @@ package org.jetbrains.kotlin.resolve.lazy +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.project.Project + interface ProbablyNothingCallableNames { fun functionNames(): Collection fun propertyNames(): Collection + + companion object { + fun getInstance(project: Project) = ServiceManager.getService(project, ProbablyNothingCallableNames::class.java)!! + } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProbablyNothingCallableNamesImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProbablyNothingCallableNamesImpl.kt new file mode 100644 index 00000000000..f7885461039 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProbablyNothingCallableNamesImpl.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.project + +import com.intellij.openapi.project.Project +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.util.containers.SLRUCache +import org.jetbrains.kotlin.idea.caches.project.getModuleInfo +import org.jetbrains.kotlin.idea.caches.resolve.PerFileAnalysisCache +import org.jetbrains.kotlin.idea.stubindex.KotlinProbablyNothingFunctionShortNameIndex +import org.jetbrains.kotlin.idea.stubindex.KotlinProbablyNothingPropertyShortNameIndex +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames + +class ProbablyNothingCallableNamesImpl(project: Project) : ProbablyNothingCallableNames { + private val functionNames = createCachedValue(project) { KotlinProbablyNothingFunctionShortNameIndex.getInstance().getAllKeys(project) } + private val propertyNames = createCachedValue(project) { KotlinProbablyNothingPropertyShortNameIndex.getInstance().getAllKeys(project) } + + override fun functionNames(): Collection = functionNames.value + override fun propertyNames(): Collection = propertyNames.value +} + +private inline fun createCachedValue(project: Project, crossinline names: () -> Collection) = + CachedValuesManager.getManager(project).createCachedValue( + { + CachedValueProvider.Result.create(names(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) + }, false + ) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt index 6cfc43274cb..4a4bfddc21d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt @@ -111,14 +111,6 @@ class ResolveElementCache( false ) - - private fun probablyNothingCallableNames(): ProbablyNothingCallableNames { - return object : ProbablyNothingCallableNames { - override fun functionNames() = KotlinProbablyNothingFunctionShortNameIndex.getInstance().getAllKeys(project) - override fun propertyNames() = KotlinProbablyNothingPropertyShortNameIndex.getInstance().getAllKeys(project) - } - } - override fun resolveFunctionBody(function: KtNamedFunction) = getElementsAdditionalResolve(function, null, BodyResolveMode.FULL) fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext { @@ -310,7 +302,6 @@ class ResolveElementCache( statementFilterUsed = PartialBodyResolveFilter( contextElements!!, resolveElement as KtDeclaration, - probablyNothingCallableNames(), bodyResolveMode == BodyResolveMode.PARTIAL_FOR_COMPLETION ) } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8308eceb8b2..ab2a222e3d9 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -349,6 +349,9 @@ + + @@ -2691,7 +2694,7 @@ level="WARNING" language="kotlin" /> - + + + @@ -2691,7 +2694,7 @@ level="WARNING" language="kotlin" /> - + + + @@ -2692,7 +2695,7 @@ level="WARNING" language="kotlin" /> - + + + @@ -2692,7 +2695,7 @@ level="WARNING" language="kotlin" /> - + + + @@ -2691,7 +2694,7 @@ level="WARNING" language="kotlin" /> - + + + @@ -2691,7 +2694,7 @@ level="WARNING" language="kotlin" /> - +