JVM_IR: avoid double encoding of byte strings

IrLibraryFile, ingerited from Klib code, needed types, bodies, strings,
signatures encoded as byte strings.
When we store this data as class annotations, it is better to store it
as protobuf structs, to avoid re-encoding byte streams twice.
This commit is contained in:
Georgy Bronnikov
2021-09-27 19:41:49 +03:00
committed by TeamCityServer
parent b61389f6f9
commit 8a459821d0
13 changed files with 686 additions and 326 deletions
@@ -16,11 +16,11 @@ message XStatementOrExpression {
message AuxTables {
// TODO: optimize the representation.
repeated bytes type = 1;
repeated bytes signature = 2;
repeated bytes string = 3;
repeated bytes body = 4;
repeated bytes debug_info = 5;
repeated common.serialization.proto.IrType type = 1;
repeated common.serialization.proto.IdSignature signature = 2;
repeated string string = 3;
repeated XStatementOrExpression body = 4;
repeated string debug_info = 5;
}
message JvmIrFile {
@@ -54,11 +54,16 @@ class JvmIrSerializerSession(
private fun serializeAuxTables(): JvmIr.AuxTables {
val proto = JvmIr.AuxTables.newBuilder()
protoTypeArray.forEach { proto.addType(it.toByteString()) }
protoIdSignatureArray.forEach { proto.addSignature(it.toByteString()) }
protoStringArray.forEach { proto.addString(ByteString.copyFromUtf8(it)) }
protoBodyArray.forEach { proto.addBody(ByteString.copyFrom(it.toByteArray())) }
protoDebugInfoArray.forEach { proto.addDebugInfo(ByteString.copyFromUtf8(it)) }
protoTypeArray.forEach(proto::addType)
protoIdSignatureArray.forEach(proto::addSignature)
protoStringArray.forEach(proto::addString)
protoBodyArray.forEach { proto.addBody(it.toProto()) }
protoDebugInfoArray.forEach(proto::addDebugInfo)
return proto.build()
}
fun XStatementOrExpression.toProto(): JvmIr.XStatementOrExpression = when (this) {
is XStatementOrExpression.XStatement -> JvmIr.XStatementOrExpression.newBuilder().setStatement(toProtoStatement()).build()
is XStatementOrExpression.XExpression -> JvmIr.XStatementOrExpression.newBuilder().setExpression(toProtoExpression()).build()
}
}
@@ -29,7 +29,11 @@ import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.protobuf.ByteString
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
import org.jetbrains.kotlin.backend.common.serialization.proto.IrExpression as ProtoExpression
import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement
import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoType
fun deserializeClassFromByteArray(
byteArray: ByteArray,
@@ -40,7 +44,7 @@ fun deserializeClassFromByteArray(
) {
val irBuiltIns = stubGenerator.irBuiltIns
val symbolTable = stubGenerator.symbolTable
val irProto = JvmIr.JvmIrClass.parseFrom(byteArray)
val irProto = JvmIr.JvmIrClass.parseFrom(byteArray.codedInputStream)
val irLibraryFile = IrLibraryFileFromAnnotation(
irProto.auxTables.typeList,
irProto.auxTables.signatureList,
@@ -98,7 +102,7 @@ fun deserializeIrFileFromByteArray(
) {
val irBuiltIns = stubGenerator.irBuiltIns
val symbolTable = stubGenerator.symbolTable
val irProto = JvmIr.JvmIrFile.parseFrom(byteArray)
val irProto = JvmIr.JvmIrFile.parseFrom(byteArray.codedInputStream)
val irLibraryFile = IrLibraryFileFromAnnotation(
irProto.auxTables.typeList,
irProto.auxTables.signatureList,
@@ -151,21 +155,26 @@ fun deserializeIrFileFromByteArray(
}
private class IrLibraryFileFromAnnotation(
private val types: List<ByteString>,
private val signatures: List<ByteString>,
private val strings: List<ByteString>,
private val bodies: List<ByteString>,
private val debugInfo: List<ByteString>
private val types: List<ProtoType>,
private val signatures: List<ProtoIdSignature>,
private val strings: List<String>,
private val bodies: List<JvmIr.XStatementOrExpression>,
private val debugInfo: List<String>
) : IrLibraryFile() {
override fun irDeclaration(index: Int): ByteArray {
override fun declaration(index: Int): ProtoDeclaration {
error("This method is never supposed to be called")
}
override fun type(index: Int): ByteArray = types[index].toByteArray()
override fun signature(index: Int): ByteArray = signatures[index].toByteArray()
override fun string(index: Int): ByteArray = strings[index].toByteArray()
override fun body(index: Int): ByteArray = bodies[index].toByteArray()
override fun debugInfo(index: Int): ByteArray = debugInfo[index].toByteArray()
override fun type(index: Int): ProtoType = types[index]
override fun signature(index: Int): ProtoIdSignature = signatures[index]
override fun string(index: Int): String = strings[index]
override fun debugInfo(index: Int): String = debugInfo[index]
override fun expressionBody(index: Int): ProtoExpression =
bodies[index].also { require(it.hasExpression()) }.expression
override fun statementBody(index: Int): ProtoStatement =
bodies[index].also { require(it.hasStatement()) }.statement
}
private fun referencePublicSymbol(