[FIR IDE] Make one global lock for resolve

This commit is contained in:
Igor Yakovlev
2021-08-06 16:10:06 +02:00
parent b42358f893
commit 9bc695e245
2 changed files with 13 additions and 37 deletions
@@ -7,28 +7,14 @@ package org.jetbrains.kotlin.idea.fir.low.level.api
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
internal class FirPhaseRunner {
private val superTypesBodyResolveLock = ReentrantLock()
private val statusResolveLock = ReentrantLock()
private val implicitTypesResolveLock = ReentrantLock()
inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) = when (phase) {
FirResolvePhase.SUPER_TYPES -> superTypesBodyResolveLock.withLock {
runPhaseWithCustomResolveWithoutLock(resolve)
}
FirResolvePhase.STATUS -> statusResolveLock.withLock {
runPhaseWithCustomResolveWithoutLock(resolve)
}
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> implicitTypesResolveLock.withLock {
runPhaseWithCustomResolveWithoutLock(resolve)
}
else -> {
runPhaseWithCustomResolveWithoutLock(resolve)
}
}
/**
* We temporary disable multi-locks to fix deadlocks problem
* @see org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
*/
inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) =
runPhaseWithCustomResolveWithoutLock(resolve)
private inline fun runPhaseWithCustomResolveWithoutLock(crossinline resolve: () -> Unit) {
executeWithoutPCE {
@@ -5,36 +5,26 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.builder
import com.google.common.collect.MapMaker
import com.google.common.util.concurrent.CycleDetectingLockFactory
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
/**
* Keyed locks provider.
* !!! We temporary remove its correct implementation to fix deadlocks problem. Do not use this until this comment is present
*/
internal class LockProvider<KEY> {
private val locks: ConcurrentMap<KEY, ReentrantLock> = MapMaker().weakKeys().makeMap()
@Suppress("UnstableApiUsage")
private val lockFactory = CycleDetectingLockFactory.newInstance(CycleDetectingLockFactory.Policies.THROW)
@Suppress("NOTHING_TO_INLINE")
private inline fun getLockFor(key: KEY) = locks.getOrPut(key) {
val file = key as FirFile
val name = "${file.packageDirective.packageFqName.asString()}.${file.name}"
@Suppress("UnstableApiUsage")
lockFactory.newReentrantLock(name)
}
val globalLock = ReentrantLock()
@OptIn(PrivateForInline::class)
inline fun <R> withWriteLock(key: KEY, action: () -> R): R =
getLockFor(key).withLock(action)
globalLock.withLock(action)
@OptIn(PrivateForInline::class)
inline fun <R> withWriteLockPCECheck(key: KEY, lockingIntervalMs: Long, action: () -> R): R =
getLockFor(key).lockWithPCECheck(lockingIntervalMs, action)
globalLock.lockWithPCECheck(lockingIntervalMs, action) //We temporary disable multi-locks to fix deadlocks problem
}
/**