[K/N] Merged two module deserializers
This commit is contained in:
+18
@@ -13,6 +13,20 @@ import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||
|
||||
sealed class CacheDeserializationStrategy {
|
||||
abstract fun contains(filePath: String): Boolean
|
||||
|
||||
object Nothing : CacheDeserializationStrategy() {
|
||||
override fun contains(filePath: String) = false
|
||||
}
|
||||
|
||||
object WholeModule : CacheDeserializationStrategy() {
|
||||
override fun contains(filePath: String) = true
|
||||
}
|
||||
}
|
||||
|
||||
class PartialCacheInfo(val klib: KotlinLibrary, val strategy: CacheDeserializationStrategy)
|
||||
|
||||
class CacheSupport(
|
||||
private val configuration: CompilerConfiguration,
|
||||
resolvedLibraries: KotlinLibraryResolveResult,
|
||||
@@ -90,6 +104,10 @@ class CacheSupport(
|
||||
}
|
||||
}
|
||||
|
||||
internal val libraryToCache = librariesToCache.singleOrNull()?.let {
|
||||
PartialCacheInfo(it, CacheDeserializationStrategy.WholeModule)
|
||||
}
|
||||
|
||||
internal val preLinkCaches: Boolean =
|
||||
configuration.get(KonanConfigKeys.PRE_LINK_CACHES, false)
|
||||
|
||||
|
||||
+3
-1
@@ -220,7 +220,6 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
konanKlibDir = File(distribution.klib)
|
||||
)
|
||||
|
||||
|
||||
val fullExportedNamePrefix: String
|
||||
get() = configuration.get(KonanConfigKeys.FULL_EXPORTED_NAME_PREFIX) ?: implicitModuleName
|
||||
|
||||
@@ -398,6 +397,9 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
internal val librariesToCache: Set<KotlinLibrary>
|
||||
get() = cacheSupport.librariesToCache
|
||||
|
||||
internal val libraryToCache: PartialCacheInfo?
|
||||
get() = cacheSupport.libraryToCache
|
||||
|
||||
val outputFiles =
|
||||
OutputFiles(configuration.get(KonanConfigKeys.OUTPUT) ?: cacheSupport.tryGetImplicitOutput(),
|
||||
target, produce)
|
||||
|
||||
+1
@@ -123,6 +123,7 @@ internal fun Context.psiToIr(
|
||||
exportedDependencies = exportedDependencies,
|
||||
cachedLibraries = config.cachedLibraries,
|
||||
lazyIrForCaches = config.lazyIrForCaches,
|
||||
libraryBeingCached = config.libraryToCache,
|
||||
unlinkedDeclarationsSupport = unlinkedDeclarationsSupport,
|
||||
userVisibleIrModulesSupport = config.userVisibleIrModulesSupport
|
||||
).also { linker ->
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ internal val psiToIrPhase = konanUnitPhase(
|
||||
internal val buildAdditionalCacheInfoPhase = konanUnitPhase(
|
||||
op = {
|
||||
irModules.values.single().let { module ->
|
||||
val moduleDeserializer = irLinker.nonCachedLibraryModuleDeserializers[module.descriptor]
|
||||
val moduleDeserializer = irLinker.moduleDeserializers[module.descriptor]
|
||||
if (moduleDeserializer == null) {
|
||||
require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" }
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -473,7 +473,7 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
|
||||
val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration
|
||||
if (moduleDescriptor.isFromInteropLibrary())
|
||||
return emptyList()
|
||||
val moduleDeserializer = context.irLinker.cachedLibraryModuleDeserializers[moduleDescriptor]
|
||||
val moduleDeserializer = context.irLinker.moduleDeserializers[moduleDescriptor]
|
||||
?: error("No module deserializer for ${irClass.render()}")
|
||||
return moduleDeserializer.deserializeClassFields(irClass, outerThisField)
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def
|
||||
} else {
|
||||
// The function is from Lazy IR, get its body from the IR linker.
|
||||
val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration
|
||||
val moduleDeserializer = context.irLinker.cachedLibraryModuleDeserializers[moduleDescriptor]
|
||||
val moduleDeserializer = context.irLinker.moduleDeserializers[moduleDescriptor]
|
||||
?: error("No module deserializer for ${function.render()}")
|
||||
context.specialDeclarationsFactory.loweredInlineFunctions[function] = moduleDeserializer.deserializeInlineFunction(function)
|
||||
function
|
||||
|
||||
+95
-88
@@ -42,6 +42,8 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -322,6 +324,7 @@ internal class KonanIrLinker(
|
||||
exportedDependencies: List<ModuleDescriptor>,
|
||||
private val cachedLibraries: CachedLibraries,
|
||||
private val lazyIrForCaches: Boolean,
|
||||
private val libraryBeingCached: PartialCacheInfo?,
|
||||
override val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport,
|
||||
override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
|
||||
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) {
|
||||
@@ -341,8 +344,7 @@ internal class KonanIrLinker(
|
||||
override val fakeOverrideBuilder: FakeOverrideBuilder =
|
||||
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), friendModules, KonanFakeOverrideClassFilter)
|
||||
|
||||
val nonCachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanModuleDeserializer>()
|
||||
val cachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanCachedLibraryModuleDeserializer>()
|
||||
val moduleDeserializers = mutableMapOf<ModuleDescriptor, KonanPartialModuleDeserializer>()
|
||||
|
||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy) =
|
||||
when {
|
||||
@@ -355,14 +357,14 @@ internal class KonanIrLinker(
|
||||
klib.isInteropLibrary() -> {
|
||||
KonanInteropModuleDeserializer(moduleDescriptor, klib, cachedLibraries.isLibraryCached(klib))
|
||||
}
|
||||
lazyIrForCaches && cachedLibraries.isLibraryCached(klib) -> {
|
||||
KonanCachedLibraryModuleDeserializer(moduleDescriptor, klib).also {
|
||||
cachedLibraryModuleDeserializers[moduleDescriptor] = it
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
KonanModuleDeserializer(moduleDescriptor, klib, strategyResolver).also {
|
||||
nonCachedLibraryModuleDeserializers[moduleDescriptor] = it
|
||||
val deserializationStrategy = when {
|
||||
klib == libraryBeingCached?.klib -> libraryBeingCached.strategy
|
||||
lazyIrForCaches && cachedLibraries.isLibraryCached(klib) -> CacheDeserializationStrategy.Nothing
|
||||
else -> CacheDeserializationStrategy.WholeModule
|
||||
}
|
||||
KonanPartialModuleDeserializer(moduleDescriptor, klib, strategyResolver, deserializationStrategy).also {
|
||||
moduleDeserializers[moduleDescriptor] = it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,12 +403,19 @@ internal class KonanIrLinker(
|
||||
|
||||
private val InvalidIndex = -1
|
||||
|
||||
inner class KonanModuleDeserializer(
|
||||
inner class KonanPartialModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
klib: KotlinLibrary,
|
||||
strategyResolver: (String) -> DeserializationStrategy
|
||||
) : BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||
override val klib: KotlinLibrary,
|
||||
strategyResolver: (String) -> DeserializationStrategy,
|
||||
private val cacheDeserializationStrategy: CacheDeserializationStrategy,
|
||||
containsErrorCode: Boolean = false
|
||||
) : BasicIrModuleDeserializer(this, moduleDescriptor, klib,
|
||||
{ fileName ->
|
||||
if (cacheDeserializationStrategy.contains(fileName))
|
||||
strategyResolver(fileName)
|
||||
else DeserializationStrategy.ON_DEMAND
|
||||
}, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, containsErrorCode) {
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
|
||||
fun buildInlineFunctionReference(irFunction: IrFunction): SerializedInlineFunctionReference {
|
||||
val signature = irFunction.symbol.signature
|
||||
@@ -562,76 +571,6 @@ internal class KonanIrLinker(
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private inner class KonanInteropModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
override val klib: KotlinLibrary,
|
||||
private val isLibraryCached: Boolean
|
||||
) : IrModuleDeserializer(moduleDescriptor, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
|
||||
init {
|
||||
require(klib.isInteropLibrary())
|
||||
}
|
||||
|
||||
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinderImpl(
|
||||
moduleDescriptor, KonanManglerDesc,
|
||||
DescriptorByIdSignatureFinderImpl.LookupMode.MODULE_ONLY
|
||||
)
|
||||
|
||||
private fun IdSignature.isInteropSignature() = IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test()
|
||||
|
||||
override fun contains(idSig: IdSignature): Boolean {
|
||||
if (idSig.isPubliclyVisible) {
|
||||
if (idSig.isInteropSignature()) {
|
||||
// TODO: add descriptor cache??
|
||||
return descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isCEnumsOrCStruct(): Boolean = cenumsProvider.isCEnumOrCStruct(this)
|
||||
|
||||
private val fileMap = mutableMapOf<PackageFragmentDescriptor, IrFile>()
|
||||
|
||||
private fun getIrFile(packageFragment: PackageFragmentDescriptor): IrFile = fileMap.getOrPut(packageFragment) {
|
||||
IrFileImpl(NaiveSourceBasedFileEntryImpl(IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName), packageFragment).also {
|
||||
moduleFragment.files.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveCEnumsOrStruct(descriptor: DeclarationDescriptor, idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||
val file = getIrFile(descriptor.findPackage())
|
||||
return cenumsProvider.getDeclaration(descriptor, idSig, file, symbolKind).symbol
|
||||
}
|
||||
|
||||
override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol? {
|
||||
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null
|
||||
// If library is cached we don't need to create an IrClass for struct or enum.
|
||||
if (!isLibraryCached && descriptor.isCEnumsOrCStruct()) return resolveCEnumsOrStruct(descriptor, idSig, symbolKind)
|
||||
|
||||
val symbolOwner = stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner
|
||||
|
||||
return symbolOwner.symbol
|
||||
}
|
||||
|
||||
override fun deserializedSymbolNotFound(idSig: IdSignature): Nothing = error("No descriptor found for $idSig")
|
||||
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
|
||||
|
||||
override val kind get() = IrModuleDeserializerKind.DESERIALIZED
|
||||
}
|
||||
|
||||
inner class KonanCachedLibraryModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
override val klib: KotlinLibrary
|
||||
) : BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib,
|
||||
{ _ -> DeserializationStrategy.ON_DEMAND },
|
||||
klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT
|
||||
) {
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||
|
||||
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinderImpl(
|
||||
moduleDescriptor, KonanManglerDesc,
|
||||
@@ -655,14 +594,22 @@ internal class KonanIrLinker(
|
||||
}
|
||||
}
|
||||
|
||||
override fun contains(idSig: IdSignature) =
|
||||
deserializedSymbols.containsKey(idSig) ||
|
||||
idSig.isPubliclyVisible && descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||
override fun contains(idSig: IdSignature): Boolean =
|
||||
super.contains(idSig) || deserializedSymbols.containsKey(idSig) ||
|
||||
cacheDeserializationStrategy != CacheDeserializationStrategy.WholeModule
|
||||
&& idSig.isPubliclyVisible && descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||
|
||||
val descriptorSignatures = mutableMapOf<DeclarationDescriptor, IdSignature>()
|
||||
|
||||
override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol? {
|
||||
super.tryDeserializeIrSymbol(idSig, symbolKind)?.let { return it }
|
||||
|
||||
deserializedSymbols[idSig]?.let { return it }
|
||||
|
||||
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null
|
||||
|
||||
descriptorSignatures[descriptor] = idSig
|
||||
|
||||
return (stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner).symbol
|
||||
}
|
||||
|
||||
@@ -687,7 +634,7 @@ internal class KonanIrLinker(
|
||||
)
|
||||
}
|
||||
|
||||
val signature = function.symbol.signature
|
||||
val signature = function.symbol.signature ?: descriptorSignatures[function.descriptor]
|
||||
?: error("No signature for ${function.render()}")
|
||||
val inlineFunctionReference = inlineFunctionReferences[signature]
|
||||
?: error("No inline function reference for ${function.render()}, sig = ${signature.render()}")
|
||||
@@ -819,6 +766,66 @@ internal class KonanIrLinker(
|
||||
}
|
||||
}
|
||||
|
||||
private inner class KonanInteropModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
override val klib: KotlinLibrary,
|
||||
private val isLibraryCached: Boolean
|
||||
) : IrModuleDeserializer(moduleDescriptor, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
|
||||
init {
|
||||
require(klib.isInteropLibrary())
|
||||
}
|
||||
|
||||
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinderImpl(
|
||||
moduleDescriptor, KonanManglerDesc,
|
||||
DescriptorByIdSignatureFinderImpl.LookupMode.MODULE_ONLY
|
||||
)
|
||||
|
||||
private fun IdSignature.isInteropSignature() = IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test()
|
||||
|
||||
override fun contains(idSig: IdSignature): Boolean {
|
||||
if (idSig.isPubliclyVisible) {
|
||||
if (idSig.isInteropSignature()) {
|
||||
// TODO: add descriptor cache??
|
||||
return descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isCEnumsOrCStruct(): Boolean = cenumsProvider.isCEnumOrCStruct(this)
|
||||
|
||||
private val fileMap = mutableMapOf<PackageFragmentDescriptor, IrFile>()
|
||||
|
||||
private fun getIrFile(packageFragment: PackageFragmentDescriptor): IrFile = fileMap.getOrPut(packageFragment) {
|
||||
IrFileImpl(NaiveSourceBasedFileEntryImpl(IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName), packageFragment).also {
|
||||
moduleFragment.files.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveCEnumsOrStruct(descriptor: DeclarationDescriptor, idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||
val file = getIrFile(descriptor.findPackage())
|
||||
return cenumsProvider.getDeclaration(descriptor, idSig, file, symbolKind).symbol
|
||||
}
|
||||
|
||||
override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol? {
|
||||
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null
|
||||
// If library is cached we don't need to create an IrClass for struct or enum.
|
||||
if (!isLibraryCached && descriptor.isCEnumsOrCStruct()) return resolveCEnumsOrStruct(descriptor, idSig, symbolKind)
|
||||
|
||||
val symbolOwner = stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner
|
||||
|
||||
return symbolOwner.symbol
|
||||
}
|
||||
|
||||
override fun deserializedSymbolNotFound(idSig: IdSignature): Nothing = error("No descriptor found for $idSig")
|
||||
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
|
||||
|
||||
override val kind get() = IrModuleDeserializerKind.DESERIALIZED
|
||||
}
|
||||
|
||||
private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) {
|
||||
init {
|
||||
require(moduleDescriptor.isForwardDeclarationModule)
|
||||
|
||||
Reference in New Issue
Block a user