[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.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
internal class FirPhaseRunner { internal class FirPhaseRunner {
private val superTypesBodyResolveLock = ReentrantLock() /**
private val statusResolveLock = ReentrantLock() * We temporary disable multi-locks to fix deadlocks problem
private val implicitTypesResolveLock = ReentrantLock() * @see org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
*/
inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) = when (phase) { inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) =
FirResolvePhase.SUPER_TYPES -> superTypesBodyResolveLock.withLock { runPhaseWithCustomResolveWithoutLock(resolve)
runPhaseWithCustomResolveWithoutLock(resolve)
}
FirResolvePhase.STATUS -> statusResolveLock.withLock {
runPhaseWithCustomResolveWithoutLock(resolve)
}
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> implicitTypesResolveLock.withLock {
runPhaseWithCustomResolveWithoutLock(resolve)
}
else -> {
runPhaseWithCustomResolveWithoutLock(resolve)
}
}
private inline fun runPhaseWithCustomResolveWithoutLock(crossinline resolve: () -> Unit) { private inline fun runPhaseWithCustomResolveWithoutLock(crossinline resolve: () -> Unit) {
executeWithoutPCE { executeWithoutPCE {
@@ -5,36 +5,26 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.builder 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.fir.declarations.FirFile
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock 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> { internal class LockProvider<KEY> {
private val locks: ConcurrentMap<KEY, ReentrantLock> = MapMaker().weakKeys().makeMap() val globalLock = ReentrantLock()
@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)
}
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <R> withWriteLock(key: KEY, action: () -> R): R = inline fun <R> withWriteLock(key: KEY, action: () -> R): R =
getLockFor(key).withLock(action) globalLock.withLock(action)
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <R> withWriteLockPCECheck(key: KEY, lockingIntervalMs: Long, action: () -> R): R = 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
} }
/** /**