IR: introduce IrLock
Use a single lock object for synchronization to avoid deadlocks.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
+30
-28
@@ -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(
|
||||
|
||||
+1
-1
@@ -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()) {
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
+3
-3
@@ -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
|
||||
}
|
||||
|
||||
+2
-2
@@ -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()
|
||||
}
|
||||
|
||||
+1
-1
@@ -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>()
|
||||
|
||||
Reference in New Issue
Block a user