FIR2IR: cleanup field static fake override caching

This commit is contained in:
Mikhail Glukhikh
2022-11-25 10:32:18 +01:00
committed by Space Team
parent 91a3c78844
commit 8ffabddf75
2 changed files with 26 additions and 35 deletions
@@ -51,10 +51,7 @@ import org.jetbrains.kotlin.ir.types.IrErrorType
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.kotlin.utils.addToStdlib.runUnless import org.jetbrains.kotlin.utils.addToStdlib.runUnless
@@ -109,7 +106,9 @@ class Fir2IrDeclarationStorage(
private val fieldCache = ConcurrentHashMap<FirField, IrField>() private val fieldCache = ConcurrentHashMap<FirField, IrField>()
private val fieldStaticOverrideCache = ConcurrentHashMap<Pair<Name, ClassId>, IrField>() private data class FieldStaticOverrideKey(val lookupTag: ConeClassLikeLookupTag, val name: Name)
private val fieldStaticOverrideCache = ConcurrentHashMap<FieldStaticOverrideKey, IrField>()
private val localStorage by threadLocal { Fir2IrLocalStorage() } private val localStorage by threadLocal { Fir2IrLocalStorage() }
@@ -1018,19 +1017,9 @@ class Fir2IrDeclarationStorage(
fun getCachedIrDelegateOrBackingField(field: FirField): IrField? = fieldCache[field] fun getCachedIrDelegateOrBackingField(field: FirField): IrField? = fieldCache[field]
fun getCachedIrField( fun getCachedIrFieldStaticFakeOverrideByDeclaration(field: FirField): IrField? {
field: FirField, val ownerLookupTag = field.containingClassLookupTag() ?: return null
// Always should be null for non-static return fieldStaticOverrideCache[FieldStaticOverrideKey(ownerLookupTag, field.name)]
// For static null means "take containing class instead"
staticFakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
): IrField? {
val classId = (staticFakeOverrideOwnerLookupTag ?: field.containingClassLookupTag())?.classId
if (classId == null || !field.isStatic ||
!field.isSubstitutionOrIntersectionOverride && staticFakeOverrideOwnerLookupTag == field.containingClassLookupTag()
) {
return fieldCache[field]
}
return fieldStaticOverrideCache[field.name to classId]
} }
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? {
@@ -1078,8 +1067,8 @@ class Fir2IrDeclarationStorage(
): IrField = convertCatching(field) { ): IrField = convertCatching(field) {
val type = typeRef.toIrType() val type = typeRef.toIrType()
val classId = (irParent as? IrClass)?.classId val classId = (irParent as? IrClass)?.classId
val containingClass = classId?.let { ConeClassLikeLookupTagImpl(it) } val containingClassLookupTag = classId?.let { ConeClassLikeLookupTagImpl(it) }
val signature = signatureComposer.composeSignature(field, containingClass) val signature = signatureComposer.composeSignature(field, containingClassLookupTag)
return field.convertWithOffsets { startOffset, endOffset -> return field.convertWithOffsets { startOffset, endOffset ->
if (signature != null) { if (signature != null) {
symbolTable.declareField( symbolTable.declareField(
@@ -1102,12 +1091,11 @@ class Fir2IrDeclarationStorage(
isStatic = field.isStatic isStatic = field.isStatic
) )
}.apply { }.apply {
if (classId == null || !field.isStatic || val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(field, containingClassLookupTag)
!field.isSubstitutionOrIntersectionOverride && classId == field.containingClassLookupTag()?.classId if (staticFakeOverrideKey == null) {
) {
fieldCache[field] = this fieldCache[field] = this
} else { } else {
fieldStaticOverrideCache[field.name to classId] = this fieldStaticOverrideCache[staticFakeOverrideKey] = this
} }
val initializer = field.unwrapFakeOverrides().initializer val initializer = field.unwrapFakeOverrides().initializer
if (initializer is FirConstExpression<*>) { if (initializer is FirConstExpression<*>) {
@@ -1118,6 +1106,14 @@ class Fir2IrDeclarationStorage(
} }
} }
// This function returns null if this field/ownerClassId combination does not describe static fake override
private fun getFieldStaticFakeOverrideKey(field: FirField, ownerLookupTag: ConeClassLikeLookupTag?): FieldStaticOverrideKey? {
if (ownerLookupTag == null || !field.isStatic ||
!field.isSubstitutionOrIntersectionOverride && ownerLookupTag == field.containingClassLookupTag()
) return null
return FieldStaticOverrideKey(ownerLookupTag, field.name)
}
internal fun createIrParameter( internal fun createIrParameter(
valueParameter: FirValueParameter, valueParameter: FirValueParameter,
index: Int = UNDEFINED_PARAMETER_INDEX, index: Int = UNDEFINED_PARAMETER_INDEX,
@@ -1545,18 +1541,13 @@ class Fir2IrDeclarationStorage(
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null
): IrFieldSymbol { ): IrFieldSymbol {
val fir = firFieldSymbol.fir val fir = firFieldSymbol.fir
val unmatchedOwner = fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag != firFieldSymbol.containingClassLookupTag() val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(fir, fakeOverrideOwnerLookupTag)
if (!fir.isStatic || !unmatchedOwner) { if (staticFakeOverrideKey == null) {
fieldCache[fir]?.let { return it.symbol } fieldCache[fir]?.let { return it.symbol }
} } else {
if (fir.isStatic) {
generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag) generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag)
if (fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag !is ConeClassLookupTagWithFixedSymbol) { // Lazy static fake override should always exist
getCachedIrField(fir, fakeOverrideOwnerLookupTag)?.let { return fieldStaticOverrideCache[staticFakeOverrideKey]!!.symbol
return it.symbol
}
}
} }
// In case of type parameters from the parent as the field's return type, find the parent ahead to cache type parameters. // In case of type parameters from the parent as the field's return type, find the parent ahead to cache type parameters.
val irParent = findIrParent(fir) val irParent = findIrParent(fir)
@@ -165,7 +165,7 @@ class FakeOverrideGenerator(
if (!propertyOrFieldSymbol.isStatic) return@processPropertiesByName if (!propertyOrFieldSymbol.isStatic) return@processPropertiesByName
createFakeOverriddenIfNeeded( createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, propertyOrFieldSymbol, firClass, irClass, isLocal, propertyOrFieldSymbol,
{ field, _, _ -> declarationStorage.getCachedIrField(field, staticFakeOverrideOwnerLookupTag = null) }, { field, _, _ -> declarationStorage.getCachedIrFieldStaticFakeOverrideByDeclaration(field) },
{ field, irParent, _, _, _ -> { field, irParent, _, _, _ ->
declarationStorage.createIrField(field, irParent) declarationStorage.createIrField(field, irParent)
}, },