[Interop][Metadata] Emit chunked metadata

This commit is contained in:
Sergey Bogolepov
2019-12-04 12:44:25 +07:00
committed by Sergey Bogolepov
parent 919db81fba
commit e187a4b40b
@@ -4,7 +4,11 @@
*/ */
package org.jetbrains.kotlin.native.interop.gen.jvm package org.jetbrains.kotlin.native.interop.gen.jvm
import kotlinx.metadata.*
import kotlinx.metadata.klib.KlibModuleFragmentWriteStrategy
import kotlinx.metadata.klib.KlibModuleMetadata import kotlinx.metadata.klib.KlibModuleMetadata
import kotlinx.metadata.klib.className
import kotlinx.metadata.klib.fqName
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CURRENT
@@ -44,8 +48,7 @@ fun createInteropLibrary(arguments: LibraryCreationArguments) {
version, version,
arguments.target arguments.target
).apply { ).apply {
// TODO: Add write strategy that splits big fragments. val metadata = arguments.metadata.write(ChunkingWriteStrategy())
val metadata = arguments.metadata.write()
addMetadata(SerializedMetadata(metadata.header, metadata.fragments, metadata.fragmentNames)) addMetadata(SerializedMetadata(metadata.header, metadata.fragments, metadata.fragmentNames))
addNativeBitcode(arguments.nativeBitcodePath) addNativeBitcode(arguments.nativeBitcodePath)
addManifestAddend(arguments.manifest) addManifestAddend(arguments.manifest)
@@ -53,3 +56,38 @@ fun createInteropLibrary(arguments: LibraryCreationArguments) {
commit() commit()
} }
} }
// TODO: Consider adding it to kotlinx-metadata-klib.
class ChunkingWriteStrategy(
private val classesChunkSize: Int = 128,
private val packagesChunkSize: Int = 128
) : KlibModuleFragmentWriteStrategy {
override fun processPackageParts(parts: List<KmModuleFragment>): List<KmModuleFragment> {
if (parts.isEmpty()) return emptyList()
val fqName = parts.first().fqName
?: error("KmModuleFragment should have a not-null fqName!")
val classFragments = parts.flatMap(KmModuleFragment::classes)
.chunked(classesChunkSize) { chunk ->
KmModuleFragment().also { fragment ->
fragment.fqName = fqName
fragment.classes += chunk
chunk.mapTo(fragment.className, KmClass::name)
}
}
val packageFragments = parts.mapNotNull(KmModuleFragment::pkg)
.flatMap { it.functions + it.typeAliases + it.properties }
.chunked(packagesChunkSize) { chunk ->
KmModuleFragment().also { fragment ->
fragment.fqName = fqName
fragment.pkg = KmPackage().also { pkg ->
pkg.fqName = fqName
pkg.properties += chunk.filterIsInstance<KmProperty>()
pkg.functions += chunk.filterIsInstance<KmFunction>()
pkg.typeAliases += chunk.filterIsInstance<KmTypeAlias>()
}
}
}
return classFragments + packageFragments
}
}