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
This commit is contained in:
Denis Zharkov
2018-04-28 13:00:33 +03:00
parent 26714d56d8
commit 8e1b0c5ab7
10 changed files with 72 additions and 22 deletions
@@ -32,14 +32,15 @@ import java.util.*
class PartialBodyResolveFilter( class PartialBodyResolveFilter(
elementsToResolve: Collection<KtElement>, elementsToResolve: Collection<KtElement>,
private val declaration: KtDeclaration, private val declaration: KtDeclaration,
probablyNothingCallableNames: ProbablyNothingCallableNames,
forCompletion: Boolean forCompletion: Boolean
) : StatementFilter() { ) : StatementFilter() {
private val statementMarks = StatementMarks() private val statementMarks = StatementMarks()
private val nothingFunctionNames = HashSet(probablyNothingCallableNames.functionNames()) private val globalProbablyNothingCallableNames = ProbablyNothingCallableNames.getInstance(declaration.project)
private val nothingVariableNames = HashSet(probablyNothingCallableNames.propertyNames())
private val contextNothingFunctionNames = HashSet<String>()
private val contextNothingVariableNames = HashSet<String>()
override val filter: ((KtExpression) -> Boolean)? = { statementMarks.statementMark(it) != MarkLevel.NONE } override val filter: ((KtExpression) -> Boolean)? = { statementMarks.statementMark(it) != MarkLevel.NONE }
@@ -55,10 +56,10 @@ class PartialBodyResolveFilter(
val name = declaration.name val name = declaration.name
if (name != null) { if (name != null) {
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
nothingFunctionNames.add(name) contextNothingFunctionNames.add(name)
} }
else { else {
nothingVariableNames.add(name) contextNothingVariableNames.add(name)
} }
} }
} }
@@ -399,7 +400,7 @@ class PartialBodyResolveFilter(
override fun visitCallExpression(expression: KtCallExpression) { override fun visitCallExpression(expression: KtCallExpression) {
val name = (expression.calleeExpression as? KtSimpleNameExpression)?.getReferencedName() 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) result.add(expression)
} }
super.visitCallExpression(expression) super.visitCallExpression(expression)
@@ -407,7 +408,7 @@ class PartialBodyResolveFilter(
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val name = expression.getReferencedName() val name = expression.getReferencedName()
if (name in nothingVariableNames) { if (name in globalProbablyNothingCallableNames.propertyNames() || name in contextNothingVariableNames) {
result.add(expression) result.add(expression)
} }
} }
@@ -16,7 +16,14 @@
package org.jetbrains.kotlin.resolve.lazy package org.jetbrains.kotlin.resolve.lazy
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
interface ProbablyNothingCallableNames { interface ProbablyNothingCallableNames {
fun functionNames(): Collection<String> fun functionNames(): Collection<String>
fun propertyNames(): Collection<String> fun propertyNames(): Collection<String>
companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, ProbablyNothingCallableNames::class.java)!!
}
} }
@@ -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<String> = functionNames.value
override fun propertyNames(): Collection<String> = propertyNames.value
}
private inline fun createCachedValue(project: Project, crossinline names: () -> Collection<String>) =
CachedValuesManager.getManager(project).createCachedValue(
{
CachedValueProvider.Result.create(names(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
}, false
)
@@ -111,14 +111,6 @@ class ResolveElementCache(
false 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) override fun resolveFunctionBody(function: KtNamedFunction) = getElementsAdditionalResolve(function, null, BodyResolveMode.FULL)
fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext { fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext {
@@ -310,7 +302,6 @@ class ResolveElementCache(
statementFilterUsed = PartialBodyResolveFilter( statementFilterUsed = PartialBodyResolveFilter(
contextElements!!, contextElements!!,
resolveElement as KtDeclaration, resolveElement as KtDeclaration,
probablyNothingCallableNames(),
bodyResolveMode == BodyResolveMode.PARTIAL_FOR_COMPLETION bodyResolveMode == BodyResolveMode.PARTIAL_FOR_COMPLETION
) )
} }
+4 -1
View File
@@ -349,6 +349,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2691,7 +2694,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"
+4 -1
View File
@@ -349,6 +349,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2691,7 +2694,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"
+4 -1
View File
@@ -349,6 +349,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2692,7 +2695,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"
+4 -1
View File
@@ -350,6 +350,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2692,7 +2695,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"
+4 -1
View File
@@ -349,6 +349,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2691,7 +2694,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"
+4 -1
View File
@@ -349,6 +349,9 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener" <projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/> serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
<projectService serviceInterface="org.jetbrains.kotlin.resolve.lazy.ProbablyNothingCallableNames"
serviceImplementation="org.jetbrains.kotlin.idea.project.ProbablyNothingCallableNamesImpl"/>
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
@@ -2691,7 +2694,7 @@
level="WARNING" level="WARNING"
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection" <localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
displayName="Non-canonical modifier order" displayName="Non-canonical modifier order"
groupPath="Kotlin" groupPath="Kotlin"