From 78cd45f937a23b482f41262cdb013250fef60b28 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Tue, 7 Sep 2021 13:49:01 +0300 Subject: [PATCH] [KLIB] Resolve deserialization on for each file separately Needs for IC --- .../BasicIrModuleDeserializer.kt | 11 ++++---- .../serialization/IrModuleDeserializer.kt | 6 ++--- .../common/serialization/KotlinIrLinker.kt | 22 +++++++++------- .../ir/backend/js/ic/IcModuleDeserializer.kt | 13 +++++----- .../jetbrains/kotlin/ir/backend/js/klib.kt | 26 ++++++++++--------- .../js/lower/serialization/ir/JsIrLinker.kt | 12 ++++----- .../backend/jvm/serialization/JvmIrLinker.kt | 8 +++--- .../kotlin/ir/AbstractKlibTextTestCase.kt | 2 +- .../konan/serialization/KonanIrlinker.kt | 8 +++--- 9 files changed, 57 insertions(+), 51 deletions(-) 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 0bfe16d230e..60b945d94ee 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 @@ -25,7 +25,7 @@ abstract class BasicIrModuleDeserializer( val linker: KotlinIrLinker, moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, - override val strategy: DeserializationStrategy, + override val strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, private val containsErrorCode: Boolean = false ) : @@ -106,15 +106,16 @@ abstract class BasicIrModuleDeserializer( val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex) val file = fileReader.createFile(moduleFragment, fileProto) + val fileStrategy = strategyResolver(file.fileEntry.name) val fileDeserializationState = FileDeserializationState( linker, file, fileReader, fileProto, - strategy.needBodies, + fileStrategy.needBodies, allowErrorNodes, - strategy.inlineBodies, + fileStrategy.inlineBodies, moduleDeserializer ) @@ -125,10 +126,10 @@ abstract class BasicIrModuleDeserializer( moduleReversedFileIndex.putIfAbsent(it, fileDeserializationState) // TODO Why not simple put? } - if (strategy.theWholeWorld) { + if (fileStrategy.theWholeWorld) { fileDeserializationState.enqueueAllDeclarations() } - if (strategy.theWholeWorld || strategy.explicitlyExported) { + if (fileStrategy.theWholeWorld || fileStrategy.explicitlyExported) { moduleDeserializationState.enqueueFile(fileDeserializationState) } 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 fcbe97e1477..9fadf090693 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 @@ -85,7 +85,7 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor, val abstract val moduleDependencies: Collection - open val strategy: DeserializationStrategy = DeserializationStrategy.ONLY_DECLARATION_HEADERS + open val strategyResolver: (String) -> DeserializationStrategy = { DeserializationStrategy.ONLY_DECLARATION_HEADERS } open val isCurrent = false @@ -215,8 +215,8 @@ class IrModuleDeserializerWithBuiltIns( override val klib: IrLibrary get() = delegate.klib - override val strategy: DeserializationStrategy - get() = delegate.strategy + override val strategyResolver: (String) -> DeserializationStrategy + get() = delegate.strategyResolver override fun addModuleReachableTopLevel(idSig: IdSignature) { delegate.addModuleReachableTopLevel(idSig) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 1760fe8b8aa..c64c0cea293 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -75,7 +75,7 @@ abstract class KotlinIrLinker( protected abstract fun createModuleDeserializer( moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, - strategy: DeserializationStrategy, + strategyResolver: (String) -> DeserializationStrategy, ): IrModuleDeserializer protected abstract fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean @@ -281,7 +281,7 @@ abstract class KotlinIrLinker( fun deserializeIrModuleHeader( moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?, - deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED, + deserializationStrategy: (String) -> DeserializationStrategy = { DeserializationStrategy.ONLY_REFERENCED }, _moduleName: String? = null ): IrModuleFragment { assert(kotlinLibrary != null || _moduleName != null) { "Either library or explicit name have to be provided $moduleDescriptor" } @@ -306,27 +306,29 @@ abstract class KotlinIrLinker( fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?, moduleName: String): IrModuleFragment { // TODO: consider skip deserializing explicitly exported declarations for libraries. // Now it's not valid because of all dependencies that must be computed. - val deserializationStrategy = + val deserializationStrategy: (String) -> DeserializationStrategy = if (exportedDependencies.contains(moduleDescriptor)) { - DeserializationStrategy.ALL + { DeserializationStrategy.ALL } } else { - DeserializationStrategy.EXPLICITLY_EXPORTED + { DeserializationStrategy.EXPLICITLY_EXPORTED } } return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, deserializationStrategy, moduleName) } fun deserializeFullModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary): IrModuleFragment = - deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.ALL) + deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, { DeserializationStrategy.ALL }) fun deserializeOnlyHeaderModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment = - deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.ONLY_DECLARATION_HEADERS) + deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, { DeserializationStrategy.ONLY_DECLARATION_HEADERS }) fun deserializeHeadersWithInlineBodies(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary): IrModuleFragment = - deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.WITH_INLINE_BODIES) + deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, { DeserializationStrategy.WITH_INLINE_BODIES }) - @Suppress("UNUSED_PARAMETER") fun deserializeDirtyFiles(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary, dirtyFiles: Collection): IrModuleFragment { - return deserializeFullModule(moduleDescriptor, kotlinLibrary) + return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, { + if (it in dirtyFiles) DeserializationStrategy.ALL + else DeserializationStrategy.WITH_INLINE_BODIES + }) } } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt index 86fc9e053dd..f467cf44a07 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt @@ -32,7 +32,7 @@ class IcModuleDeserializer( val icData: SerializedIcData, moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, - override val strategy: DeserializationStrategy, + override val strategyResolver: (String) -> DeserializationStrategy, private val containsErrorCode: Boolean = false, ) : IrModuleDeserializer(moduleDescriptor, (klib as KotlinLibrary).versions.abiVersion ?: KotlinAbiVersion.CURRENT) { @@ -129,17 +129,18 @@ class IcModuleDeserializer( val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex) val file = fileReader.createFile(moduleFragment, fileProto) + val fileStrategy = strategyResolver(file.fileEntry.name) - val icFileData = pathToIcFileData[file.path]!! + val icFileData = pathToIcFileData[file.path] ?: error("No IC cache found for file ${file.path}") val icDeserializer = IcFileDeserializer( linker, file, fileReader, fileProto, - strategy.needBodies, + fileStrategy.needBodies, allowErrorNodes, - strategy.inlineBodies, + fileStrategy.inlineBodies, moduleDeserializer, { fileDeserializer -> originalEnqueue(fileDeserializer) }, icFileData, @@ -169,10 +170,10 @@ class IcModuleDeserializer( } } - if (strategy.theWholeWorld) { + if (fileStrategy.theWholeWorld) { icDeserializer.allOriginalDeclarationSignatures().forEach { it.originalEnqueue(icDeserializer) } } - if (strategy.theWholeWorld || strategy.explicitlyExported) { + if (fileStrategy.theWholeWorld || fileStrategy.explicitlyExported) { linker.modulesWithReachableTopLevels.add(this) } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index ed69419b896..1dac0d3674b 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -288,7 +288,7 @@ fun loadIr( irLinker.deserializeIrModuleHeader( depsDescriptors.getModuleDescriptor(klib), klib, - deserializationStrategy = DeserializationStrategy.EXPLICITLY_EXPORTED + deserializationStrategy = { DeserializationStrategy.EXPLICITLY_EXPORTED } ).also { moduleFragment -> klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { moduleFragmentToUniqueName[moduleFragment] = it @@ -359,19 +359,21 @@ fun loadIr( it.library.libraryFile.canonicalPath == mainPath } - val deserializedModuleFragments = sortDependencies(reachableDependencies.getFullResolvedList(), depsDescriptors.descriptors).map { klib -> - val strategy = - if (klib == mainModuleLib) - DeserializationStrategy.ALL - else - DeserializationStrategy.EXPLICITLY_EXPORTED + val deserializedModuleFragments = + sortDependencies(reachableDependencies.getFullResolvedList(), depsDescriptors.descriptors).map { klib -> + val strategy = + if (klib == mainModuleLib) + DeserializationStrategy.ALL + else + DeserializationStrategy.EXPLICITLY_EXPORTED - irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib, strategy).also { moduleFragment -> - klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { - moduleFragmentToUniqueName[moduleFragment] = it - } + irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib, { strategy }) + .also { moduleFragment -> + klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { + moduleFragmentToUniqueName[moduleFragment] = it + } + } } - } val moduleFragment = deserializedModuleFragments.last() 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 703629eb2cd..2ee7db83412 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 @@ -40,7 +40,7 @@ class JsIrLinker( private val IrLibrary.libContainsErrorCode: Boolean get() = this is KotlinLibrary && this.containsErrorCode - override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer { require(klib != null) { "Expecting kotlin library" } loweredIcData[moduleDescriptor]?.let { loweredIcData -> return IcModuleDeserializer( @@ -50,17 +50,17 @@ class JsIrLinker( loweredIcData, moduleDescriptor, klib, - strategy, + strategyResolver, containsErrorCode = klib.libContainsErrorCode, ) } - return JsModuleDeserializer(moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, klib.libContainsErrorCode) + return JsModuleDeserializer(moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, klib.libContainsErrorCode) } val mapping: JsMapping by lazy { JsMapping(symbolTable.irFactory) } - private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion, allowErrorCode) + private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : + BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode) override fun maybeWrapWithBuiltInAndInit( moduleDescriptor: ModuleDescriptor, @@ -75,7 +75,7 @@ class JsIrLinker( val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) icData?.let { return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> - JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy, KotlinAbiVersion.CURRENT, it.containsErrorCode) + JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategyResolver, KotlinAbiVersion.CURRENT, it.containsErrorCode) } } return currentModuleDeserializer 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 8b1d3263aea..184bca30302 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 @@ -49,17 +49,17 @@ class JvmIrLinker( moduleDescriptor.name.asString().startsWith(" DeserializationStrategy): IrModuleDeserializer { if (klib != null) { assert(moduleDescriptor.getCapability(KlibModuleOrigin.CAPABILITY) != null) - return JvmModuleDeserializer(moduleDescriptor, klib, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, strategy) + return JvmModuleDeserializer(moduleDescriptor, klib, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, strategyResolver) } return MetadataJVMModuleDeserializer(moduleDescriptor, emptyList()) } - private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategy: DeserializationStrategy) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion) + private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategyResolver: (String) -> DeserializationStrategy) : + BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion) private fun DeclarationDescriptor.isJavaDescriptor(): Boolean { if (this is PackageFragmentDescriptor) { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt index c12c392413a..8afebd26f53 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt @@ -218,7 +218,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { val irBuiltIns = IrBuiltInsOverDescriptors(testDescriptor.builtIns, typeTranslator, symbolTable) val irLinker = JsIrLinker(null, IrMessageLogger.None, irBuiltIns, symbolTable, null, null) irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib) - val testModule = irLinker.deserializeIrModuleHeader(testDescriptor, klib, DeserializationStrategy.ALL) + val testModule = irLinker.deserializeIrModuleHeader(testDescriptor, klib, { DeserializationStrategy.ALL }) irLinker.init(null, emptyList()) ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() irLinker.postProcess() diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index 9d6fa239641..f8663482540 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -92,7 +92,7 @@ internal class KonanIrLinker( override val fakeOverrideBuilder: FakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter) - override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer { if (moduleDescriptor === forwardModuleDescriptor) { return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected") } @@ -104,14 +104,14 @@ internal class KonanIrLinker( return KonanInteropModuleDeserializer(moduleDescriptor, klib, isCached) } - return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) + return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategyResolver) } private inner class KonanModuleDeserializer( moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary, - strategy: DeserializationStrategy - ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) { + strategyResolver: (String) -> DeserializationStrategy + ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) { override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) }