Support a more optimized way of storing types in metadata

Together with almost every type now there's also an id which references a type
from a separate table. Storing such ids instead of Type messages will allow to
reduce the size of the metadata for files where types are used many times over
and over again. Currently only deserialization of such types is supported,
along with the former mechanism
This commit is contained in:
Alexander Udalov
2015-10-07 19:00:08 +03:00
parent bff6639e2d
commit 82d2e623d3
32 changed files with 5583 additions and 796 deletions
@@ -92,8 +92,8 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
proto as ProtoBuf.Property
val nameResolver = container.nameResolver
val syntheticFunctionSignature = getPropertySignature(proto, nameResolver, synthetic = true)
val fieldSignature = getPropertySignature(proto, nameResolver, field = true)
val syntheticFunctionSignature = getPropertySignature(proto, nameResolver, container.typeTable, synthetic = true)
val fieldSignature = getPropertySignature(proto, nameResolver, container.typeTable, field = true)
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
findClassAndLoadMemberAnnotations(container, proto, sig)
@@ -106,7 +106,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
}
val signature = getCallableSignature(proto, container.nameResolver, kind) ?: return emptyList()
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList()
return transformAnnotations(findClassAndLoadMemberAnnotations(container, proto, signature))
}
@@ -138,7 +138,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
parameterIndex: Int,
proto: ProtoBuf.ValueParameter
): List<A> {
val methodSignature = getCallableSignature(message, container.nameResolver, kind)
val methodSignature = getCallableSignature(message, container.nameResolver, container.typeTable, kind)
if (methodSignature != null) {
val index = if (proto.hasExtension(index)) proto.getExtension(index) else parameterIndex
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index)
@@ -153,7 +153,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
message: MessageLite,
kind: AnnotatedCallableKind
): List<A> {
val methodSignature = getCallableSignature(message, container.nameResolver, kind)
val methodSignature = getCallableSignature(message, container.nameResolver, container.typeTable, kind)
if (methodSignature != null) {
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, 0)
return findClassAndLoadMemberAnnotations(container, message, paramSignature)
@@ -168,7 +168,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
override fun loadPropertyConstant(container: ProtoContainer, proto: ProtoBuf.Property, expectedType: JetType): C? {
val nameResolver = container.nameResolver
val signature = getCallableSignature(proto, nameResolver, AnnotatedCallableKind.PROPERTY) ?: return null
val signature = getCallableSignature(proto, nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY) ?: return null
val kotlinClass = findClassWithAnnotationsAndInitializers(
container, getImplClassName(proto, nameResolver), isStaticFieldInOuter(proto)
@@ -279,6 +279,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
private fun getPropertySignature(
proto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable,
field: Boolean = false,
synthetic: Boolean = false
): MemberSignature? {
@@ -287,7 +288,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
else return null
if (field) {
val (name, desc) = JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver) ?: return null
val (name, desc) = JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable) ?: return null
return MemberSignature.fromFieldNameAndDesc(name, desc)
}
else if (synthetic && signature.hasSyntheticMethod()) {
@@ -297,20 +298,25 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
return null
}
private fun getCallableSignature(proto: MessageLite, nameResolver: NameResolver, kind: AnnotatedCallableKind): MemberSignature? {
private fun getCallableSignature(
proto: MessageLite,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: AnnotatedCallableKind
): MemberSignature? {
return when {
proto is ProtoBuf.Constructor -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver) ?: return null)
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable) ?: return null)
}
proto is ProtoBuf.Function -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver) ?: return null)
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null)
}
proto is ProtoBuf.Property && proto.hasExtension(propertySignature) -> {
val signature = proto.getExtension(propertySignature)
when (kind) {
AnnotatedCallableKind.PROPERTY_GETTER -> MemberSignature.fromMethod(nameResolver, signature.getter)
AnnotatedCallableKind.PROPERTY_SETTER -> MemberSignature.fromMethod(nameResolver, signature.setter)
AnnotatedCallableKind.PROPERTY -> getPropertySignature(proto, nameResolver, true, true)
AnnotatedCallableKind.PROPERTY -> getPropertySignature(proto, nameResolver, typeTable, true, true)
else -> null
}
}
@@ -25,7 +25,8 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.serialization.ClassData
import org.jetbrains.kotlin.serialization.PackageData
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.io.ByteArrayInputStream
public object JvmProtoBufUtil {
@@ -60,7 +61,11 @@ public object JvmProtoBufUtil {
}
// returns JVM signature in the format: "equals(Ljava/lang/Object;)Z"
fun getJvmMethodSignature(proto: ProtoBuf.FunctionOrBuilder, nameResolver: NameResolver): String? {
fun getJvmMethodSignature(
proto: ProtoBuf.Function,
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.methodSignature)) proto.getExtension(JvmProtoBuf.methodSignature) else null
val name = if (signature != null && signature.hasName()) signature.name else proto.name
@@ -68,18 +73,21 @@ public object JvmProtoBufUtil {
nameResolver.getString(signature.desc)
}
else {
val parameterTypes =
(if (proto.hasReceiverType()) listOf(proto.receiverType) else listOf()) + proto.valueParameterList.map { it.type }
val parameterTypes = proto.receiverType(typeTable).singletonOrEmptyList() + proto.valueParameterList.map { it.type(typeTable) }
val parametersDesc = parameterTypes.map { mapTypeDefault(it, nameResolver) ?: return null }
val returnTypeDesc = mapTypeDefault(proto.returnType, nameResolver) ?: return null
val returnTypeDesc = mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null
parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc
}
return nameResolver.getString(name) + desc
}
fun getJvmConstructorSignature(proto: ProtoBuf.ConstructorOrBuilder, nameResolver: NameResolver): String? {
fun getJvmConstructorSignature(
proto: ProtoBuf.Constructor,
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.constructorSignature)) proto.getExtension(JvmProtoBuf.constructorSignature) else null
val desc = if (signature != null && signature.hasDesc()) {
@@ -87,13 +95,17 @@ public object JvmProtoBufUtil {
}
else {
proto.valueParameterList.map {
mapTypeDefault(it.type, nameResolver) ?: return null
mapTypeDefault(it.type(typeTable), nameResolver) ?: return null
}.joinToString(separator = "", prefix = "(", postfix = ")V")
}
return "<init>" + desc
}
fun getJvmFieldSignature(proto: ProtoBuf.Property, nameResolver: NameResolver): PropertySignature? {
fun getJvmFieldSignature(
proto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable
): PropertySignature? {
val signature =
if (proto.hasExtension(JvmProtoBuf.propertySignature)) proto.getExtension(JvmProtoBuf.propertySignature) else return null
val field =
@@ -102,7 +114,7 @@ public object JvmProtoBufUtil {
val name = if (field != null && field.hasName()) field.name else proto.name
val desc =
if (field != null && field.hasDesc()) nameResolver.getString(field.desc)
else mapTypeDefault(proto.returnType, nameResolver) ?: return null
else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null
return PropertySignature(nameResolver.getString(name), desc)
}