[KLIB] Resolve deserialization on for each file separately

Needs for IC
This commit is contained in:
Roman Artemev
2021-09-07 13:49:01 +03:00
committed by TeamCityServer
parent 28ffcf1e81
commit 78cd45f937
9 changed files with 57 additions and 51 deletions
@@ -25,7 +25,7 @@ abstract class BasicIrModuleDeserializer(
val linker: KotlinIrLinker, val linker: KotlinIrLinker,
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
override val klib: IrLibrary, override val klib: IrLibrary,
override val strategy: DeserializationStrategy, override val strategyResolver: (String) -> DeserializationStrategy,
libraryAbiVersion: KotlinAbiVersion, libraryAbiVersion: KotlinAbiVersion,
private val containsErrorCode: Boolean = false private val containsErrorCode: Boolean = false
) : ) :
@@ -106,15 +106,16 @@ abstract class BasicIrModuleDeserializer(
val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex) val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex)
val file = fileReader.createFile(moduleFragment, fileProto) val file = fileReader.createFile(moduleFragment, fileProto)
val fileStrategy = strategyResolver(file.fileEntry.name)
val fileDeserializationState = FileDeserializationState( val fileDeserializationState = FileDeserializationState(
linker, linker,
file, file,
fileReader, fileReader,
fileProto, fileProto,
strategy.needBodies, fileStrategy.needBodies,
allowErrorNodes, allowErrorNodes,
strategy.inlineBodies, fileStrategy.inlineBodies,
moduleDeserializer moduleDeserializer
) )
@@ -125,10 +126,10 @@ abstract class BasicIrModuleDeserializer(
moduleReversedFileIndex.putIfAbsent(it, fileDeserializationState) // TODO Why not simple put? moduleReversedFileIndex.putIfAbsent(it, fileDeserializationState) // TODO Why not simple put?
} }
if (strategy.theWholeWorld) { if (fileStrategy.theWholeWorld) {
fileDeserializationState.enqueueAllDeclarations() fileDeserializationState.enqueueAllDeclarations()
} }
if (strategy.theWholeWorld || strategy.explicitlyExported) { if (fileStrategy.theWholeWorld || fileStrategy.explicitlyExported) {
moduleDeserializationState.enqueueFile(fileDeserializationState) moduleDeserializationState.enqueueFile(fileDeserializationState)
} }
@@ -85,7 +85,7 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor, val
abstract val moduleDependencies: Collection<IrModuleDeserializer> abstract val moduleDependencies: Collection<IrModuleDeserializer>
open val strategy: DeserializationStrategy = DeserializationStrategy.ONLY_DECLARATION_HEADERS open val strategyResolver: (String) -> DeserializationStrategy = { DeserializationStrategy.ONLY_DECLARATION_HEADERS }
open val isCurrent = false open val isCurrent = false
@@ -215,8 +215,8 @@ class IrModuleDeserializerWithBuiltIns(
override val klib: IrLibrary override val klib: IrLibrary
get() = delegate.klib get() = delegate.klib
override val strategy: DeserializationStrategy override val strategyResolver: (String) -> DeserializationStrategy
get() = delegate.strategy get() = delegate.strategyResolver
override fun addModuleReachableTopLevel(idSig: IdSignature) { override fun addModuleReachableTopLevel(idSig: IdSignature) {
delegate.addModuleReachableTopLevel(idSig) delegate.addModuleReachableTopLevel(idSig)
@@ -75,7 +75,7 @@ abstract class KotlinIrLinker(
protected abstract fun createModuleDeserializer( protected abstract fun createModuleDeserializer(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
klib: KotlinLibrary?, klib: KotlinLibrary?,
strategy: DeserializationStrategy, strategyResolver: (String) -> DeserializationStrategy,
): IrModuleDeserializer ): IrModuleDeserializer
protected abstract fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean protected abstract fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean
@@ -281,7 +281,7 @@ abstract class KotlinIrLinker(
fun deserializeIrModuleHeader( fun deserializeIrModuleHeader(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
kotlinLibrary: KotlinLibrary?, kotlinLibrary: KotlinLibrary?,
deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED, deserializationStrategy: (String) -> DeserializationStrategy = { DeserializationStrategy.ONLY_REFERENCED },
_moduleName: String? = null _moduleName: String? = null
): IrModuleFragment { ): IrModuleFragment {
assert(kotlinLibrary != null || _moduleName != null) { "Either library or explicit name have to be provided $moduleDescriptor" } 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 { fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?, moduleName: String): IrModuleFragment {
// TODO: consider skip deserializing explicitly exported declarations for libraries. // TODO: consider skip deserializing explicitly exported declarations for libraries.
// Now it's not valid because of all dependencies that must be computed. // Now it's not valid because of all dependencies that must be computed.
val deserializationStrategy = val deserializationStrategy: (String) -> DeserializationStrategy =
if (exportedDependencies.contains(moduleDescriptor)) { if (exportedDependencies.contains(moduleDescriptor)) {
DeserializationStrategy.ALL { DeserializationStrategy.ALL }
} else { } else {
DeserializationStrategy.EXPLICITLY_EXPORTED { DeserializationStrategy.EXPLICITLY_EXPORTED }
} }
return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, deserializationStrategy, moduleName) return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, deserializationStrategy, moduleName)
} }
fun deserializeFullModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary): IrModuleFragment = fun deserializeFullModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary): IrModuleFragment =
deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.ALL) deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, { DeserializationStrategy.ALL })
fun deserializeOnlyHeaderModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment = 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 = 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<String>): IrModuleFragment { fun deserializeDirtyFiles(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary, dirtyFiles: Collection<String>): IrModuleFragment {
return deserializeFullModule(moduleDescriptor, kotlinLibrary) return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, {
if (it in dirtyFiles) DeserializationStrategy.ALL
else DeserializationStrategy.WITH_INLINE_BODIES
})
} }
} }
@@ -32,7 +32,7 @@ class IcModuleDeserializer(
val icData: SerializedIcData, val icData: SerializedIcData,
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
override val klib: IrLibrary, override val klib: IrLibrary,
override val strategy: DeserializationStrategy, override val strategyResolver: (String) -> DeserializationStrategy,
private val containsErrorCode: Boolean = false, private val containsErrorCode: Boolean = false,
) : IrModuleDeserializer(moduleDescriptor, (klib as KotlinLibrary).versions.abiVersion ?: KotlinAbiVersion.CURRENT) { ) : IrModuleDeserializer(moduleDescriptor, (klib as KotlinLibrary).versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
@@ -129,17 +129,18 @@ class IcModuleDeserializer(
val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex) val fileReader = IrLibraryFileFromKlib(moduleDeserializer.klib, fileIndex)
val file = fileReader.createFile(moduleFragment, fileProto) 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( val icDeserializer = IcFileDeserializer(
linker, linker,
file, file,
fileReader, fileReader,
fileProto, fileProto,
strategy.needBodies, fileStrategy.needBodies,
allowErrorNodes, allowErrorNodes,
strategy.inlineBodies, fileStrategy.inlineBodies,
moduleDeserializer, moduleDeserializer,
{ fileDeserializer -> originalEnqueue(fileDeserializer) }, { fileDeserializer -> originalEnqueue(fileDeserializer) },
icFileData, icFileData,
@@ -169,10 +170,10 @@ class IcModuleDeserializer(
} }
} }
if (strategy.theWholeWorld) { if (fileStrategy.theWholeWorld) {
icDeserializer.allOriginalDeclarationSignatures().forEach { it.originalEnqueue(icDeserializer) } icDeserializer.allOriginalDeclarationSignatures().forEach { it.originalEnqueue(icDeserializer) }
} }
if (strategy.theWholeWorld || strategy.explicitlyExported) { if (fileStrategy.theWholeWorld || fileStrategy.explicitlyExported) {
linker.modulesWithReachableTopLevels.add(this) linker.modulesWithReachableTopLevels.add(this)
} }
@@ -288,7 +288,7 @@ fun loadIr(
irLinker.deserializeIrModuleHeader( irLinker.deserializeIrModuleHeader(
depsDescriptors.getModuleDescriptor(klib), depsDescriptors.getModuleDescriptor(klib),
klib, klib,
deserializationStrategy = DeserializationStrategy.EXPLICITLY_EXPORTED deserializationStrategy = { DeserializationStrategy.EXPLICITLY_EXPORTED }
).also { moduleFragment -> ).also { moduleFragment ->
klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let {
moduleFragmentToUniqueName[moduleFragment] = it moduleFragmentToUniqueName[moduleFragment] = it
@@ -359,19 +359,21 @@ fun loadIr(
it.library.libraryFile.canonicalPath == mainPath it.library.libraryFile.canonicalPath == mainPath
} }
val deserializedModuleFragments = sortDependencies(reachableDependencies.getFullResolvedList(), depsDescriptors.descriptors).map { klib -> val deserializedModuleFragments =
val strategy = sortDependencies(reachableDependencies.getFullResolvedList(), depsDescriptors.descriptors).map { klib ->
if (klib == mainModuleLib) val strategy =
DeserializationStrategy.ALL if (klib == mainModuleLib)
else DeserializationStrategy.ALL
DeserializationStrategy.EXPLICITLY_EXPORTED else
DeserializationStrategy.EXPLICITLY_EXPORTED
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib, strategy).also { moduleFragment -> irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib, { strategy })
klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { .also { moduleFragment ->
moduleFragmentToUniqueName[moduleFragment] = it klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let {
} moduleFragmentToUniqueName[moduleFragment] = it
}
}
} }
}
val moduleFragment = deserializedModuleFragments.last() val moduleFragment = deserializedModuleFragments.last()
@@ -40,7 +40,7 @@ class JsIrLinker(
private val IrLibrary.libContainsErrorCode: Boolean private val IrLibrary.libContainsErrorCode: Boolean
get() = this is KotlinLibrary && this.containsErrorCode 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" } require(klib != null) { "Expecting kotlin library" }
loweredIcData[moduleDescriptor]?.let { loweredIcData -> loweredIcData[moduleDescriptor]?.let { loweredIcData ->
return IcModuleDeserializer( return IcModuleDeserializer(
@@ -50,17 +50,17 @@ class JsIrLinker(
loweredIcData, loweredIcData,
moduleDescriptor, moduleDescriptor,
klib, klib,
strategy, strategyResolver,
containsErrorCode = klib.libContainsErrorCode, 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) } val mapping: JsMapping by lazy { JsMapping(symbolTable.irFactory) }
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion, allowErrorCode) BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode)
override fun maybeWrapWithBuiltInAndInit( override fun maybeWrapWithBuiltInAndInit(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
@@ -75,7 +75,7 @@ class JsIrLinker(
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies)
icData?.let { icData?.let {
return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> 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 return currentModuleDeserializer
@@ -49,17 +49,17 @@ class JvmIrLinker(
moduleDescriptor.name.asString().startsWith("<dependencies of ") moduleDescriptor.name.asString().startsWith("<dependencies of ")
// TODO: implement special Java deserializer // TODO: implement special Java deserializer
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer {
if (klib != null) { if (klib != null) {
assert(moduleDescriptor.getCapability(KlibModuleOrigin.CAPABILITY) != 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()) return MetadataJVMModuleDeserializer(moduleDescriptor, emptyList())
} }
private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategy: DeserializationStrategy) : private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategyResolver: (String) -> DeserializationStrategy) :
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion) BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion)
private fun DeclarationDescriptor.isJavaDescriptor(): Boolean { private fun DeclarationDescriptor.isJavaDescriptor(): Boolean {
if (this is PackageFragmentDescriptor) { if (this is PackageFragmentDescriptor) {
@@ -218,7 +218,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
val irBuiltIns = IrBuiltInsOverDescriptors(testDescriptor.builtIns, typeTranslator, symbolTable) val irBuiltIns = IrBuiltInsOverDescriptors(testDescriptor.builtIns, typeTranslator, symbolTable)
val irLinker = JsIrLinker(null, IrMessageLogger.None, irBuiltIns, symbolTable, null, null) val irLinker = JsIrLinker(null, IrMessageLogger.None, irBuiltIns, symbolTable, null, null)
irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib) irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib)
val testModule = irLinker.deserializeIrModuleHeader(testDescriptor, klib, DeserializationStrategy.ALL) val testModule = irLinker.deserializeIrModuleHeader(testDescriptor, klib, { DeserializationStrategy.ALL })
irLinker.init(null, emptyList()) irLinker.init(null, emptyList())
ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
irLinker.postProcess() irLinker.postProcess()
@@ -92,7 +92,7 @@ internal class KonanIrLinker(
override val fakeOverrideBuilder: FakeOverrideBuilder = override val fakeOverrideBuilder: FakeOverrideBuilder =
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter) 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) { if (moduleDescriptor === forwardModuleDescriptor) {
return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected") return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected")
} }
@@ -104,14 +104,14 @@ internal class KonanIrLinker(
return KonanInteropModuleDeserializer(moduleDescriptor, klib, isCached) 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( private inner class KonanModuleDeserializer(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
klib: KotlinLibrary, klib: KotlinLibrary,
strategy: DeserializationStrategy strategyResolver: (String) -> DeserializationStrategy
): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) { ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
} }