[IR SERIALIZATION] Support both Per-File and Monolitic klib layout

This commit is contained in:
Roman Artemev
2019-08-13 17:44:55 +03:00
committed by romanart
parent 125982841a
commit aa313903cc
5 changed files with 97 additions and 124 deletions
@@ -32,11 +32,6 @@ interface MetadataLibrary {
interface IrLibrary {
val dataFlowGraph: ByteArray?
val irHeader: ByteArray?
fun irDeclaration(index: Long, isLocal: Boolean): ByteArray
fun symbol(index: Int): ByteArray
fun type(index: Int): ByteArray
fun string(index: Int): ByteArray
fun irDeclaration(index: Long, isLocal: Boolean, fileIndex: Int): ByteArray
fun symbol(index: Int, fileIndex: Int): ByteArray
fun type(index: Int, fileIndex: Int): ByteArray
@@ -48,10 +48,6 @@ interface MetadataKotlinLibraryLayout : KotlinLibraryLayout {
interface IrKotlinLibraryLayout : KotlinLibraryLayout {
val irDir
get() = File(libDir, "ir")
val irTablesDir
get() = File(irDir, "ir_tables")
val irHeader
get() = File(irDir, "irHeaders.kni")
val irDeclarations
get() = File(irDir, "irDeclarations.knd")
val irSymbols
@@ -73,15 +69,4 @@ interface IrKotlinLibraryLayout : KotlinLibraryLayout {
fun irStrings(file: File): File = File(file, "strings.knt")
fun irBodies(file: File): File = File(file, "body.knb")
fun irFile(file: File): File = File(file, "file.knf")
val irFilesX
get() = run {
val fileDirectories = mutableListOf<File>()
irDir.postorder {
if (it.fileName.toString().endsWith(".file")) {
fileDirectories.add(File(it))
}
}
fileDirectories
}
}
@@ -7,42 +7,19 @@ package org.jetbrains.kotlin.library.impl
import org.jetbrains.kotlin.library.*
class IrWriterImpl(val irLayout: IrKotlinLibraryLayout) : IrWriter {
abstract class IrWriterImpl(val irLayout: IrKotlinLibraryLayout) : IrWriter {
init {
irLayout.irDir.mkdirs()
irLayout.irTablesDir.mkdirs()
}
private fun serializeFile(file: SerializedIrFile) {
val fqnPath = file.fqName.joinToString(separator = "/")
val fileId = file.path.hashCode().toString(Character.MAX_RADIX)
val fileDirectoryName = "${fileId}.file"
val packageDir = irLayout.irDir.child(fqnPath)
if (!packageDir.exists) {
packageDir.mkdirs()
}
val fileDir = packageDir.child(fileDirectoryName)
assert(!fileDir.exists)
fileDir.mkdirs()
irLayout.irFile(fileDir).writeBytes(file.fileData)
IrDeclarationWriter(file.declarations).writeIntoFile(irLayout.irDeclarations(fileDir).absolutePath)
IrArrayWriter(file.symbols).writeIntoFile(irLayout.irSymbols(fileDir).absolutePath)
IrArrayWriter(file.types).writeIntoFile(irLayout.irTypes(fileDir).absolutePath)
IrArrayWriter(file.strings).writeIntoFile(irLayout.irStrings(fileDir).absolutePath)
IrArrayWriter(file.bodies).writeIntoFile(irLayout.irBodies(fileDir).absolutePath)
fileDir.child("declarations.txt").writeText(file.declarations.joinToString(separator = "\n") { "${it.declarationName} -> (${it.id}, ${it.local})" })
override fun addDataFlowGraph(dataFlowGraph: ByteArray) {
irLayout.dataFlowGraphFile.writeBytes(dataFlowGraph)
}
}
class IrMonoliticWriterImpl(irLayout: IrKotlinLibraryLayout) : IrWriterImpl(irLayout) {
override fun addIr(ir: SerializedIrModule) {
// ir.files.forEach {
// serializeFile(it)
// }
with(ir.files.sortedBy { it.path }) {
IrArrayWriter(map { it.fileData }).writeIntoFile(irLayout.irFiles.absolutePath)
IrArrayWriter(map { IrMemoryDeclarationWriter(it.declarations).writeIntoMemory() }).writeIntoFile(irLayout.irDeclarations.absolutePath)
@@ -51,15 +28,31 @@ class IrWriterImpl(val irLayout: IrKotlinLibraryLayout) : IrWriter {
IrArrayWriter(map { IrMemoryArrayWriter(it.strings).writeIntoMemory() }).writeIntoFile(irLayout.irStrings.absolutePath)
IrArrayWriter(map { IrMemoryArrayWriter(it.bodies).writeIntoMemory() }).writeIntoFile(irLayout.irBodies.absolutePath)
}
// IrDeclarationWriter(ir.serializedDeclarations).writeIntoFile(irLayout.irDeclarations.absolutePath)
// IrArrayWriter(ir.symbols).writeIntoFile(irLayout.irSymbols.absolutePath)
// IrArrayWriter(ir.types).writeIntoFile(irLayout.irTypes.absolutePath)
// IrArrayWriter(ir.strings).writeIntoFile(irLayout.irStrings.absolutePath)
}
override fun addDataFlowGraph(dataFlowGraph: ByteArray) {
irLayout.dataFlowGraphFile.writeBytes(dataFlowGraph)
}
}
class IrPerFileWriterImpl(irLayout: IrKotlinLibraryLayout) : IrWriterImpl(irLayout) {
override fun addIr(ir: SerializedIrModule) {
ir.files.forEach {
serializeFile(it)
}
}
private fun serializeFile(file: SerializedIrFile) {
val fqnPath = file.fqName.joinToString(separator = ".")
val fileId = file.path.hashCode().toString(Character.MAX_RADIX)
val irFileDirectory = "$fqnPath.$fileId.file"
val fileDir = irLayout.irDir.child(irFileDirectory)
assert(!fileDir.exists)
fileDir.mkdirs()
irLayout.irFile(fileDir).writeBytes(file.fileData)
IrDeclarationWriter(file.declarations).writeIntoFile(irLayout.irDeclarations(fileDir).absolutePath)
IrArrayWriter(file.symbols).writeIntoFile(irLayout.irSymbols(fileDir).absolutePath)
IrArrayWriter(file.types).writeIntoFile(irLayout.irTypes(fileDir).absolutePath)
IrArrayWriter(file.strings).writeIntoFile(irLayout.irStrings(fileDir).absolutePath)
IrArrayWriter(file.bodies).writeIntoFile(irLayout.irBodies(fileDir).absolutePath)
// fileDir.child("declarations.txt").writeText(file.declarations.joinToString(separator = "\n") { "${it.declarationName} -> (${it.id}, ${it.local})" })
}
}
@@ -71,31 +71,20 @@ open class MetadataLibraryImpl(
}
}
open class IrLibraryImpl(
private val access: IrLibraryAccess<IrKotlinLibraryLayout>
abstract class IrLibraryImpl(
protected val access: IrLibraryAccess<IrKotlinLibraryLayout>
) : IrLibrary {
override val irHeader: ByteArray? by lazy {
access.inPlace { library: IrKotlinLibraryLayout ->
library.irHeader.let {
if (it.exists) loadIrHeader() else null
}
override val dataFlowGraph by lazy {
access.inPlace { it: IrKotlinLibraryLayout ->
it.dataFlowGraphFile.let { if (it.exists) it.readBytes() else null }
}
}
}
override fun irDeclaration(index: Long, isLocal: Boolean) = error("Should not call this") //loadIrDeclaraton(index, isLocal)
override fun symbol(index: Int) = symbols.tableItemBytes(index)
override fun type(index: Int) = types.tableItemBytes(index)
override fun string(index: Int) = strings.tableItemBytes(index)
override fun file(index: Int): ByteArray = files.tableItemBytes(index)
class IrMonoliticLibraryImpl(_access: IrLibraryAccess<IrKotlinLibraryLayout>) : IrLibraryImpl(_access) {
override fun fileCount(): Int = files.entryCount()
override fun irDeclaration(index: Long, isLocal: Boolean, fileIndex: Int) = loadIrDeclaraton(index, isLocal, fileIndex)
override fun irDeclaration(index: Long, isLocal: Boolean, fileIndex: Int) = loadIrDeclaration(index, isLocal, fileIndex)
override fun symbol(index: Int, fileIndex: Int) = symbols.tableItemBytes(fileIndex, index)
@@ -105,6 +94,11 @@ open class IrLibraryImpl(
override fun body(index: Int, fileIndex: Int) = bodies.tableItemBytes(fileIndex, index)
override fun file(index: Int) = files.tableItemBytes(index)
private fun loadIrDeclaration(index: Long, isLocal: Boolean, fileIndex: Int) =
combinedDeclarations.tableItemBytes(fileIndex, DeclarationId(index, isLocal))
private val combinedDeclarations: DeclarationIrMultiTableReader by lazy {
DeclarationIrMultiTableReader(access.realFiles {
it.irDeclarations
@@ -140,75 +134,79 @@ open class IrLibraryImpl(
it.irFiles
})
}
}
class IrPerFileLibraryImpl(_access: IrLibraryAccess<IrKotlinLibraryLayout>) : IrLibraryImpl(_access) {
private fun getFileDirectory(fileName: String): File {
val directoryName = "${fileName.hashCode().toString(Character.MAX_RADIX)}.file"
return access.realFiles {
it.irFilesX.first { it.name == directoryName }
private val directories by lazy {
access.realFiles {
it.irDir.listFiles.filter { f -> f.isDirectory && f.name.endsWith(".file") }
}
}
private val fileToDeclarationMap = mutableMapOf<String, DeclarationIrTableReader>()
private fun combinedDeclarations(fileName: String): DeclarationIrTableReader {
return fileToDeclarationMap.getOrPut(fileName) {
private val fileToDeclarationMap = mutableMapOf<Int, DeclarationIrTableReader>()
override fun irDeclaration(index: Long, isLocal: Boolean, fileIndex: Int): ByteArray {
val dataReader = fileToDeclarationMap.getOrPut(fileIndex) {
val fileDirectory = directories[fileIndex]
DeclarationIrTableReader(access.realFiles {
it.irDeclarations(getFileDirectory(fileName))
it.irDeclarations(fileDirectory)
})
}
return dataReader.tableItemBytes(DeclarationId(index, isLocal))
}
private val fileToSymbolMap = mutableMapOf<String, IrArrayReader>()
private fun symbols(fileName: String): IrArrayReader {
return fileToSymbolMap.getOrPut(fileName) {
private val fileToSymbolMap = mutableMapOf<Int, IrArrayReader>()
override fun symbol(index: Int, fileIndex: Int): ByteArray {
val dataReader = fileToSymbolMap.getOrPut(fileIndex) {
val fileDirectory = directories[fileIndex]
IrArrayReader(access.realFiles {
it.irSymbols(getFileDirectory(fileName))
it.irSymbols(fileDirectory)
})
}
return dataReader.tableItemBytes(index)
}
private val fileToTypeMap = mutableMapOf<String, IrArrayReader>()
private fun types(fileName: String): IrArrayReader {
return fileToTypeMap.getOrPut(fileName) {
private val fileToTypeMap = mutableMapOf<Int, IrArrayReader>()
override fun type(index: Int, fileIndex: Int): ByteArray {
val dataReader = fileToTypeMap.getOrPut(fileIndex) {
val fileDirectory = directories[fileIndex]
IrArrayReader(access.realFiles {
it.irTypes(getFileDirectory(fileName))
it.irTypes(fileDirectory)
})
}
return dataReader.tableItemBytes(index)
}
// private val fileToStringMap = mutableMapOf<String, IrArrayReader>()
// private fun strings(fileIndex: Int): IrArrayReader {
// return fileToStringMap.getOrPut(fileName) {
// IrArrayReader(access.realFiles {
// it.irStrings(getFileDirectory(fileName))
// })
// }
// }
private val fileToBodyMap = mutableMapOf<String, IrArrayReader>()
private fun bodies(fileName: String): IrArrayReader {
return fileToBodyMap.getOrPut(fileName) {
private val fileToStringMap = mutableMapOf<Int, IrArrayReader>()
override fun string(index: Int, fileIndex: Int): ByteArray {
val dataReader = fileToStringMap.getOrPut(fileIndex) {
val fileDirectory = directories[fileIndex]
IrArrayReader(access.realFiles {
it.irBodies(getFileDirectory(fileName))
it.irStrings(fileDirectory)
})
}
return dataReader.tableItemBytes(index)
}
private val fileToBodyMap = mutableMapOf<Int, IrArrayReader>()
override fun body(index: Int, fileIndex: Int): ByteArray {
val dataReader = fileToBodyMap.getOrPut(fileIndex) {
val fileDirectory = directories[fileIndex]
IrArrayReader(access.realFiles {
it.irBodies(fileDirectory)
})
}
return dataReader.tableItemBytes(index)
}
override fun file(index: Int): ByteArray {
return access.realFiles {
it.irFile(directories[index]).readBytes()
}
}
private fun loadIrHeader(): ByteArray =
access.inPlace {
it.irHeader.readBytes()
}
// private fun loadIrDeclaraton(index: Long, isLocal: Boolean) =
// combinedDeclarations.tableItemBytes(DeclarationId(index, isLocal))
private fun loadIrDeclaraton(index: Long, isLocal: Boolean, fileIndex: Int) =
combinedDeclarations.tableItemBytes(fileIndex, DeclarationId(index, isLocal))
override val dataFlowGraph by lazy {
access.inPlace { it: IrKotlinLibraryLayout ->
it.dataFlowGraphFile.let { if (it.exists) it.readBytes() else null }
}
override fun fileCount(): Int {
return directories.size
}
}
@@ -231,7 +229,8 @@ fun createKotlinLibrary(
val base = BaseKotlinLibraryImpl(baseAccess, isDefault)
val metadata = MetadataLibraryImpl(metadataAccess)
val ir = IrLibraryImpl(irAccess)
// val ir = IrMonoliticLibraryImpl(irAccess)
val ir = IrPerFileLibraryImpl(irAccess)
return KotlinLibraryImpl(base, metadata, ir)
}
@@ -81,7 +81,8 @@ class KoltinLibraryWriterImpl(
base: BaseWriter = BaseWriterImpl(layout, moduleName, versions, nopack),
metadata: MetadataWriter = MetadataWriterImpl(layout),
ir: IrWriter = IrWriterImpl(layout)
// ir: IrWriter = IrMonoliticWriterImpl(layout)
ir: IrWriter = IrPerFileWriterImpl(layout)
) : BaseWriter by base, MetadataWriter by metadata, IrWriter by ir, KotlinLibraryWriter