[Analysis API FIR] fix invalid usages of CachedValue

it should not cache map as values are stored on soft references
This commit is contained in:
Ilya Kirillov
2022-09-30 15:51:10 +02:00
committed by teamcity
parent 457069090b
commit fceb3425c8
6 changed files with 116 additions and 58 deletions
@@ -41,13 +41,14 @@ internal class LLFirResolveSessionDepended(
override val useSiteKtModule: KtModule get() = originalFirResolveSession.useSiteKtModule
override val useSiteFirSession get() = originalFirResolveSession.useSiteFirSession
private val scopeSessionProviderCache by softCachedValue(
private val scopeSessionProviderCache = SoftCachedMap.create<FirSession, LLFirScopeSessionProvider>(
project,
PsiModificationTracker.MODIFICATION_COUNT,
ProjectRootModificationTracker.getInstance(project),
) {
ConcurrentHashMap<FirSession, LLFirScopeSessionProvider>()
}
SoftCachedMap.Kind.SOFT_KEYS_SOFT_VALUES,
listOf(
PsiModificationTracker.MODIFICATION_COUNT,
ProjectRootModificationTracker.getInstance(project)
)
)
override fun getScopeSessionFor(firSession: FirSession): ScopeSession {
return scopeSessionProviderCache
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootModificationTracker
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
@@ -19,33 +20,23 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveS
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.analysis.utils.caches.getValue
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.withLock
import org.jetbrains.kotlin.analysis.utils.caches.SoftCachedMap
internal class LLFirResolveSessionService(project: Project) {
private val sessionProviderStorage = LLFirSessionProviderStorage(project)
private val stateCache by softCachedValue(
private val cache = SoftCachedMap.create<KtModule, LLFirResolvableResolveSession>(
project,
project.createProjectWideOutOfBlockModificationTracker(),
ProjectRootModificationTracker.getInstance(project),
) {
mutableMapOf<KtModule, LLFirResolvableResolveSession>()
}
private val cacheLock = ReentrantReadWriteLock()
SoftCachedMap.Kind.STRONG_KEYS_SOFT_VALUES,
listOf(
ProjectRootModificationTracker.getInstance(project),
project.createProjectWideOutOfBlockModificationTracker(),
)
)
fun getFirResolveSession(module: KtModule): LLFirResolvableResolveSession {
cacheLock.readLock().withLock {
stateCache[module]?.let { return it }
}
cacheLock.writeLock().withLock {
stateCache[module]?.let { return it }
val session = createFirResolveSessionFor(module, sessionProviderStorage)
stateCache[module] = session
return session
return cache.getOrPut(module) {
createFirResolveSessionFor(module, sessionProviderStorage)
}
}
@@ -9,6 +9,7 @@ import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
@@ -40,7 +41,7 @@ import org.jetbrains.kotlin.psi.*
* PSI index based implementation of [FirPredicateBasedProvider].
*/
internal class LLFirIdePredicateBasedProvider(
private val session: FirSession,
private val session: LLFirSourcesSession,
private val annotationsResolver: KotlinAnnotationsResolver,
private val declarationProvider: KotlinDeclarationProvider,
) : FirPredicateBasedProvider() {
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootModificationTracker
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.analysis.utils.caches.getValue
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
import org.jetbrains.kotlin.analysis.utils.caches.SoftCachedMap
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import java.util.concurrent.ConcurrentHashMap
@@ -28,12 +25,11 @@ abstract class LLFirScopeSessionProvider {
private class LLFirInvalidatableScopeSessionProvider(project: Project, invalidationTrackers: List<Any>) : LLFirScopeSessionProvider() {
// ScopeSession is thread-local, so we use Thread id as a key
// We cannot use thread locals here as it may lead to memory leaks
private val cache by softCachedValue(
private val cache = SoftCachedMap.create<Long, ScopeSession>(
project,
*invalidationTrackers.toTypedArray(),
) {
ConcurrentHashMap<Long, ScopeSession>()
}
SoftCachedMap.Kind.STRONG_KEYS_SOFT_VALUES,
invalidationTrackers
)
override fun getScopeSession(): ScopeSession {
return cache.getOrPut(Thread.currentThread().id) { ScopeSession() }