Cache isProperType calculations in the constraint system

avoid expensive calculations with type.contains
This commit is contained in:
Ilya Chernikov
2020-03-05 12:14:16 +01:00
parent 70c89a28e1
commit 54f10a709a
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.math.max import kotlin.math.max
@@ -34,6 +35,8 @@ class NewConstraintSystemImpl(
private val storage = MutableConstraintStorage() private val storage = MutableConstraintStorage()
private var state = State.BUILDING private var state = State.BUILDING
private val typeVariablesTransaction: MutableList<TypeVariableMarker> = SmartList() private val typeVariablesTransaction: MutableList<TypeVariableMarker> = SmartList()
private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
private enum class State { private enum class State {
BUILDING, BUILDING,
@@ -90,6 +93,7 @@ class NewConstraintSystemImpl(
transactionRegisterVariable(variable) transactionRegisterVariable(variable)
storage.allTypeVariables[variable.freshTypeConstructor()] = variable storage.allTypeVariables[variable.freshTypeConstructor()] = variable
notProperTypesCache.clear()
storage.notFixedTypeVariables[variable.freshTypeConstructor()] = MutableVariableWithConstraints(variable) storage.notFixedTypeVariables[variable.freshTypeConstructor()] = MutableVariableWithConstraints(variable)
} }
@@ -189,10 +193,13 @@ class NewConstraintSystemImpl(
} }
override fun addOtherSystem(otherSystem: ConstraintStorage) { override fun addOtherSystem(otherSystem: ConstraintStorage) {
otherSystem.allTypeVariables.forEach { if (otherSystem.allTypeVariables.isNotEmpty()) {
transactionRegisterVariable(it.value) otherSystem.allTypeVariables.forEach {
transactionRegisterVariable(it.value)
}
storage.allTypeVariables.putAll(otherSystem.allTypeVariables)
notProperTypesCache.clear()
} }
storage.allTypeVariables.putAll(otherSystem.allTypeVariables)
for ((variable, constraints) in otherSystem.notFixedTypeVariables) { for ((variable, constraints) in otherSystem.notFixedTypeVariables) {
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints) notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints)
} }
@@ -208,7 +215,15 @@ class NewConstraintSystemImpl(
override fun isProperType(type: KotlinTypeMarker): Boolean { override fun isProperType(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
if (storage.allTypeVariables.isEmpty()) return true if (storage.allTypeVariables.isEmpty()) return true
return !type.contains { if (notProperTypesCache.contains(type)) return false
if (properTypesCache.contains(type)) return true
return isProperTypeImpl(type).also {
(if (it) properTypesCache else notProperTypesCache).add(type)
}
}
private fun isProperTypeImpl(type: KotlinTypeMarker): Boolean =
!type.contains {
val capturedType = it.asSimpleType()?.asCapturedType() val capturedType = it.asSimpleType()?.asCapturedType()
// TODO: change NewCapturedType to markered one for FE-IR // TODO: change NewCapturedType to markered one for FE-IR
val typeToCheck = if (capturedType is CapturedTypeMarker && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION) val typeToCheck = if (capturedType is CapturedTypeMarker && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION)
@@ -220,7 +235,6 @@ class NewConstraintSystemImpl(
storage.allTypeVariables.containsKey(typeToCheck.typeConstructor()) storage.allTypeVariables.containsKey(typeToCheck.typeConstructor())
} }
}
override fun isTypeVariable(type: KotlinTypeMarker): Boolean { override fun isTypeVariable(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)