[LL FIR] KT-58257 Turn LLFirSession.isValid into a volatile variable

- We do not need `AtomicBoolean` here, because setting `_isValid` to a
  constant `false` suffices.
- Also replace the public setter of `isValid` with `markInvalid` to
  prohibit setting `isValid` to `true` again.
This commit is contained in:
Marco Pennekamp
2023-07-13 13:55:12 +02:00
committed by Space Team
parent 62a71b1559
commit 7f4af06ac7
2 changed files with 13 additions and 14 deletions
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
@OptIn(PrivateSessionConstructor::class) @OptIn(PrivateSessionConstructor::class)
@@ -32,20 +31,20 @@ abstract class LLFirSession(
val project: Project val project: Project
get() = ktModule.project get() = ktModule.project
private val _isValid = AtomicBoolean(true)
/** /**
* Whether the [LLFirSession] is valid. The session should not be used if it is invalid. * Whether the [LLFirSession] is valid. The session should not be used if it is invalid.
* */
* [isValid] should be set to `false` at the same time as the session is removed from [LLFirSessionCache]. Hence, [isValid] should be @Volatile
var isValid: Boolean = true
private set
/**
* [markInvalid] should be called at the same time as the session is removed from [LLFirSessionCache]. Hence, session validity should be
* managed by [LLFirSessionCache]. * managed by [LLFirSessionCache].
*/ */
var isValid: Boolean internal fun markInvalid() {
get() = _isValid.get() isValid = false
internal set(value) { }
check(!value) { "An invalid LL FIR session cannot become valid again." }
_isValid.set(value)
}
fun invalidate() { fun invalidate() {
val application = ApplicationManager.getApplication() val application = ApplicationManager.getApplication()
@@ -86,7 +86,7 @@ class LLFirSessionCache(private val project: Project) {
private fun removeSessionFrom(module: KtModule, storage: SessionStorage): Boolean { private fun removeSessionFrom(module: KtModule, storage: SessionStorage): Boolean {
val session = storage.remove(module) ?: return false val session = storage.remove(module) ?: return false
session.isValid = false session.markInvalid()
return true return true
} }
@@ -122,7 +122,7 @@ class LLFirSessionCache(private val project: Project) {
private fun removeAllSessionsFrom(storage: SessionStorage) { private fun removeAllSessionsFrom(storage: SessionStorage) {
// Because `removeAllSessionsFrom` is executed in a write action, the order of setting `isValid` and clearing `storage` is not // Because `removeAllSessionsFrom` is executed in a write action, the order of setting `isValid` and clearing `storage` is not
// important. // important.
storage.values.forEach { it.isValid = false } storage.values.forEach { it.markInvalid() }
storage.clear() storage.clear()
} }
@@ -133,7 +133,7 @@ class LLFirSessionCache(private val project: Project) {
// "collect and remove" approach also works. // "collect and remove" approach also works.
val scriptEntries = storage.entries.filter { (module, _) -> shouldBeRemoved(module) } val scriptEntries = storage.entries.filter { (module, _) -> shouldBeRemoved(module) }
for ((module, session) in scriptEntries) { for ((module, session) in scriptEntries) {
session.isValid = false session.markInvalid()
storage.remove(module) storage.remove(module)
} }
} }