[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:
+7
-6
@@ -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
|
||||
|
||||
+11
-20
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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() {
|
||||
|
||||
+5
-9
@@ -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() }
|
||||
|
||||
Reference in New Issue
Block a user