From 2bf5a58a300dafcb4a0dcb08a098183e915be272 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Tue, 16 Jan 2024 11:10:54 +0100 Subject: [PATCH] [Fir2Ir] Don't use FirSyntheticProperty as the cache key ^KT-64871 --- ...LFirBlackBoxCodegenBasedTestGenerated.java | 12 +++++ ...rsedBlackBoxCodegenBasedTestGenerated.java | 12 +++++ .../fir/backend/Fir2IrCommonMemberStorage.kt | 1 + .../fir/backend/Fir2IrDeclarationStorage.kt | 54 ++++++++++++++----- ...LightTreeBlackBoxCodegenTestGenerated.java | 12 +++++ ...hIrFakeOverrideGeneratorTestGenerated.java | 12 +++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 12 +++++ .../box/multiplatform/k2/hashSetSize.kt | 20 +++++++ .../box/multiplatform/k2/synteticProperty.kt | 32 +++++++++++ 9 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt create mode 100644 compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java index 795b7e73fad..e5445781ff6 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java @@ -35385,6 +35385,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo runTest("compiler/testData/codegen/box/multiplatform/k2/extensionPropertiesOverloads.kt"); } + @Test + @TestMetadata("hashSetSize.kt") + public void testHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt"); + } + @Test @TestMetadata("internalOverride.kt") public void testInternalOverride() throws Exception { @@ -35421,6 +35427,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo runTest("compiler/testData/codegen/box/multiplatform/k2/staticjavaFieldInCommonCode.kt"); } + @Test + @TestMetadata("synteticProperty.kt") + public void testSynteticProperty() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/multiplatform/k2/annotations") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java index 2ed44b2a11a..9095a159c91 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java @@ -35385,6 +35385,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi runTest("compiler/testData/codegen/box/multiplatform/k2/extensionPropertiesOverloads.kt"); } + @Test + @TestMetadata("hashSetSize.kt") + public void testHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt"); + } + @Test @TestMetadata("internalOverride.kt") public void testInternalOverride() throws Exception { @@ -35421,6 +35427,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi runTest("compiler/testData/codegen/box/multiplatform/k2/staticjavaFieldInCommonCode.kt"); } + @Test + @TestMetadata("synteticProperty.kt") + public void testSynteticProperty() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/multiplatform/k2/annotations") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt index 12da444c9ab..cfd6758a70c 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt @@ -45,6 +45,7 @@ class Fir2IrCommonMemberStorage( val fieldCache: ConcurrentHashMap = ConcurrentHashMap() val propertyCache: ConcurrentHashMap = ConcurrentHashMap() + val syntheticPropertyCache: ConcurrentHashMap = ConcurrentHashMap() val getterForPropertyCache: ConcurrentHashMap = ConcurrentHashMap() val setterForPropertyCache: ConcurrentHashMap = ConcurrentHashMap() val backingFieldForPropertyCache: ConcurrentHashMap = ConcurrentHashMap() 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 333fb8ed126..e082159fbe5 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 @@ -82,7 +82,32 @@ class Fir2IrDeclarationStorage( private val initializerCache: ConcurrentHashMap = ConcurrentHashMap() - private val propertyCache: ConcurrentHashMap = commonMemberStorage.propertyCache + class PropertyCacheStorage( + val normal: ConcurrentHashMap, + val synthetic: ConcurrentHashMap + ) { + /** + * Fir synthetic properties are session-dependent, so it can't be used as a cache key + * That's why, we are using original java function as a key in that case. + */ + private val FirSyntheticProperty.cacheKey + get() = symbol.getterSymbol!!.delegateFunctionSymbol.fir + + operator fun set(fir: FirProperty, value: IrPropertySymbol) { + when (fir) { + is FirSyntheticProperty -> synthetic[fir.cacheKey] = value + else -> normal[fir] = value + } + } + + operator fun get(fir: FirProperty): IrPropertySymbol? { + return when (fir) { + is FirSyntheticProperty -> synthetic[fir.cacheKey] + else -> normal[fir] + } + } + } + private val propertyCache = PropertyCacheStorage(commonMemberStorage.propertyCache, commonMemberStorage.syntheticPropertyCache) private val getterForPropertyCache: ConcurrentHashMap = commonMemberStorage.getterForPropertyCache private val setterForPropertyCache: ConcurrentHashMap = @@ -104,7 +129,8 @@ class Fir2IrDeclarationStorage( fun forEachCachedDeclarationSymbol(block: (IrSymbol) -> Unit) { functionCache.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapFunctionSymbol, block) constructorCache.values.forEach(block) - propertyCache.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapPropertySymbol, block) + propertyCache.normal.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapPropertySymbol, block) + propertyCache.synthetic.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapPropertySymbol, block) getterForPropertyCache.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapFunctionSymbol, block) setterForPropertyCache.values.forEachWithRemapping(symbolsMappingForLazyClasses::remapFunctionSymbol, block) backingFieldForPropertyCache.values.forEach(block) @@ -315,7 +341,8 @@ class Fir2IrDeclarationStorage( val cachedIrCallable = getCachedIrCallableSymbol( function, fakeOverrideOwnerLookupTag, - functionCache, + functionCache::get, + functionCache::set, signatureCalculator ) { signature -> symbolTable.referenceSimpleFunctionIfAny(signature) @@ -757,7 +784,8 @@ class Fir2IrDeclarationStorage( val symbol = getCachedIrCallableSymbol( property, fakeOverrideOwnerLookupTag, - propertyCache, + propertyCache::get, + propertyCache::set, signatureCalculator ) { signature -> symbolTable.referencePropertyIfAny(signature) @@ -1138,7 +1166,8 @@ class Fir2IrDeclarationStorage( private inline fun getCachedIrCallableSymbol( declaration: FC, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, - cache: MutableMap, + cacheGetter: (FC) -> IS?, + cacheSetter: (FC, IS) -> Unit, signatureCalculator: () -> IdSignature?, referenceIfAny: (IdSignature) -> IS? ): IS? { @@ -1166,12 +1195,12 @@ class Fir2IrDeclarationStorage( ) irForFirSessionDependantDeclarationMap[key]?.let { return it as IS } } else { - cache[declaration]?.let { return it } + cacheGetter(declaration)?.let { return it } } // TODO: Special case mentioned above. Should be removed after fixing creation. KT-61085 if (declaration.isSubstitutionOrIntersectionOverride) { - cache[declaration]?.let { return it } + cacheGetter(declaration)?.let { return it } } /* @@ -1222,7 +1251,7 @@ class Fir2IrDeclarationStorage( * * TODO: potentially this situation won't happen after migration from FIR2IR f/o generator to IR f/o generator (see KT-58861) */ - cache[declaration] = cachedInSymbolTable + cacheSetter(declaration, cachedInSymbolTable) } declaration.initialSignatureAttr != null -> { /* @@ -1230,20 +1259,20 @@ class Fir2IrDeclarationStorage( * It leads to the situations when we have two different mapped FIR functions for the same original function * (and same IR function) */ - cache[declaration] = cachedInSymbolTable + cacheSetter(declaration, cachedInSymbolTable) } declaration.symbol is FirJavaOverriddenSyntheticPropertySymbol -> { /* * Synthetic properties for java classes, if those properties are based on real Kotlin properties are also session * dependant */ - cache[declaration] = cachedInSymbolTable + cacheSetter(declaration, cachedInSymbolTable) } declaration.origin.generatedAnyMethod -> { /* * Generated methods from Any for data and value classes are session-dependant */ - cache[declaration] = cachedInSymbolTable + cacheSetter(declaration, cachedInSymbolTable) } else -> { error("IR declaration with signature \"$signature\" found in SymbolTable and not found in declaration storage") @@ -1345,7 +1374,8 @@ class Fir2IrDeclarationStorage( @LeakedDeclarationCaches internal fun fillUnboundSymbols() { fillUnboundSymbols(functionCache) - fillUnboundSymbols(propertyCache) + fillUnboundSymbols(propertyCache.normal) + fillUnboundSymbols(propertyCache.synthetic) } @LeakedDeclarationCaches diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 9ecf8381d39..9a5aba2f88c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -35000,6 +35000,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/multiplatform/k2/extensionPropertiesOverloads.kt"); } + @Test + @TestMetadata("hashSetSize.kt") + public void testHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt"); + } + @Test @TestMetadata("internalOverride.kt") public void testInternalOverride() throws Exception { @@ -35036,6 +35042,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/multiplatform/k2/staticjavaFieldInCommonCode.kt"); } + @Test + @TestMetadata("synteticProperty.kt") + public void testSynteticProperty() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/multiplatform/k2/annotations") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index 66b6da799db..10d45d2032c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -35000,6 +35000,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated runTest("compiler/testData/codegen/box/multiplatform/k2/extensionPropertiesOverloads.kt"); } + @Test + @TestMetadata("hashSetSize.kt") + public void testHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt"); + } + @Test @TestMetadata("internalOverride.kt") public void testInternalOverride() throws Exception { @@ -35036,6 +35042,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated runTest("compiler/testData/codegen/box/multiplatform/k2/staticjavaFieldInCommonCode.kt"); } + @Test + @TestMetadata("synteticProperty.kt") + public void testSynteticProperty() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/multiplatform/k2/annotations") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index ffaba75390d..a9c374380e5 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -35000,6 +35000,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/k2/extensionPropertiesOverloads.kt"); } + @Test + @TestMetadata("hashSetSize.kt") + public void testHashSetSize() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt"); + } + @Test @TestMetadata("internalOverride.kt") public void testInternalOverride() throws Exception { @@ -35036,6 +35042,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/k2/staticjavaFieldInCommonCode.kt"); } + @Test + @TestMetadata("synteticProperty.kt") + public void testSynteticProperty() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/multiplatform/k2/annotations") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt b/compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt new file mode 100644 index 00000000000..0a5e2dc2f1a --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/k2/hashSetSize.kt @@ -0,0 +1,20 @@ +// LANGUAGE: +MultiPlatformProjects +// WITH_STDLIB +// FULL_JDK +// TARGET_BACKEND: JVM_IR + +// MODULE: common +// FILE: common.kt + +val p = LinkedHashMap() + +// MODULE: platform()()(common) +// FILE: platform.kt + +val q = object : LinkedHashMap() { + val s = size +} + +fun box() : String { + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt b/compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt new file mode 100644 index 00000000000..674662c5634 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/k2/synteticProperty.kt @@ -0,0 +1,32 @@ +// LANGUAGE: +MultiPlatformProjects +// TARGET_BACKEND: JVM_IR + +// MODULE: lib +// FILE: Derived.java + +public class Derived extends Base { + public String getFoo() { return "OK"; } +} + +// FILE: Base.kt +open class Base { + open val foo: String + get() = "FAIL" +} + + +// MODULE: common(lib) +// FILE: common.kt + +val p = Derived().foo + +// MODULE: platform(lib)()(common) +// FILE: platform.kt + +val q = object : Derived() { + val s = foo +} + +fun box() : String { + return "OK" +} \ No newline at end of file