From 2b40ef6b05a3db4c901bac82cbb75005ed2054f4 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 7 Feb 2024 21:43:21 +0100 Subject: [PATCH] [LL] `CleanableSoftValueCache`: Avoid cleanup on already removed values - The cache guarantees deterministic cleanup on removal, so if the reference has already been removed from the cache, there is no need to clean it up again. - Still, I don't want to guarantee that `SoftValueCleaner` is only invoked once (see its documentation), as soft reference semantics cannot be tested properly in our current test infrastructure. ^KT-61222 --- .../low/level/api/fir/caches/CleanableSoftValueCache.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/CleanableSoftValueCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/CleanableSoftValueCache.kt index d86bbe8a138..6b875cdccf0 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/CleanableSoftValueCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/CleanableSoftValueCache.kt @@ -61,8 +61,12 @@ class CleanableSoftValueCache( @Suppress("UNCHECKED_CAST") ref as SoftReferenceWithCleanup - backingMap.remove(ref.key, ref) - ref.performCleanup() + val wasRemoved = backingMap.remove(ref.key, ref) + + // If `ref` already wasn't part of the map, it will have been cleaned up by a deterministic removal operation. + if (wasRemoved) { + ref.performCleanup() + } } }