From 8ffabddf75618d99e3b730d58914b279bc6c643a Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 25 Nov 2022 10:32:18 +0100 Subject: [PATCH] FIR2IR: cleanup field static fake override caching --- .../fir/backend/Fir2IrDeclarationStorage.kt | 59 ++++++++----------- .../generators/FakeOverrideGenerator.kt | 2 +- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 0f7d6b8affd..3c321aeb2fb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -51,10 +51,7 @@ import org.jetbrains.kotlin.ir.types.IrErrorType import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.addToStdlib.runUnless @@ -109,7 +106,9 @@ class Fir2IrDeclarationStorage( private val fieldCache = ConcurrentHashMap() - private val fieldStaticOverrideCache = ConcurrentHashMap, IrField>() + private data class FieldStaticOverrideKey(val lookupTag: ConeClassLikeLookupTag, val name: Name) + + private val fieldStaticOverrideCache = ConcurrentHashMap() private val localStorage by threadLocal { Fir2IrLocalStorage() } @@ -1018,19 +1017,9 @@ class Fir2IrDeclarationStorage( fun getCachedIrDelegateOrBackingField(field: FirField): IrField? = fieldCache[field] - fun getCachedIrField( - field: FirField, - // Always should be null for non-static - // 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 getCachedIrFieldStaticFakeOverrideByDeclaration(field: FirField): IrField? { + val ownerLookupTag = field.containingClassLookupTag() ?: return null + return fieldStaticOverrideCache[FieldStaticOverrideKey(ownerLookupTag, field.name)] } fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { @@ -1078,8 +1067,8 @@ class Fir2IrDeclarationStorage( ): IrField = convertCatching(field) { val type = typeRef.toIrType() val classId = (irParent as? IrClass)?.classId - val containingClass = classId?.let { ConeClassLikeLookupTagImpl(it) } - val signature = signatureComposer.composeSignature(field, containingClass) + val containingClassLookupTag = classId?.let { ConeClassLikeLookupTagImpl(it) } + val signature = signatureComposer.composeSignature(field, containingClassLookupTag) return field.convertWithOffsets { startOffset, endOffset -> if (signature != null) { symbolTable.declareField( @@ -1102,12 +1091,11 @@ class Fir2IrDeclarationStorage( isStatic = field.isStatic ) }.apply { - if (classId == null || !field.isStatic || - !field.isSubstitutionOrIntersectionOverride && classId == field.containingClassLookupTag()?.classId - ) { + val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(field, containingClassLookupTag) + if (staticFakeOverrideKey == null) { fieldCache[field] = this } else { - fieldStaticOverrideCache[field.name to classId] = this + fieldStaticOverrideCache[staticFakeOverrideKey] = this } val initializer = field.unwrapFakeOverrides().initializer 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( valueParameter: FirValueParameter, index: Int = UNDEFINED_PARAMETER_INDEX, @@ -1545,18 +1541,13 @@ class Fir2IrDeclarationStorage( fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null ): IrFieldSymbol { val fir = firFieldSymbol.fir - val unmatchedOwner = fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag != firFieldSymbol.containingClassLookupTag() - if (!fir.isStatic || !unmatchedOwner) { + val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(fir, fakeOverrideOwnerLookupTag) + if (staticFakeOverrideKey == null) { fieldCache[fir]?.let { return it.symbol } - } - - if (fir.isStatic) { + } else { generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag) - if (fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag !is ConeClassLookupTagWithFixedSymbol) { - getCachedIrField(fir, fakeOverrideOwnerLookupTag)?.let { - return it.symbol - } - } + // Lazy static fake override should always exist + return fieldStaticOverrideCache[staticFakeOverrideKey]!!.symbol } // 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) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 577111a17c2..7234c27aace 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -165,7 +165,7 @@ class FakeOverrideGenerator( if (!propertyOrFieldSymbol.isStatic) return@processPropertiesByName createFakeOverriddenIfNeeded( firClass, irClass, isLocal, propertyOrFieldSymbol, - { field, _, _ -> declarationStorage.getCachedIrField(field, staticFakeOverrideOwnerLookupTag = null) }, + { field, _, _ -> declarationStorage.getCachedIrFieldStaticFakeOverrideByDeclaration(field) }, { field, irParent, _, _, _ -> declarationStorage.createIrField(field, irParent) },