[LL FIR] implement lock resolution algorithm for jumping phases
This commit extends `LLFirLockProvider` API functionality to provide `withJumpingLock`, which can be safely used in multithreaded scenarios. Comparing to regular `withWriteLock`/`withReadLock`, the new API has a bit more overhead as we have to maintain `jumpingResolutionStatesStack` and `FirInProcessOfResolvingToJumpingPhaseState` even without contention. See KDoc of `LLFirLockProvider#withJumpingLockImpl` for implementation details. The implicit type phase has been migrated to the new approach, so now it is safe to drop the last global phase lock. Potentially, we can have some benefits from migration of other jumping phases to this API. ^KT-56551 Fixed ^KT-55750 Fixed
This commit is contained in:
committed by
Space Team
parent
58ed52ee1f
commit
e03f8b503f
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
/**
|
||||
* The current lazy resolve state of some [org.jetbrains.kotlin.fir.FirElementWithResolveState].
|
||||
@@ -99,10 +99,9 @@ class FirInProcessOfResolvingToPhaseStateWithoutBarrier private constructor(
|
||||
*
|
||||
* @see FirResolveState
|
||||
*/
|
||||
class FirInProcessOfResolvingToPhaseStateWithBarrier(
|
||||
override val resolvingTo: FirResolvePhase,
|
||||
val barrier: CountDownLatch,
|
||||
) : FirInProcessOfResolvingToPhaseState() {
|
||||
class FirInProcessOfResolvingToPhaseStateWithBarrier(override val resolvingTo: FirResolvePhase) : FirInProcessOfResolvingToPhaseState() {
|
||||
val barrier: CountDownLatch = CountDownLatch(1)
|
||||
|
||||
init {
|
||||
require(resolvingTo != FirResolvePhase.RAW_FIR) {
|
||||
"Cannot resolve to ${FirResolvePhase.RAW_FIR} as it's a first phase"
|
||||
@@ -110,4 +109,26 @@ class FirInProcessOfResolvingToPhaseStateWithBarrier(
|
||||
}
|
||||
|
||||
override fun toString(): String = "ResolvingToWithBarrier($resolvingTo)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class representing the lazy resolve state of some [FirElementWithResolveState] in a case
|
||||
* when some thread is resolving it from [resolvePhase] to [resolvingTo] and potentially can have a cycle
|
||||
* between threads.
|
||||
*
|
||||
* Some other threads can wait on a [latch].
|
||||
*
|
||||
* [waitingFor] shows that the current state is waining for the result of another [FirElementWithResolveState] element.
|
||||
* This another element can be in the process of resolution as from the same thread and also from another thread.
|
||||
* In the second case the current thread will wait on the corresponding [latch].
|
||||
*
|
||||
* @see FirResolveState
|
||||
*/
|
||||
class FirInProcessOfResolvingToJumpingPhaseState(override val resolvingTo: FirResolvePhase) : FirInProcessOfResolvingToPhaseState() {
|
||||
val latch = CountDownLatch(1)
|
||||
|
||||
@Volatile
|
||||
var waitingFor: FirInProcessOfResolvingToJumpingPhaseState? = null
|
||||
|
||||
override fun toString(): String = "ResolvingJumpingTo($resolvingTo)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user