From 4538e212db278b0a7288b2f8c44841880b4ea5b3 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Fri, 6 Mar 2020 12:16:00 +0100 Subject: [PATCH] Optimize hot addSubTypeConstraintAndIncorporateIt function reduce number of allocations, optimize for cases with small number of possible new constraints --- .../components/ConstraintInjector.kt | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt index bd73c401b6a..18903fe4fa0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt @@ -26,8 +26,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.refinement.TypeRefinement -import java.util.* -import kotlin.collections.ArrayList +import org.jetbrains.kotlin.utils.SmartList import kotlin.math.max class ConstraintInjector( @@ -71,15 +70,21 @@ class ConstraintInjector( upperType: KotlinTypeMarker, incorporatePosition: IncorporationConstraintPosition ) { - val possibleNewConstraints = ArrayList>() - val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints) + var possibleNewConstraints: MutableList>? = null + + val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType) { typeVar, constraint -> + if (possibleNewConstraints == null) { + possibleNewConstraints = SmartList() + } + possibleNewConstraints!!.add(typeVar to constraint) + } typeCheckerContext.runIsSubtypeOf(lowerType, upperType) - while (possibleNewConstraints.isNotEmpty()) { + while (possibleNewConstraints != null) { - val constraintsToProcess = possibleNewConstraints.toTypedArray() - possibleNewConstraints.clear() - for ((typeVariable, constraint) in constraintsToProcess) { + val constraintsToProcess = possibleNewConstraints + possibleNewConstraints = null + for ((typeVariable, constraint) in constraintsToProcess!!) { if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue val constraints = @@ -139,7 +144,7 @@ class ConstraintInjector( val position: IncorporationConstraintPosition, val baseLowerType: KotlinTypeMarker, val baseUpperType: KotlinTypeMarker, - val possibleNewConstraints: MutableCollection> + val addPossibleNewConstraints: (TypeVariableMarker, Constraint) -> Unit ) : AbstractTypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c { val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything) @@ -280,7 +285,7 @@ class ConstraintInjector( isNullabilityConstraint = isNullabilityConstraint, inputTypePositionBeforeIncorporation = inputTypePosition ) - possibleNewConstraints.add(typeVariable to newConstraint) + addPossibleNewConstraints(typeVariable, newConstraint) } override val allTypeVariablesWithConstraints: Collection @@ -296,7 +301,7 @@ class ConstraintInjector( override fun getConstraintsForVariable(typeVariable: TypeVariableMarker) = c.notFixedTypeVariables[typeVariable.freshTypeConstructor()]?.constraints - ?: fixedTypeVariable(typeVariable) + ?: fixedTypeVariable(typeVariable) fun fixedTypeVariable(variable: TypeVariableMarker): Nothing { error(