IR Deserialization: Avoid usage of IrLibrary in module deserializers With this commit the usage of `IrLibrary` is reduced in the hierarchy of `IrModuleDeserializer`: - The type of `val klib: IrLibrary` is changed to `KotlinLibrary`. - `val klib: KotlinLibrary` is made abstract. Each concrete implementation of the module deserializer may implement it in the most suitable way. Some, as `KonanPartialModuleDeserializer`, may keep the instance of `KotlinLibrary` immediately inside the deserializer. While others, as `JsModuleDeserializer`, may not store an instance of `KotlinLibrary` and just implement `val klib` in a way that it will throw an error on access. - `BasicIrModuleDeserializer` gets a new `open val ir: IrDirectory`. By default, the value of this property is obtained as `klib.mainIr`. But some specific deserializers, as `JsModuleDeserializer`, may implement `val ir: IrDirectory` in their specific way even without storing an instance of `KotlinLibrary`. ^KT-81411
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt index 77e21cf..1a6e304 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt
@@ -30,7 +30,6 @@ abstract class BasicIrModuleDeserializer( val linker: KotlinIrLinker, moduleDescriptor: ModuleDescriptor, - override val klib: IrLibrary, override val strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, private val allowErrorNodes: Boolean = false, @@ -44,6 +43,8 @@ protected val moduleReversedFileIndex = hashMapOf<IdSignature, FileDeserializationState>() + protected open val ir: IrLibrary.IrDirectory get() = klib.mainIr + override val moduleDependencies by lazy { moduleDescriptor.allDependencyModules .filter { it != moduleDescriptor } @@ -55,13 +56,12 @@ } override fun init(delegate: IrModuleDeserializer) { - val mainIr = klib.mainIr - val fileCount = mainIr.fileCount() + val fileCount = ir.fileCount() fileDeserializationStates = buildList { for (i in 0 until fileCount) { - val fileStream = mainIr.file(i).codedInputStream + val fileStream = ir.file(i).codedInputStream val fileProto = ProtoFile.parseFrom(fileStream, ExtensionRegistryLite.newInstance()) - val fileReader = IrLibraryFileFromBytes(IrKlibBytesSource(mainIr, i)) + val fileReader = IrLibraryFileFromBytes(IrKlibBytesSource(ir, i)) val file = fileReader.createFile(moduleFragment, fileProto, linker.irInterner) this += deserializeIrFile(fileProto, file, fileReader, i, delegate, allowErrorNodes)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt index ae29152..1d55719 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt
@@ -20,13 +20,13 @@ import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinAbiVersion +import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.impl.* -import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled class ICData(val icData: List<SerializedIrFile>) -class ICKotlinLibrary(private val icData: List<SerializedIrFile>) : IrLibrary { +class ICKotlinLibrary(private val icData: List<SerializedIrFile>) : IrLibrary.IrDirectory { private inline fun Array<DeclarationIdTableReader?>.itemBytes(fileIndex: Int, key: DeclarationId, factory: () -> DeclarationIdTableReader): ByteArray { val reader = this[fileIndex] ?: factory().also { this[fileIndex] = it } @@ -53,79 +53,56 @@ private val indexedBodies = arrayOfNulls<IrArrayReader>(icData.size) private val indexedFileEntries = arrayOfNulls<IrArrayReader>(icData.size) - override val hasMainIr get() = true - override val mainIr: IrLibrary.IrDirectory = object : IrLibrary.IrDirectory { - override fun irDeclaration(index: Int, fileIndex: Int): ByteArray = - indexedDeclarations.itemBytes(fileIndex, DeclarationId(index)) { - DeclarationIdTableReader(icData[fileIndex].declarations) - } + override fun irDeclaration(index: Int, fileIndex: Int): ByteArray = + indexedDeclarations.itemBytes(fileIndex, DeclarationId(index)) { + DeclarationIdTableReader(icData[fileIndex].declarations) + } - override fun type(index: Int, fileIndex: Int): ByteArray = - indexedTypes.itemBytes(fileIndex, index) { - IrArrayReader(icData[fileIndex].types) - } + override fun type(index: Int, fileIndex: Int): ByteArray = + indexedTypes.itemBytes(fileIndex, index) { + IrArrayReader(icData[fileIndex].types) + } - override fun signature(index: Int, fileIndex: Int): ByteArray = - indexedSignatures.itemBytes(fileIndex, index) { - IrArrayReader(icData[fileIndex].signatures) - } + override fun signature(index: Int, fileIndex: Int): ByteArray = + indexedSignatures.itemBytes(fileIndex, index) { + IrArrayReader(icData[fileIndex].signatures) + } - override fun string(index: Int, fileIndex: Int): ByteArray = - indexedStrings.itemBytes(fileIndex, index) { - IrArrayReader(icData[fileIndex].strings) - } + override fun string(index: Int, fileIndex: Int): ByteArray = + indexedStrings.itemBytes(fileIndex, index) { + IrArrayReader(icData[fileIndex].strings) + } - override fun body(index: Int, fileIndex: Int): ByteArray = - indexedBodies.itemBytes(fileIndex, index) { - IrArrayReader(icData[fileIndex].bodies) - } + override fun body(index: Int, fileIndex: Int): ByteArray = + indexedBodies.itemBytes(fileIndex, index) { + IrArrayReader(icData[fileIndex].bodies) + } - override fun debugInfo(index: Int, fileIndex: Int): ByteArray? = - indexedDebugInfos.itemNullableBytes(fileIndex, index) { - icData[fileIndex].debugInfo?.let { IrArrayReader(it) } - } + override fun debugInfo(index: Int, fileIndex: Int): ByteArray? = + indexedDebugInfos.itemNullableBytes(fileIndex, index) { + icData[fileIndex].debugInfo?.let { IrArrayReader(it) } + } - override fun fileEntry(index: Int, fileIndex: Int): ByteArray? = - indexedFileEntries.itemNullableBytes(fileIndex, index) { - icData[fileIndex].fileEntries?.let { IrArrayReader(it) } - } + override fun fileEntry(index: Int, fileIndex: Int): ByteArray? = + indexedFileEntries.itemNullableBytes(fileIndex, index) { + icData[fileIndex].fileEntries?.let { IrArrayReader(it) } + } - override fun file(index: Int): ByteArray = icData[index].fileData + override fun file(index: Int): ByteArray = icData[index].fileData - override fun fileCount(): Int = icData.size + override fun fileCount(): Int = icData.size - override fun types(fileIndex: Int): ByteArray = icData[fileIndex].types + override fun types(fileIndex: Int): ByteArray = icData[fileIndex].types - override fun signatures(fileIndex: Int): ByteArray = icData[fileIndex].signatures + override fun signatures(fileIndex: Int): ByteArray = icData[fileIndex].signatures - override fun strings(fileIndex: Int): ByteArray = icData[fileIndex].strings + override fun strings(fileIndex: Int): ByteArray = icData[fileIndex].strings - override fun declarations(fileIndex: Int): ByteArray = icData[fileIndex].declarations + override fun declarations(fileIndex: Int): ByteArray = icData[fileIndex].declarations - override fun bodies(fileIndex: Int): ByteArray = icData[fileIndex].bodies + override fun bodies(fileIndex: Int): ByteArray = icData[fileIndex].bodies - override fun fileEntries(fileIndex: Int): ByteArray? = icData[fileIndex].fileEntries - } - - // This class is not used by the K2 compiler, so the first stage inlining feature is not supported. - override val hasInlinableFunsIr: Boolean get() = false - override val inlinableFunsIr = object : IrLibrary.IrDirectory { - override fun irDeclaration(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun type(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun signature(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun string(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun body(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun debugInfo(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun fileEntry(index: Int, fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun file(index: Int): ByteArray = shouldNotBeCalled() - override fun fileCount(): Int = shouldNotBeCalled() - override fun types(fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun signatures(fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun strings(fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun declarations(fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun bodies(fileIndex: Int): ByteArray = shouldNotBeCalled() - override fun fileEntries(fileIndex: Int): ByteArray? = shouldNotBeCalled() - } + override fun fileEntries(fileIndex: Int): ByteArray? = icData[fileIndex].fileEntries } class CurrentModuleWithICDeserializer( @@ -133,7 +110,7 @@ private val symbolTable: SymbolTable, private val irBuiltIns: IrBuiltIns, icData: List<SerializedIrFile>, - icReaderFactory: (IrLibrary) -> IrModuleDeserializer) : + icReaderFactory: (IrLibrary.IrDirectory) -> IrModuleDeserializer) : IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) { private val dirtyDeclarations = hashMapOf<IdSignature, IrSymbol>() @@ -191,7 +168,7 @@ override fun toString(): String = "Incremental Cache Klib" - override val klib: IrLibrary + override val klib: KotlinLibrary get() = icDeserializer.klib override val moduleFragment: IrModuleFragment
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt index 85cb8a0..5426a9a 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibraryProperResolverWithAttributes @@ -79,7 +78,7 @@ deserializeIrSymbolOrFail(signature, symbol.kind()) } - open val klib: IrLibrary get() = error("Unsupported operation") + abstract val klib: KotlinLibrary open fun init() = init(this) @@ -226,7 +225,7 @@ delegate.init(this) } - override val klib: IrLibrary + override val klib: KotlinLibrary get() = delegate.klib override val strategyResolver: (String) -> DeserializationStrategy @@ -257,6 +256,8 @@ override val moduleFragment: IrModuleFragment, override val moduleDependencies: Collection<IrModuleDeserializer> ) : IrModuleDeserializer(moduleFragment.descriptor, KotlinAbiVersion.CURRENT) { + override val klib get() = error("'klib' is not available for ${this::class.java}") + override fun contains(idSig: IdSignature): Boolean = false // TODO: override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): Nothing =
diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 08847a6..83f0516 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt
@@ -64,15 +64,21 @@ require(klib != null) { "Expecting kotlin library" } val libraryAbiVersion = klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT return when (val lazyIrGenerator = stubGenerator) { - null -> JsModuleDeserializer(moduleDescriptor, klib, strategyResolver, libraryAbiVersion) + null -> JsModuleDeserializer(moduleDescriptor, klib.mainIr, strategyResolver, libraryAbiVersion) else -> JsLazyIrModuleDeserializer(moduleDescriptor, libraryAbiVersion, builtIns, lazyIrGenerator) } } private val deserializedFilesInKlibOrder = mutableMapOf<IrModuleFragment, List<IrFile>>() - private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion) { + private inner class JsModuleDeserializer( + moduleDescriptor: ModuleDescriptor, + override val ir: IrLibrary.IrDirectory, + strategyResolver: (String) -> DeserializationStrategy, + libraryAbiVersion: KotlinAbiVersion, + ) : BasicIrModuleDeserializer(this, moduleDescriptor, strategyResolver, libraryAbiVersion) { + + override val klib get() = error("'klib' is not available for ${this::class.java}") override fun init(delegate: IrModuleDeserializer) { super.init(delegate) @@ -84,8 +90,8 @@ val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) icData?.let { - return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> - JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategyResolver, KotlinAbiVersion.CURRENT) + return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { ir -> + JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, ir, currentModuleDeserializer.strategyResolver, KotlinAbiVersion.CURRENT) } } return currentModuleDeserializer
diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsLazyIrModuleDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsLazyIrModuleDeserializer.kt index 3d08d5f..d0af06f 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsLazyIrModuleDeserializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsLazyIrModuleDeserializer.kt
@@ -30,6 +30,8 @@ ) : IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) { private val dependencies = emptyList<IrModuleDeserializer>() + override val klib get() = error("'klib' is not available for ${this::class.java}") + // TODO: implement proper check whether `idSig` belongs to this module override fun contains(idSig: IdSignature): Boolean = true
diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index 008ef3f..e451bd7 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.KlibModuleOrigin @@ -66,8 +65,12 @@ return MetadataJVMModuleDeserializer(moduleDescriptor, emptyList()) } - private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategyResolver: (String) -> DeserializationStrategy) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion) + private inner class JvmModuleDeserializer( + moduleDescriptor: ModuleDescriptor, + override val klib: KotlinLibrary, + libraryAbiVersion: KotlinAbiVersion, + strategyResolver: (String) -> DeserializationStrategy, + ) : BasicIrModuleDeserializer(this, moduleDescriptor, strategyResolver, libraryAbiVersion) private fun DeclarationDescriptor.isJavaDescriptor(): Boolean { if (this is PackageFragmentDescriptor) { @@ -106,6 +109,7 @@ private inner class JvmCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>) : CurrentModuleDeserializer(moduleFragment, dependencies) { + override fun declareIrSymbol(symbol: IrSymbol) { val descriptor = symbol.descriptor @@ -131,6 +135,8 @@ private inner class MetadataJVMModuleDeserializer(moduleDescriptor: ModuleDescriptor, dependencies: List<IrModuleDeserializer>) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) { + override val klib get() = error("'klib' is not available for ${this::class.java}") + // TODO: implement proper check whether `idSig` belongs to this module override fun contains(idSig: IdSignature): Boolean = true
diff --git a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanForwardDeclarationModuleDeserializer.kt b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanForwardDeclarationModuleDeserializer.kt index 63d361f..ce2de60 100644 --- a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanForwardDeclarationModuleDeserializer.kt +++ b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanForwardDeclarationModuleDeserializer.kt
@@ -31,6 +31,9 @@ private val linker: KotlinIrLinker, private val stubGenerator: DeclarationStubGenerator, ) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.Companion.CURRENT) { + + override val klib get() = error("'klib' is not available for ${this::class.java}") + init { require(moduleDescriptor.isForwardDeclarationModule) }
diff --git a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt index 0b9b9df..e915ca4 100644 --- a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt +++ b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt
@@ -105,7 +105,7 @@ deserializersForModules .filter { !it.key.isForwardDeclarationModuleName && it.value.moduleDescriptor !== currentModule } .forEach { - val klib = it.value.klib as? KotlinLibrary ?: error("Expected to be KotlinLibrary (${it.key})") + val klib = it.value.klib this[klib.libraryName] = it.value.moduleFragment } }
diff --git a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt index 7ffa5e4..373170c 100644 --- a/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt +++ b/compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt
@@ -27,7 +27,6 @@ ) : BasicIrModuleDeserializer( linker = kotlinIrLinker, moduleDescriptor = moduleDescriptor, - klib = klib, strategyResolver = { fileName -> if (cacheDeserializationStrategy.contains(fileName)) strategyResolver(fileName) else DeserializationStrategy.ON_DEMAND }, libraryAbiVersion = klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, ) {
diff --git a/kotlin-native/klib/src/org/jetbrains/kotlin/cli/klib/KlibToolIrLinker.kt b/kotlin-native/klib/src/org/jetbrains/kotlin/cli/klib/KlibToolIrLinker.kt index c7d5dd8..c45a2f72 100644 --- a/kotlin-native/klib/src/org/jetbrains/kotlin/cli/klib/KlibToolIrLinker.kt +++ b/kotlin-native/klib/src/org/jetbrains/kotlin/cli/klib/KlibToolIrLinker.kt
@@ -50,12 +50,11 @@ private inner class KlibToolModuleDeserializer( module: ModuleDescriptor, - klib: KotlinLibrary, + override val klib: KotlinLibrary, strategyResolver: (String) -> DeserializationStrategy, ) : BasicIrModuleDeserializer( linker = this, moduleDescriptor = module, - klib = klib, strategyResolver = strategyResolver, libraryAbiVersion = klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, allowErrorNodes = true,