[Klib] Split up IR header tables onto three parts
There was one monolith protobuf at irHeader.knd, it was split up onto 4 parts due to performance issues: - a small irHeader with some basic info about a module - symbols table - types table - strings table These 3 tables are then mmapped and accessed by index.
This commit is contained in:
@@ -22,7 +22,7 @@ fun String.parseKonanAbiVersion(): KotlinAbiVersion {
|
||||
|
||||
data class KotlinAbiVersion(val version: Int) {
|
||||
companion object {
|
||||
val CURRENT = KotlinAbiVersion(11)
|
||||
val CURRENT = KotlinAbiVersion(12)
|
||||
}
|
||||
override fun toString() = "$version"
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ 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
|
||||
}
|
||||
|
||||
val BaseKotlinLibrary.uniqueName: String
|
||||
|
||||
@@ -48,10 +48,18 @@ interface MetadataKotlinLibraryLayout : KotlinLibraryLayout {
|
||||
interface IrKotlinLibraryLayout : KotlinLibraryLayout {
|
||||
val irDir
|
||||
get() = File(libDir, "ir")
|
||||
val irFile
|
||||
get() = File(irDir, "irCombined.knd")
|
||||
val irTablesDir
|
||||
get() = File(irDir, "ir_tables")
|
||||
val irHeader
|
||||
get() = File(irDir, "irHeaders.kni")
|
||||
val irDeclarations
|
||||
get() = File(irTablesDir, "irCombined.knd")
|
||||
val irSymbols
|
||||
get() = File(irTablesDir, "symbols.knt")
|
||||
val irTypes
|
||||
get() = File(irTablesDir, "types.knt")
|
||||
val irStrings
|
||||
get() = File(irTablesDir, "strings.knt")
|
||||
val dataFlowGraphFile
|
||||
get() = File(irDir, "module_data_flow_graph")
|
||||
}
|
||||
|
||||
@@ -35,5 +35,8 @@ class SerializedMetadata(
|
||||
|
||||
class SerializedIr (
|
||||
val module: ByteArray,
|
||||
val symbolTableFilePath: String,
|
||||
val typeTableFilePath: String,
|
||||
val stringTableFilePath: String,
|
||||
val combinedDeclarationFilePath: String
|
||||
)
|
||||
@@ -11,12 +11,16 @@ import org.jetbrains.kotlin.library.*
|
||||
class IrWriterImpl(val irLayout: IrKotlinLibraryLayout) : IrWriter {
|
||||
init {
|
||||
irLayout.irDir.mkdirs()
|
||||
irLayout.irTablesDir.mkdirs()
|
||||
}
|
||||
|
||||
override fun addIr(ir: SerializedIr) {
|
||||
irLayout.irHeader.writeBytes(ir.module)
|
||||
// TODO: use Files.move.
|
||||
File(ir.combinedDeclarationFilePath).copyTo(irLayout.irFile)
|
||||
File(ir.combinedDeclarationFilePath).copyTo(irLayout.irDeclarations)
|
||||
File(ir.symbolTableFilePath).copyTo(irLayout.irSymbols)
|
||||
File(ir.typeTableFilePath).copyTo(irLayout.irTypes)
|
||||
File(ir.stringTableFilePath).copyTo(irLayout.irStrings)
|
||||
}
|
||||
|
||||
override fun addDataFlowGraph(dataFlowGraph: ByteArray) {
|
||||
|
||||
@@ -18,10 +18,8 @@ package org.jetbrains.kotlin.library.impl
|
||||
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.library.*
|
||||
import org.jetbrains.kotlin.library.impl.*
|
||||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||
|
||||
open class BaseKotlinLibraryImpl(
|
||||
private val access: BaseLibraryAccess<KotlinLibraryLayout>,
|
||||
@@ -87,9 +85,33 @@ open class IrLibraryImpl(
|
||||
|
||||
override fun irDeclaration(index: Long, isLocal: Boolean) = 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)
|
||||
|
||||
private val combinedDeclarations: CombinedIrFileReader by lazy {
|
||||
CombinedIrFileReader(access.realFiles {
|
||||
it.irFile
|
||||
it.irDeclarations
|
||||
})
|
||||
}
|
||||
|
||||
private val symbols: SimpleIrTableFileReader by lazy {
|
||||
SimpleIrTableFileReader(access.realFiles {
|
||||
it.irSymbols
|
||||
})
|
||||
}
|
||||
|
||||
private val types: SimpleIrTableFileReader by lazy {
|
||||
SimpleIrTableFileReader(access.realFiles {
|
||||
it.irTypes
|
||||
})
|
||||
}
|
||||
|
||||
private val strings: SimpleIrTableFileReader by lazy {
|
||||
SimpleIrTableFileReader(access.realFiles {
|
||||
it.irStrings
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,13 @@ class ExtractingIrLibraryImpl(val zipped: IrLibraryLayoutImpl) :
|
||||
ExtractingKotlinLibraryLayout(zipped),
|
||||
IrKotlinLibraryLayout {
|
||||
|
||||
override val irFile: File by lazy { zipped.extract(zipped.irFile) }
|
||||
override val irDeclarations: File by lazy { zipped.extract(zipped.irDeclarations) }
|
||||
|
||||
override val irSymbols: File by lazy { zipped.extract(zipped.irSymbols) }
|
||||
|
||||
override val irTypes: File by lazy { zipped.extract(zipped.irTypes) }
|
||||
|
||||
override val irStrings: File by lazy { zipped.extract(zipped.irStrings) }
|
||||
}
|
||||
|
||||
internal fun zippedKotlinLibraryChecks(klibFile: File) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.library.impl
|
||||
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import java.io.RandomAccessFile
|
||||
import java.nio.channels.FileChannel
|
||||
import java.nio.file.Files
|
||||
|
||||
class SimpleIrTableFileReader(file: File) {
|
||||
private val buffer = file.map(FileChannel.MapMode.READ_ONLY)
|
||||
private val indexToOffset: IntArray
|
||||
|
||||
init {
|
||||
val count = buffer.int
|
||||
indexToOffset = IntArray(count + 1)
|
||||
indexToOffset[0] = 4 * (count + 1)
|
||||
for (i in 0 until count) {
|
||||
val size = buffer.int
|
||||
indexToOffset[i + 1] = indexToOffset[i] + size
|
||||
}
|
||||
}
|
||||
|
||||
fun tableItemBytes(id: Int): ByteArray {
|
||||
val offset = indexToOffset[id]
|
||||
val size = indexToOffset[id + 1] - offset
|
||||
val result = ByteArray(size)
|
||||
buffer.position(offset)
|
||||
buffer.get(result, 0, size)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleIrTableFileWriter(val tableName: String, val itemsCount: Int) {
|
||||
private var currentItemIndex = 0
|
||||
private var currentPosition = 0
|
||||
private val file = Files.createTempFile(tableName, "").toFile()
|
||||
private val randomAccessFile = RandomAccessFile(file.path, "rw")
|
||||
|
||||
init {
|
||||
randomAccessFile.writeInt(itemsCount)
|
||||
assert(randomAccessFile.filePointer.toInt() == 4)
|
||||
for (i in 0 until itemsCount) {
|
||||
randomAccessFile.writeInt(-1) // size
|
||||
}
|
||||
currentPosition = randomAccessFile.filePointer.toInt()
|
||||
assert(currentPosition == 4 + 4 * itemsCount)
|
||||
}
|
||||
|
||||
fun addItem(bytes: ByteArray) {
|
||||
randomAccessFile.seek((currentItemIndex * 4 + 4).toLong())
|
||||
randomAccessFile.writeInt(bytes.size)
|
||||
randomAccessFile.seek(currentPosition.toLong())
|
||||
randomAccessFile.write(bytes)
|
||||
assert(randomAccessFile.filePointer < Int.MAX_VALUE.toLong())
|
||||
currentPosition = randomAccessFile.filePointer.toInt()
|
||||
currentItemIndex++
|
||||
}
|
||||
|
||||
fun finishWriting(): java.io.File {
|
||||
assert(currentItemIndex == itemsCount) { "Expected: $itemsCount, but was: $currentItemIndex" }
|
||||
randomAccessFile.close()
|
||||
return file
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user