From 019001ca20a70ccfd8b66a6ad46a1f1d8d9ac297 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 4 Aug 2021 16:15:19 +0300 Subject: [PATCH] Optimize memory footprint related to empty/single element collections ^KT-47926 Related --- .../calls/tower/KotlinToResolvedCallTransformer.kt | 6 ++---- .../calls/tower/NewResolutionOldInference.kt | 6 +++--- .../kotlin/resolve/calls/tower/PSICallResolver.kt | 3 ++- .../components/ArgumentsToParametersMapper.kt | 4 ++-- .../resolve/calls/components/ResolutionParts.kt | 3 ++- .../src/org/jetbrains/kotlin/utils/addToStdlib.kt | 14 ++++++++++++++ 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 7913de31407..8e772f45f75 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -48,7 +48,6 @@ import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver -import org.jetbrains.kotlin.resolve.diagnostics.MutableDiagnosticsWithSuppression import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue @@ -64,9 +63,8 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible import org.jetbrains.kotlin.utils.addToStdlib.safeAs -import java.util.* -import kotlin.collections.LinkedHashMap class KotlinToResolvedCallTransformer( private val callCheckers: Iterable, @@ -677,7 +675,7 @@ sealed class NewAbstractResolvedCall() : ResolvedCall result[parameter] = argument } } - } + }.compactIfPossible() } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index 7e31a186e80..a1876d4c214 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -21,13 +21,13 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer @@ -61,8 +61,8 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible import org.jetbrains.kotlin.utils.sure -import java.util.* class NewResolutionOldInference( private val candidateResolver: CandidateResolver, @@ -601,7 +601,7 @@ fun transformToReceiverWithSmartCastInfo( val dataFlowValue = dataFlowValueFactory.createDataFlowValue(receiver, bindingContext, containingDescriptor) return ReceiverValueWithSmartCastInfo( receiver, - dataFlowInfo.getCollectedTypes(dataFlowValue, languageVersionSettings), + dataFlowInfo.getCollectedTypes(dataFlowValue, languageVersionSettings).compactIfPossible(), dataFlowValue.isStable ) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 7934a4beaf2..327a0520f0f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.expressions.* import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.util.* @@ -542,7 +543,7 @@ class PSICallResolver( dataFlowValueFactory.createDataFlowValue(variableReceiver, temporaryTrace.bindingContext, context.scope.ownerDescriptor) return ReceiverValueWithSmartCastInfo( variableReceiver, - context.dataFlowInfo.getCollectedTypes(dataFlowValue, context.languageVersionSettings), + context.dataFlowInfo.getCollectedTypes(dataFlowValue, context.languageVersionSettings).compactIfPossible(), dataFlowValue.isStable ).prepareReceiverRegardingCaptureTypes() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt index f2936a1227e..260fe50242b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.model.* -import java.util.* +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible class ArgumentsToParametersMapper( languageVersionSettings: LanguageVersionSettings @@ -63,7 +63,7 @@ class ArgumentsToParametersMapper( } processor.processDefaultsAndRunChecks() - return ArgumentMapping(processor.result, processor.getDiagnostics()) + return ArgumentMapping(processor.result.compactIfPossible(), processor.getDiagnostics()) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 14a502a9043..1e9d90927f3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal object CheckVisibility : ResolutionPart() { @@ -96,7 +97,7 @@ internal object ArgumentsToCandidateParameterDescriptor : ResolutionPart() { map[argument] = valueParameter } } - resolvedCall.argumentToCandidateParameter = map + resolvedCall.argumentToCandidateParameter = map.compactIfPossible() } } diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt index bcdd8d37d68..e4a1c8f853a 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt @@ -185,6 +185,20 @@ inline fun MutableMap.getOrPut(key: K, defaultValue: (K) -> } } +fun Set.compactIfPossible(): Set = + when (size) { + 0 -> emptySet() + 1 -> setOf(single()) + else -> this + } + +fun Map.compactIfPossible(): Map = + when (size) { + 0 -> emptyMap() + 1 -> Collections.singletonMap(keys.single(), values.single()) + else -> this + } + inline fun T.applyIf(`if`: Boolean, body: T.() -> T): T = if (`if`) body() else this