IR: introduce IrLock

Use a single lock object for synchronization to avoid deadlocks.
This commit is contained in:
Georgy Bronnikov
2021-02-02 14:12:34 +03:00
parent 215556511e
commit 42279c3b5b
24 changed files with 112 additions and 86 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -22,6 +23,7 @@ interface Fir2IrComponents {
val irBuiltIns: IrBuiltIns
val builtIns: Fir2IrBuiltIns
val irFactory: IrFactory
val lock: IrLock
val classifierStorage: Fir2IrClassifierStorage
val declarationStorage: Fir2IrDeclarationStorage
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -36,4 +37,7 @@ class Fir2IrComponentsStorage(
override lateinit var annotationGenerator: AnnotationGenerator
override lateinit var callGenerator: CallAndReferenceGenerator
override lateinit var fakeOverrideGenerator: FakeOverrideGenerator
override val lock: IrLock
get() = symbolTable.lock
}
@@ -1145,40 +1145,42 @@ class Fir2IrDeclarationStorage(
val fir = firSymbol.fir as F
val irParent by lazy { findIrParent(fir) }
val signature by lazy { signatureComposer.composeSignature(fir) }
getCachedIrDeclaration(fir) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent
signature
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin)
// TODO: package fragment members (?)
when (val parent = irParent) {
is Fir2IrLazyClass -> {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
synchronized(symbolTable.lock) {
getCachedIrDeclaration(fir) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent
signature
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin)
// TODO: package fragment members (?)
when (val parent = irParent) {
is Fir2IrLazyClass -> {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
}
signature?.let {
return createIrLazyDeclaration(it, parent, declarationOrigin).symbol
}
}
signature?.let {
return createIrLazyDeclaration(it, parent, declarationOrigin).symbol
}
}
is IrLazyClass -> {
val unwrapped = fir.unwrapFakeOverrides()
if (unwrapped !== fir) {
when (unwrapped) {
is FirSimpleFunction -> {
return getIrFunctionSymbol(unwrapped.symbol)
}
is FirProperty -> {
return getIrPropertySymbol(unwrapped.symbol)
is IrLazyClass -> {
val unwrapped = fir.unwrapFakeOverrides()
if (unwrapped !== fir) {
when (unwrapped) {
is FirSimpleFunction -> {
return getIrFunctionSymbol(unwrapped.symbol)
}
is FirProperty -> {
return getIrPropertySymbol(unwrapped.symbol)
}
}
}
}
}
return createIrDeclaration(irParent, declarationOrigin).apply {
(this as IrDeclaration).setAndModifyParent(irParent)
}.symbol
}
return createIrDeclaration(irParent, declarationOrigin).apply {
(this as IrDeclaration).setAndModifyParent(irParent)
}.symbol
}
private fun computeDeclarationOrigin(
@@ -38,7 +38,7 @@ interface AbstractFir2IrLazyDeclaration<F : FirMemberDeclaration, D : IrDeclarat
}
}
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar {
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(lock) {
fir.annotations.mapNotNull {
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
}
@@ -68,7 +68,7 @@ abstract class AbstractFir2IrLazyFunction<F : FirMemberDeclaration>(
get() = null
set(_) = error("We should never need to store body of external functions.")
override var visibility: DescriptorVisibility by lazyVar {
override var visibility: DescriptorVisibility by lazyVar(lock) {
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility)
}
@@ -96,11 +96,11 @@ class Fir2IrLazyClass(
override val isFun: Boolean
get() = fir.isFun
override var superTypes: List<IrType> by lazyVar {
override var superTypes: List<IrType> by lazyVar(lock) {
fir.superTypeRefs.map { it.toIrType(typeConverter) }
}
override var thisReceiver: IrValueParameter? by lazyVar {
override var thisReceiver: IrValueParameter? by lazyVar(lock) {
symbolTable.enterScope(this)
val typeArguments = fir.typeParameters.map {
IrSimpleTypeImpl(
@@ -124,7 +124,7 @@ class Fir2IrLazyClass(
.also(fakeOverrideGenerator::bindOverriddenSymbols)
}
override val declarations: MutableList<IrDeclaration> by lazyVar {
override val declarations: MutableList<IrDeclaration> by lazyVar(lock) {
val result = mutableListOf<IrDeclaration>()
val processedNames = mutableSetOf<Name>()
// NB: it's necessary to take all callables from scope,
@@ -67,11 +67,11 @@ class Fir2IrLazyConstructor(
error("Mutating Fir2Ir lazy elements is not possible")
}
override var returnType: IrType by lazyVar {
override var returnType: IrType by lazyVar(lock) {
fir.returnTypeRef.toIrType(typeConverter)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
val containingClass = parent as? IrClass
val outerClass = containingClass?.parentClassOrNull
if (containingClass?.isInner == true && outerClass != null) {
@@ -92,7 +92,7 @@ class Fir2IrLazyConstructor(
error("Mutating Fir2Ir lazy elements is not possible")
}
override var valueParameters: List<IrValueParameter> by lazyVar {
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
declarationStorage.enterScope(this)
fir.valueParameters.mapIndexed { index, valueParameter ->
declarationStorage.createIrParameter(
@@ -86,7 +86,7 @@ class Fir2IrLazyProperty(
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
override var backingField: IrField? by lazyVar {
override var backingField: IrField? by lazyVar(lock) {
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
val parent = parent
when {
@@ -126,7 +126,7 @@ class Fir2IrLazyProperty(
}
}
override var getter: IrSimpleFunction? by lazyVar {
override var getter: IrSimpleFunction? by lazyVar(lock) {
if (fir.isConst) return@lazyVar null
Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
@@ -155,7 +155,7 @@ class Fir2IrLazyProperty(
}
}
override var setter: IrSimpleFunction? by lazyVar {
override var setter: IrSimpleFunction? by lazyVar(lock) {
if (!fir.isVar) null else Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {
@@ -45,11 +45,11 @@ class Fir2IrLazyPropertyAccessor(
override val name: Name
get() = Name.special("<${if (isSetter) "set" else "get"}-${firParentProperty.name}>")
override var returnType: IrType by lazyVar {
override var returnType: IrType by lazyVar(lock) {
if (isSetter) irBuiltIns.unitType else firParentProperty.returnTypeRef.toIrType(typeConverter, conversionTypeContext)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, firParentProperty)
) {
@@ -57,13 +57,13 @@ class Fir2IrLazyPropertyAccessor(
} else null
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar {
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
firParentProperty.receiverTypeRef?.let {
createThisReceiverParameter(it.toIrType(typeConverter, conversionTypeContext))
}
}
override var valueParameters: List<IrValueParameter> by lazyVar {
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
if (!isSetter) emptyList()
else {
declarationStorage.enterScope(this)
@@ -81,7 +81,7 @@ class Fir2IrLazyPropertyAccessor(
}
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar {
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar(lock) {
firParentProperty.generateOverriddenAccessorSymbols(
firParentClass,
!isSetter,
@@ -37,24 +37,24 @@ class Fir2IrLazySimpleFunction(
override val name: Name
get() = fir.name
override var returnType: IrType by lazyVar {
override var returnType: IrType by lazyVar(lock) {
fir.returnTypeRef.toIrType(typeConverter)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, fir)) {
createThisReceiverParameter(thisType = containingClass.thisReceiver?.type ?: error("No this receiver for containing class"))
} else null
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar {
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
fir.receiverTypeRef?.let {
createThisReceiverParameter(it.toIrType(typeConverter))
}
}
override var valueParameters: List<IrValueParameter> by lazyVar {
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
declarationStorage.enterScope(this)
fir.valueParameters.mapIndexed { index, valueParameter ->
declarationStorage.createIrParameter(
@@ -67,7 +67,7 @@ class Fir2IrLazySimpleFunction(
}
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar {
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar(lock) {
val parent = parent
if (isFakeOverride && parent is Fir2IrLazyClass) {
fakeOverrideGenerator.calcBaseSymbolsForFakeOverrideFunction(
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2020 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.ir
/*
Lock protecting accesses to global IR structures during by-file lowerings.
*/
class IrLock
@@ -47,14 +47,14 @@ class IrLazyClass(
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
override var thisReceiver: IrValueParameter? by lazyVar {
override var thisReceiver: IrValueParameter? by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
descriptor.thisAsReceiverParameter.generateReceiverParameterStub().apply { parent = this@IrLazyClass }
}
}
override val declarations: MutableList<IrDeclaration> by lazyVar {
override val declarations: MutableList<IrDeclaration> by lazyVar(stubGenerator.lock) {
ArrayList<IrDeclaration>().also {
typeTranslator.buildWithScope(this) {
generateChildStubs(descriptor.constructors, it)
@@ -68,13 +68,13 @@ class IrLazyClass(
}
}
override var typeParameters: List<IrTypeParameter> by lazyVar {
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
descriptor.declaredTypeParameters.mapTo(arrayListOf()) {
stubGenerator.generateOrGetTypeParameterStub(it)
}
}
override var superTypes: List<IrType> by lazyVar {
override var superTypes: List<IrType> by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
// TODO get rid of code duplication, see ClassGenerator#generateClass
descriptor.typeConstructor.supertypes.mapNotNullTo(arrayListOf()) {
@@ -56,7 +56,7 @@ class IrLazyConstructor(
get() = null
set(_) = error("We should never need to store metadata of external declarations.")
override var typeParameters: List<IrTypeParameter> by lazyVar {
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
stubGenerator.symbolTable.withScope(this) {
val classTypeParametersCount = descriptor.constructedClass.original.declaredTypeParameters.size
@@ -47,11 +47,11 @@ interface IrLazyDeclarationBase : IrDeclaration {
}
}
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar {
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(stubGenerator.lock) {
descriptor.annotations.mapNotNull(typeTranslator.constantValueGenerator::generateAnnotationConstructorCall).toMutableList()
}
fun createLazyParent(): ReadWriteProperty<Any?, IrDeclarationParent> = lazyVar {
fun createLazyParent(): ReadWriteProperty<Any?, IrDeclarationParent> = lazyVar(stubGenerator.lock) {
val currentDescriptor = descriptor
val containingDeclaration =
@@ -43,17 +43,17 @@ class IrLazyField(
override var parent: IrDeclarationParent by createLazyParent()
override var annotations: List<IrConstructorCall> by lazyVar {
override var annotations: List<IrConstructorCall> by lazyVar(stubGenerator.lock) {
descriptor.backingField?.annotations
?.mapNotNullTo(mutableListOf(), typeTranslator.constantValueGenerator::generateAnnotationConstructorCall)
?: mutableListOf()
}
override var type: IrType by lazyVar {
override var type: IrType by lazyVar(stubGenerator.lock) {
descriptor.type.toIrType()
}
override var initializer: IrExpressionBody? by lazyVar {
override var initializer: IrExpressionBody? by lazyVar(stubGenerator.lock) {
descriptor.compileTimeInitializer?.let {
factory.createExpressionBody(
typeTranslator.constantValueGenerator.generateConstantValueAsExpression(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it)
@@ -61,7 +61,7 @@ class IrLazyField(
}
}
override var correspondingPropertySymbol: IrPropertySymbol? by lazyVar {
override var correspondingPropertySymbol: IrPropertySymbol? by lazyVar(stubGenerator.lock) {
stubGenerator.generatePropertyStub(descriptor).symbol
}
@@ -64,7 +64,7 @@ class IrLazyFunction(
get() = null
set(_) = error("We should never need to store metadata of external declarations.")
override var typeParameters: List<IrTypeParameter> by lazyVar {
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
stubGenerator.symbolTable.withScope(this) {
val propertyIfAccessor = descriptor.propertyIfAccessor
@@ -81,7 +81,7 @@ class IrLazyFunction(
}
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar {
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar(stubGenerator.lock) {
descriptor.overriddenDescriptors.mapTo(arrayListOf()) {
stubGenerator.generateFunctionStub(it.original).symbol
}
@@ -26,7 +26,7 @@ interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer
}
fun createValueParameters(): ReadWriteProperty<Any?, List<IrValueParameter>> =
lazyVar {
lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
descriptor.valueParameters.mapTo(arrayListOf()) {
stubGenerator.generateValueParameterStub(it).apply { parent = this@IrLazyFunctionBase }
@@ -38,7 +38,7 @@ interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer
parameter: ReceiverParameterDescriptor?,
functionDispatchReceiver: Boolean = false,
): ReadWriteProperty<Any?, IrValueParameter?> =
lazyVar {
lazyVar(stubGenerator.lock) {
if (functionDispatchReceiver && stubGenerator.extensions.isStaticFunction(descriptor)) null
else typeTranslator.buildWithScope(this) {
parameter?.generateReceiverParameterStub()?.also { it.parent = this@IrLazyFunctionBase }
@@ -46,7 +46,7 @@ interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer
}
fun createReturnType(): ReadWriteProperty<Any?, IrType> =
lazyVar {
lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
descriptor.returnType!!.toIrType()
}
@@ -50,7 +50,7 @@ class IrLazyProperty(
descriptor.compileTimeInitializer != null || descriptor.getter == null ||
stubGenerator.extensions.isPropertyWithPlatformField(descriptor)
override var backingField: IrField? by lazyVar {
override var backingField: IrField? by lazyVar(stubGenerator.lock) {
if (hasBackingField) {
stubGenerator.generateFieldStub(descriptor).apply {
correspondingPropertySymbol = this@IrLazyProperty.symbol
@@ -58,13 +58,13 @@ class IrLazyProperty(
} else null
}
override var getter: IrSimpleFunction? by lazyVar {
override var getter: IrSimpleFunction? by lazyVar(stubGenerator.lock) {
descriptor.getter?.let { stubGenerator.generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
correspondingPropertySymbol = this@IrLazyProperty.symbol
}
}
override var setter: IrSimpleFunction? by lazyVar {
override var setter: IrSimpleFunction? by lazyVar(stubGenerator.lock) {
descriptor.setter?.let { stubGenerator.generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
correspondingPropertySymbol = this@IrLazyProperty.symbol
}
@@ -37,13 +37,13 @@ class IrLazyTypeAlias(
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
override var typeParameters: List<IrTypeParameter> by lazyVar {
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
descriptor.declaredTypeParameters.mapTo(arrayListOf()) {
stubGenerator.generateOrGetTypeParameterStub(it)
}
}
override var expandedType: IrType by lazyVar {
override var expandedType: IrType by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this) {
descriptor.expandedType.toIrType()
}
@@ -38,7 +38,7 @@ class IrLazyTypeParameter(
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
override var superTypes: List<IrType> by lazyVar {
override var superTypes: List<IrType> by lazyVar(stubGenerator.lock) {
typeTranslator.buildWithScope(this.parent as IrTypeParametersContainer) {
val descriptor = symbol.descriptor
descriptor.upperBounds.mapTo(arrayListOf()) { it.toIrType() }
@@ -5,12 +5,13 @@
package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.ir.IrLock
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> lazyVar(initializer: () -> T): ReadWriteProperty<Any?, T> = SynchronizedLazyVar(initializer)
fun <T> lazyVar(lock: IrLock, initializer: () -> T): ReadWriteProperty<Any?, T> = SynchronizedLazyVar(lock, initializer)
private class SynchronizedLazyVar<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> {
private class SynchronizedLazyVar<T>(val lock: IrLock, initializer: () -> T) : ReadWriteProperty<Any?, T> {
@Volatile
private var isInitialized = false
@@ -23,7 +24,7 @@ private class SynchronizedLazyVar<T>(initializer: () -> T) : ReadWriteProperty<A
get() {
@Suppress("UNCHECKED_CAST")
if (isInitialized) return _value as T
synchronized(this) {
synchronized(lock) {
if (!isInitialized) {
_value = initializer!!()
isInitialized = true
@@ -39,7 +40,7 @@ private class SynchronizedLazyVar<T>(initializer: () -> T) : ReadWriteProperty<A
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
synchronized(this) {
synchronized(lock) {
this._value = value
isInitialized = true
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
@@ -44,6 +45,9 @@ abstract class DeclarationStubGenerator(
) : IrProvider {
protected val lazyTable = symbolTable.lazyWrapper
val lock: IrLock
get() = symbolTable.lock
var unboundSymbolGeneration: Boolean
get() = lazyTable.stubGenerator != null
set(value) {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
@@ -62,13 +63,15 @@ interface ReferenceSymbolTable {
class SymbolTable(
val signaturer: IdSignatureComposer,
val irFactory: IrFactory,
val nameProvider: NameProvider = NameProvider.DEFAULT
val nameProvider: NameProvider = NameProvider.DEFAULT,
) : ReferenceSymbolTable {
val lock = IrLock()
@Suppress("LeakingThis")
val lazyWrapper = IrLazySymbolTable(this)
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>>(val lock: IrLock) {
val unboundSymbols = linkedSetOf<S>()
abstract fun get(d: D): S?
@@ -76,7 +79,7 @@ class SymbolTable(
abstract fun get(sig: IdSignature): S?
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
synchronized(this) {
synchronized(lock) {
@Suppress("UNCHECKED_CAST")
val d0 = d.original as D
assert(d0 === d) {
@@ -97,7 +100,7 @@ class SymbolTable(
@OptIn(ObsoleteDescriptorBasedAPI::class)
inline fun declare(sig: IdSignature, createSymbol: () -> S, createOwner: (S) -> B): B {
synchronized(this) {
synchronized(lock) {
val existing = get(sig)
val symbol = if (existing == null) {
createSymbol()
@@ -113,7 +116,7 @@ class SymbolTable(
}
inline fun declareIfNotExists(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
synchronized(this) {
synchronized(lock) {
@Suppress("UNCHECKED_CAST")
val d0 = d.original as D
assert(d0 === d) {
@@ -133,7 +136,7 @@ class SymbolTable(
}
inline fun declare(sig: IdSignature, d: D?, createSymbol: () -> S, createOwner: (S) -> B): B {
synchronized(this) {
synchronized(lock) {
@Suppress("UNCHECKED_CAST")
val d0 = d?.original as D
assert(d0 === d) {
@@ -153,7 +156,7 @@ class SymbolTable(
}
inline fun referenced(d: D, orElse: () -> S): S {
synchronized(this) {
synchronized(lock) {
@Suppress("UNCHECKED_CAST")
val d0 = d.original as D
assert(d0 === d) {
@@ -174,7 +177,7 @@ class SymbolTable(
@OptIn(ObsoleteDescriptorBasedAPI::class)
inline fun referenced(sig: IdSignature, orElse: () -> S): S {
synchronized(this) {
synchronized(lock) {
return get(sig) ?: run {
val new = orElse()
assert(unboundSymbols.add(new)) {
@@ -188,7 +191,7 @@ class SymbolTable(
}
private open inner class FlatSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> :
SymbolTableBase<D, B, S>() {
SymbolTableBase<D, B, S>(lock) {
val descriptorToSymbol = linkedMapOf<D, S>()
val idSigToSymbol = linkedMapOf<IdSignature, S>()
@@ -225,7 +228,7 @@ class SymbolTable(
}
private inner class ScopedSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>>
: SymbolTableBase<D, B, S>() {
: SymbolTableBase<D, B, S>(lock) {
inner class Scope(val owner: IrSymbol, val parent: Scope?) {
private val descriptorToSymbol = linkedMapOf<D, S>()
private val idSigToSymbol = linkedMapOf<IdSignature, S>()