Optimize hot addSubTypeConstraintAndIncorporateIt function

reduce number of allocations, optimize for cases with small number
of possible new constraints
This commit is contained in:
Ilya Chernikov
2020-03-06 12:16:00 +01:00
parent 357ceeae19
commit 4538e212db
@@ -26,8 +26,7 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.refinement.TypeRefinement
import java.util.* import org.jetbrains.kotlin.utils.SmartList
import kotlin.collections.ArrayList
import kotlin.math.max import kotlin.math.max
class ConstraintInjector( class ConstraintInjector(
@@ -71,15 +70,21 @@ class ConstraintInjector(
upperType: KotlinTypeMarker, upperType: KotlinTypeMarker,
incorporatePosition: IncorporationConstraintPosition incorporatePosition: IncorporationConstraintPosition
) { ) {
val possibleNewConstraints = ArrayList<Pair<TypeVariableMarker, Constraint>>() var possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>? = null
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints)
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType) { typeVar, constraint ->
if (possibleNewConstraints == null) {
possibleNewConstraints = SmartList()
}
possibleNewConstraints!!.add(typeVar to constraint)
}
typeCheckerContext.runIsSubtypeOf(lowerType, upperType) typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
while (possibleNewConstraints.isNotEmpty()) { while (possibleNewConstraints != null) {
val constraintsToProcess = possibleNewConstraints.toTypedArray() val constraintsToProcess = possibleNewConstraints
possibleNewConstraints.clear() possibleNewConstraints = null
for ((typeVariable, constraint) in constraintsToProcess) { for ((typeVariable, constraint) in constraintsToProcess!!) {
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
val constraints = val constraints =
@@ -139,7 +144,7 @@ class ConstraintInjector(
val position: IncorporationConstraintPosition, val position: IncorporationConstraintPosition,
val baseLowerType: KotlinTypeMarker, val baseLowerType: KotlinTypeMarker,
val baseUpperType: KotlinTypeMarker, val baseUpperType: KotlinTypeMarker,
val possibleNewConstraints: MutableCollection<Pair<TypeVariableMarker, Constraint>> val addPossibleNewConstraints: (TypeVariableMarker, Constraint) -> Unit
) : AbstractTypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c { ) : AbstractTypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything) val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything)
@@ -280,7 +285,7 @@ class ConstraintInjector(
isNullabilityConstraint = isNullabilityConstraint, isNullabilityConstraint = isNullabilityConstraint,
inputTypePositionBeforeIncorporation = inputTypePosition inputTypePositionBeforeIncorporation = inputTypePosition
) )
possibleNewConstraints.add(typeVariable to newConstraint) addPossibleNewConstraints(typeVariable, newConstraint)
} }
override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints> override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints>
@@ -296,7 +301,7 @@ class ConstraintInjector(
override fun getConstraintsForVariable(typeVariable: TypeVariableMarker) = override fun getConstraintsForVariable(typeVariable: TypeVariableMarker) =
c.notFixedTypeVariables[typeVariable.freshTypeConstructor()]?.constraints c.notFixedTypeVariables[typeVariable.freshTypeConstructor()]?.constraints
?: fixedTypeVariable(typeVariable) ?: fixedTypeVariable(typeVariable)
fun fixedTypeVariable(variable: TypeVariableMarker): Nothing { fun fixedTypeVariable(variable: TypeVariableMarker): Nothing {
error( error(