diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt index bb2a2dd5a74..06b4c7ca488 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt @@ -25,8 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.name.Name -class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns) - class DeclarationIrBuilder( generatorContext: IrGeneratorContext, symbol: IrSymbol, @@ -59,12 +57,19 @@ open class VariableRemapper(val mapping: Map T.at(element: IrElement) = this.at(element.startOffset, element.endOffset) diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt index cf93395ff70..c29a93cd146 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations +import org.jetbrains.kotlin.backend.jvm.lower.SingletonObjectJvmStaticTransformer import org.jetbrains.kotlin.backend.jvm.serialization.deserializeClassFromByteArray import org.jetbrains.kotlin.backend.jvm.serialization.deserializeIrFileFromByteArray +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -24,8 +26,11 @@ import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator +import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor @@ -98,29 +103,47 @@ open class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = tru } } + @Volatile + private var cachedFields: CachedFieldsForObjectInstances? = null + + override fun getCachedFields(irFactory: IrFactory, languageVersionSettings: LanguageVersionSettings): CachedFieldsForObjectInstances { + cachedFields?.let { return it } + synchronized(this) { + cachedFields?.let { return it } + cachedFields = CachedFieldsForObjectInstances(irFactory, languageVersionSettings) + return cachedFields!! + } + } + override fun deserializeLazyClass( irClass: IrLazyClass, - moduleDescriptor: ModuleDescriptor, - irBuiltIns: IrBuiltIns, - symbolTable: SymbolTable, + stubGenerator: DeclarationStubGenerator, parent: IrDeclarationParent, allowErrorNodes: Boolean ): Boolean { val serializedIr = (irClass.source as? KotlinJvmBinarySourceElement)?.binaryClass?.classHeader?.serializedIr ?: return false - deserializeClassFromByteArray(serializedIr, moduleDescriptor, irBuiltIns, symbolTable, parent, allowErrorNodes) + deserializeClassFromByteArray( + serializedIr, stubGenerator.moduleDescriptor, stubGenerator.irBuiltIns, stubGenerator.symbolTable, parent, allowErrorNodes + ) + ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies() + val cachedFields = getCachedFields(stubGenerator.irBuiltIns.irFactory, stubGenerator.irBuiltIns.languageVersionSettings) + irClass.transform(SingletonObjectJvmStaticTransformer(stubGenerator.irBuiltIns, cachedFields), null) return true } override fun deserializeFacadeClass( irClass: IrClass, - moduleDescriptor: ModuleDescriptor, - irBuiltIns: IrBuiltIns, - symbolTable: SymbolTable, + stubGenerator: DeclarationStubGenerator, parent: IrDeclarationParent, allowErrorNodes: Boolean ): Boolean { val serializedIr = (irClass.source as? JvmPackagePartSource)?.knownJvmBinaryClass?.classHeader?.serializedIr ?: return false - deserializeIrFileFromByteArray(serializedIr, moduleDescriptor, irBuiltIns, symbolTable, irClass, allowErrorNodes) + deserializeIrFileFromByteArray( + serializedIr, stubGenerator.moduleDescriptor, stubGenerator.irBuiltIns, stubGenerator.symbolTable, irClass, allowErrorNodes + ) + ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies() + val cachedFields = getCachedFields(stubGenerator.irBuiltIns.irFactory, stubGenerator.irBuiltIns.languageVersionSettings) + irClass.transform(SingletonObjectJvmStaticTransformer(stubGenerator.irBuiltIns, cachedFields), null) return true } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 06f5a4c525a..834d93bf3a9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -67,7 +67,9 @@ class JvmBackendContext( val methodSignatureMapper = MethodSignatureMapper(this) internal val innerClassesSupport = JvmInnerClassesSupport(irFactory) - internal val cachedDeclarations = JvmCachedDeclarations(this, CachedFieldsForObjectInstances(irFactory, state.languageVersionSettings)) + internal val cachedDeclarations = JvmCachedDeclarations( + this, generatorExtensions.getCachedFields(irFactory, state.languageVersionSettings) + ) override val mapping: Mapping = DefaultMapping() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmFileFacadeClass.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmFileFacadeClass.kt index c50efdf37de..b7c6f42f869 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmFileFacadeClass.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmFileFacadeClass.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeserializableClass -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.name.Name class JvmFileFacadeClass( @@ -30,15 +29,7 @@ class JvmFileFacadeClass( override fun loadIr(): Boolean { irLoaded?.let { return it } - irLoaded = stubGenerator.extensions.deserializeFacadeClass( - this, - stubGenerator.moduleDescriptor, - stubGenerator.irBuiltIns, - stubGenerator.symbolTable, - parent, - allowErrorNodes = false - ) - ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies() - return irLoaded as Boolean + irLoaded = stubGenerator.extensions.deserializeFacadeClass(this, stubGenerator, parent, allowErrorNodes = false) + return irLoaded!! } } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt index d3b64525bca..d59897bc4d7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt @@ -5,12 +5,16 @@ package org.jetbrains.kotlin.backend.jvm +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.resolve.jvm.JvmClassName interface JvmGeneratorExtensions { val classNameOverride: MutableMap val rawTypeAnnotationConstructor: IrConstructor? + + fun getCachedFields(irFactory: IrFactory, languageVersionSettings: LanguageVersionSettings): CachedFieldsForObjectInstances } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index 1673ee60d2a..060f98d9a7f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.jvm.ir import org.jetbrains.kotlin.backend.common.ir.ir2string -import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext import org.jetbrains.kotlin.backend.jvm.* import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface @@ -22,6 +21,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.PsiIrFileEntry import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope +import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.declarations.buildProperty import org.jetbrains.kotlin.ir.declarations.* @@ -191,7 +191,7 @@ class JvmIrBuilder( startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET ) : IrBuilderWithScope( - IrLoweringContext(backendContext), + IrGeneratorContextBase(backendContext.irBuiltIns), Scope(symbol), startOffset, endOffset diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt index 545098f1aee..e9135d25f98 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase +import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isEffectivelyInlineOnly @@ -41,7 +42,9 @@ internal val jvmStaticInCompanionPhase = makeIrFilePhase( private class JvmStaticInObjectLowering(val context: JvmBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) = - irFile.transformChildrenVoid(SingletonObjectJvmStaticTransformer(context)) + irFile.transformChildrenVoid( + SingletonObjectJvmStaticTransformer(context.irBuiltIns, context.cachedDeclarations.fieldsForObjectInstances) + ) } private class JvmStaticInCompanionLowering(val context: JvmBackendContext) : FileLoweringPass { @@ -64,7 +67,7 @@ internal fun IrDeclaration.isJvmStaticInObject(): Boolean = private fun IrExpression.coerceToUnit(irBuiltIns: IrBuiltIns) = IrTypeOperatorCallImpl(startOffset, endOffset, irBuiltIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, irBuiltIns.unitType, this) -private fun IrMemberAccessExpression<*>.makeStatic(context: JvmBackendContext, replaceCallee: IrSimpleFunction?) = +private fun IrMemberAccessExpression<*>.makeStatic(irBuiltIns: IrBuiltIns, replaceCallee: IrSimpleFunction?) = dispatchReceiver?.let { receiver -> dispatchReceiver = null val newCall = if (replaceCallee != null) irCall(this@makeStatic as IrCall, replaceCallee) else this@makeStatic @@ -73,13 +76,16 @@ private fun IrMemberAccessExpression<*>.makeStatic(context: JvmBackendContext, r newCall } else { IrBlockImpl(startOffset, endOffset, newCall.type).apply { - statements += receiver.coerceToUnit(context.irBuiltIns) // evaluate for side effects + statements += receiver.coerceToUnit(irBuiltIns) // evaluate for side effects statements += newCall } } } ?: this -private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext) : IrElementTransformerVoid() { +class SingletonObjectJvmStaticTransformer( + private val irBuiltIns: IrBuiltIns, + private val cachedFields: CachedFieldsForObjectInstances +) : IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { if (declaration.isNonCompanionObject) { for (function in declaration.simpleFunctions()) { @@ -87,9 +93,7 @@ private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext // dispatch receiver parameter is already null for synthetic property annotation methods function.dispatchReceiverParameter?.let { oldDispatchReceiverParameter -> function.dispatchReceiverParameter = null - function.replaceThisByStaticReference( - context.cachedDeclarations.fieldsForObjectInstances, declaration, oldDispatchReceiverParameter - ) + function.replaceThisByStaticReference(cachedFields, declaration, oldDispatchReceiverParameter) } } } @@ -102,7 +106,7 @@ private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext expression.transformChildrenVoid(this) val callee = expression.symbol.owner if (callee is IrDeclaration && callee.isJvmStaticInObject()) { - return expression.makeStatic(context, replaceCallee = null) + return expression.makeStatic(irBuiltIns, replaceCallee = null) } return expression } @@ -146,7 +150,7 @@ private class CompanionObjectJvmStaticTransformer(val context: JvmBackendContext return when { shouldReplaceWithStaticCall(callee) -> { val (staticProxy, _) = context.cachedDeclarations.getStaticAndCompanionDeclaration(callee) - expression.makeStatic(context, staticProxy) + expression.makeStatic(context.irBuiltIns, staticProxy) } callee.symbol == context.ir.symbols.indyLambdaMetafactoryIntrinsic -> { val implFunRef = expression.getValueArgument(1) as? IrFunctionReference diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt index 0b64e315f29..902e7429782 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeserializableClass -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.metadata.ProtoBuf diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StubGeneratorExtensions.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StubGeneratorExtensions.kt index f5def8db90f..2d30f49d4fa 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StubGeneratorExtensions.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StubGeneratorExtensions.kt @@ -34,18 +34,14 @@ open class StubGeneratorExtensions { open fun deserializeLazyClass( irClass: IrLazyClass, - moduleDescriptor: ModuleDescriptor, - irBuiltIns: IrBuiltIns, - symbolTable: SymbolTable, + stubGenerator: DeclarationStubGenerator, parent: IrDeclarationParent, allowErrorNodes: Boolean, ): Boolean = false open fun deserializeFacadeClass( irClass: IrClass, - moduleDescriptor: ModuleDescriptor, - irBuiltIns: IrBuiltIns, - symbolTable: SymbolTable, + stubGenerator: DeclarationStubGenerator, parent: IrDeclarationParent, allowErrorNodes: Boolean, ): Boolean = false