Moved from int32 indices to message UniqId { int64 index; }.

This commit is contained in:
Alexander Gorshenev
2017-04-13 13:01:22 +03:00
committed by alexander-gorshenev
parent a703647b79
commit f14716dfc0
6 changed files with 102 additions and 89 deletions
@@ -173,22 +173,6 @@ internal val PropertyDescriptor.symbolName: String
} }
internal val TypeParameterDescriptor.symbolName: String
get() {
val containingDeclarationPart = containingDeclaration.fqNameSafe.let {
if (it.isRoot) "" else "$it."
}
return "ktypeparam:$containingDeclarationPart$name"
}
internal val ValueParameterDescriptor.symbolName: String
get() {
val containingDeclarationPart = containingDeclaration.fqNameSafe.let {
if (it.isRoot) "" else "$it."
}
return "kvalueparam:$containingDeclarationPart$name"
}
private fun getStringValue(annotation: AnnotationDescriptor): String? { private fun getStringValue(annotation: AnnotationDescriptor): String? {
annotation.allValueArguments.values.ifNotEmpty { annotation.allValueArguments.values.ifNotEmpty {
val stringValue = this.single() as StringValue val stringValue = this.single() as StringValue
@@ -29,54 +29,39 @@ import org.jetbrains.kotlin.backend.konan.llvm.typeInfoSymbolName
import org.jetbrains.kotlin.backend.konan.llvm.symbolName import org.jetbrains.kotlin.backend.konan.llvm.symbolName
import org.jetbrains.kotlin.backend.konan.llvm.localHash import org.jetbrains.kotlin.backend.konan.llvm.localHash
// TODO: We take Long hash .toInt() here. internal fun DeclarationDescriptor.symbolName(): String = when (this) {
// Make it long all the way down to the protobuf? is FunctionDescriptor
internal fun DeclarationDescriptor.uniqId(): Int = when (this) { -> this.symbolName
is FunctionDescriptor -> { is PropertyDescriptor
this.symbolName.localHash.value.toInt() -> this.symbolName
} is ClassDescriptor
is PropertyDescriptor -> { -> this.typeInfoSymbolName
this.symbolName.localHash.value.toInt()
}
is TypeParameterDescriptor -> {
this.symbolName.localHash.value.toInt()
}
is ValueParameterDescriptor -> {
this.symbolName.localHash.value.toInt()
}
is ClassDescriptor -> {
this.typeInfoSymbolName.localHash.value.toInt()
}
else -> error("Unexpected exported descriptor: $this") else -> error("Unexpected exported descriptor: $this")
} }
internal val DeclarationDescriptor.uniqId
get() = this.symbolName().localHash.value
// TODO: we currently just assign each encountered
// descriptor a new int id. // TODO: We don't manage id clashes anyhow now.
// That;s okay until we have more than one external module.
// In that case the descriptors will get different ids.
// Need to come up with a stable scheme of ids
// dependant on something like FunctionDescriptor.functionName
class DescriptorTable(val builtIns: IrBuiltIns) { class DescriptorTable(val builtIns: IrBuiltIns) {
val table = mutableMapOf<DeclarationDescriptor, Int>() val table = mutableMapOf<DeclarationDescriptor, Long>()
var currentIndex = 0 var currentIndex = 0L
init { init {
builtIns.irBuiltInDescriptors.forEachIndexed { builtIns.irBuiltInDescriptors.forEach {
index, descriptor -> table.put(it, it.uniqId)
table.put(descriptor, index)
currentIndex = index + 1
} }
} }
fun indexByValue(value: DeclarationDescriptor): Int { fun indexByValue(value: DeclarationDescriptor): Long {
val index = table.getOrPut(value) { val index = table.getOrPut(value) {
if (!value.isExported()) { if (!value.isExported()
|| value is TypeParameterDescriptor) {
currentIndex++ currentIndex++
} else { } else {
value.uniqId() value.uniqId
} }
} }
return index return index
@@ -85,12 +70,11 @@ class DescriptorTable(val builtIns: IrBuiltIns) {
class IrDeserializationDescriptorIndex(irBuiltIns: IrBuiltIns) { class IrDeserializationDescriptorIndex(irBuiltIns: IrBuiltIns) {
val map = mutableMapOf<Int, DeclarationDescriptor>() val map = mutableMapOf<Long, DeclarationDescriptor>()
init { init {
irBuiltIns.irBuiltInDescriptors.forEachIndexed { irBuiltIns.irBuiltInDescriptors.forEach {
index, descriptor -> map.put(it.uniqId, it)
map.put(index, descriptor)
} }
} }
@@ -39,6 +39,55 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
fun newUniqId(index: Long): KonanLinkData.UniqId =
KonanLinkData.UniqId.newBuilder().setIndex(index).build()
val ProtoBuf.Function.functionIndex: Long
get() = this.getExtension(KonanLinkData.functionIndex).index
val ProtoBuf.Constructor.constructorIndex: Long
get() = this.getExtension(KonanLinkData.constructorIndex).index
val ProtoBuf.Property.propertyIndex: Long
get() = this.getExtension(KonanLinkData.propertyIndex).index
fun ProtoBuf.Function.Builder.setFunctionIndex(index: Long)
= this.setExtension(KonanLinkData.functionIndex, newUniqId(index))
fun ProtoBuf.Constructor.Builder.setConstructorIndex(index: Long)
= this.setExtension(KonanLinkData.constructorIndex, newUniqId(index))
fun ProtoBuf.Property.Builder.setPropertyIndex(index: Long)
= this.setExtension(KonanLinkData.propertyIndex, newUniqId(index))
fun ProtoBuf.Class.Builder.setClassIndex(index: Long)
= this.setExtension(KonanLinkData.classIndex, newUniqId(index))
val KonanIr.KotlinDescriptor.index: Long
get() = this.uniqId.index
fun KonanIr.KotlinDescriptor.Builder.setIndex(index: Long)
= this.setUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.originalIndex: Long
get() = this.originalUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setOriginalIndex(index: Long)
= this.setOriginalUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.dispatchReceiverIndex: Long
get() = this.dispatchReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setDispatchReceiverIndex(index: Long)
= this.setDispatchReceiverUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.extensionReceiverIndex: Long
get() = this.extensionReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setExtensionReceiverIndex(index: Long)
= this.setExtensionReceiverUniqId(newUniqId(index))
internal fun printType(proto: ProtoBuf.Type) { internal fun printType(proto: ProtoBuf.Type) {
println("debug text: " + proto.getExtension(KonanLinkData.typeText)) println("debug text: " + proto.getExtension(KonanLinkData.typeText))
@@ -92,12 +141,11 @@ internal class IrDescriptorDeserializer(val context: Context,
return type return type
} }
fun deserializeLocalDeclaration(proto: KonanLinkData.Descriptor): DeclarationDescriptor { fun deserializeLocalDeclaration(proto: KonanLinkData.Descriptor): DeclarationDescriptor {
when { when {
proto.hasFunction() -> { proto.hasFunction() -> {
val functionProto = proto.function val functionProto = proto.function
val index = functionProto.getExtension(KonanLinkData.functionIndex) val index = functionProto.functionIndex
val descriptor = localDeserializer.deserializeFunction(functionProto) val descriptor = localDeserializer.deserializeFunction(functionProto)
descriptorIndex.put(index, descriptor) descriptorIndex.put(index, descriptor)
return descriptor return descriptor
@@ -105,7 +153,7 @@ internal class IrDescriptorDeserializer(val context: Context,
proto.hasProperty() -> { proto.hasProperty() -> {
val propertyProto = proto.property val propertyProto = proto.property
val index = propertyProto.getExtension(KonanLinkData.propertyIndex) val index = propertyProto.propertyIndex
val descriptor = localDeserializer.deserializeProperty(propertyProto) val descriptor = localDeserializer.deserializeProperty(propertyProto)
descriptorIndex.put(index, descriptor) descriptorIndex.put(index, descriptor)
return descriptor return descriptor
@@ -204,21 +252,19 @@ internal class IrDescriptorDeserializer(val context: Context,
val dispatchReceiver = functionDescriptor.dispatchReceiverParameter val dispatchReceiver = functionDescriptor.dispatchReceiverParameter
if (dispatchReceiver != null) { if (dispatchReceiver != null) {
assert(proto.hasDispatchReceiverIndex()) assert(proto.hasDispatchReceiverUniqId())
val dispatchReceiverIndex = proto.dispatchReceiverIndex val dispatchReceiverIndex = proto.dispatchReceiverIndex
descriptorIndex.put(dispatchReceiverIndex, dispatchReceiver) descriptorIndex.put(dispatchReceiverIndex, dispatchReceiver)
} }
val extensionReceiver = functionDescriptor.extensionReceiverParameter val extensionReceiver = functionDescriptor.extensionReceiverParameter
if (extensionReceiver != null) { if (extensionReceiver != null) {
assert(proto.hasExtensionReceiverIndex()) assert(proto.hasExtensionReceiverUniqId())
val extensionReceiverIndex = proto.extensionReceiverIndex val extensionReceiverIndex = proto.extensionReceiverIndex
descriptorIndex.put(extensionReceiverIndex, extensionReceiver) descriptorIndex.put(extensionReceiverIndex, extensionReceiver)
} }
} }
fun substituteFunction(proto: KonanIr.KotlinDescriptor, fun substituteFunction(proto: KonanIr.KotlinDescriptor,
originalDescriptor: FunctionDescriptor): FunctionDescriptor { originalDescriptor: FunctionDescriptor): FunctionDescriptor {
@@ -292,14 +338,14 @@ internal class IrDescriptorDeserializer(val context: Context,
val dispatchReceiver = newPropertyDescriptor.dispatchReceiverParameter val dispatchReceiver = newPropertyDescriptor.dispatchReceiverParameter
if (dispatchReceiver != null) { if (dispatchReceiver != null) {
assert(proto.hasDispatchReceiverIndex()) assert(proto.hasDispatchReceiverUniqId())
val dispatchReceiverIndex = proto.dispatchReceiverIndex val dispatchReceiverIndex = proto.dispatchReceiverIndex
descriptorIndex.put(dispatchReceiverIndex, dispatchReceiver) descriptorIndex.put(dispatchReceiverIndex, dispatchReceiver)
} }
val extensionReceiver = newPropertyDescriptor.extensionReceiverParameter val extensionReceiver = newPropertyDescriptor.extensionReceiverParameter
if (extensionReceiver != null) { if (extensionReceiver != null) {
assert(proto.hasExtensionReceiverIndex()) assert(proto.hasExtensionReceiverUniqId())
val extensionReceiverIndex = proto.extensionReceiverIndex val extensionReceiverIndex = proto.extensionReceiverIndex
descriptorIndex.put(extensionReceiverIndex, extensionReceiver) descriptorIndex.put(extensionReceiverIndex, extensionReceiver)
} }
@@ -362,8 +408,7 @@ internal class IrDescriptorDeserializer(val context: Context,
val originalIndex = descriptorProto.originalIndex val originalIndex = descriptorProto.originalIndex
val match = functions.singleOrNull() { val match = functions.singleOrNull() {
val proto = (it as DeserializedSimpleFunctionDescriptor).proto val proto = (it as DeserializedSimpleFunctionDescriptor).proto
println("${proto.getExtension(KonanLinkData.functionIndex)} =? ${originalIndex}") proto.functionIndex == originalIndex
proto.getExtension(KonanLinkData.functionIndex) == originalIndex
} as? DeserializedSimpleFunctionDescriptor } as? DeserializedSimpleFunctionDescriptor
if (match != null) return match if (match != null) return match
@@ -388,7 +433,7 @@ internal class IrDescriptorDeserializer(val context: Context,
val originalIndex = descriptorProto.originalIndex val originalIndex = descriptorProto.originalIndex
return constructors.single { return constructors.single {
val proto = (it as DeserializedClassConstructorDescriptor).proto val proto = (it as DeserializedClassConstructorDescriptor).proto
proto.getExtension(KonanLinkData.constructorIndex) == originalIndex proto.constructorIndex == originalIndex
} as DeserializedClassConstructorDescriptor } as DeserializedClassConstructorDescriptor
} }
@@ -406,7 +451,7 @@ internal class IrDescriptorDeserializer(val context: Context,
val originalIndex = proto.originalIndex val originalIndex = proto.originalIndex
return functions.single { return functions.single {
val property = (it as PropertyAccessorDescriptor).correspondingProperty as DeserializedPropertyDescriptor val property = (it as PropertyAccessorDescriptor).correspondingProperty as DeserializedPropertyDescriptor
property.proto.getExtension(KonanLinkData.propertyIndex) == originalIndex property.proto.propertyIndex == originalIndex
} as PropertyAccessorDescriptor } as PropertyAccessorDescriptor
} }
@@ -23,16 +23,16 @@ message KotlinDescriptor {
// TODO: Use the string table? // TODO: Use the string table?
optional string name = 1; optional string name = 1;
required Kind kind = 2; required Kind kind = 2;
required int32 index = 3; required UniqId uniq_id = 3;
required int32 original_index = 4; required UniqId original_uniq_id = 4;
// index in fq name table // index in fq name table
required int32 class_or_package = 5; required int32 class_or_package = 5;
// Descriptor kind specific fields. // Descriptor kind specific fields.
optional KotlinType type = 6; optional KotlinType type = 6;
repeated KotlinDescriptor value_parameter = 7; repeated KotlinDescriptor value_parameter = 7;
repeated KotlinDescriptor type_parameter = 8; repeated KotlinDescriptor type_parameter = 8;
optional int32 dispatch_receiver_index = 9; optional UniqId dispatch_receiver_uniq_id = 9;
optional int32 extension_receiver_index = 10; optional UniqId extension_receiver_uniq_id = 10;
optional KotlinType extension_receiver_type = 11; optional KotlinType extension_receiver_type = 11;
optional LocalDeclaration ir_local_declaration = 12; optional LocalDeclaration ir_local_declaration = 12;
} }
@@ -15,31 +15,35 @@ option optimize_for = LITE_RUNTIME;
// Konan extensions to the "descriptors" protobuf. // Konan extensions to the "descriptors" protobuf.
message UniqId {
required int64 index = 1;
}
extend Package { extend Package {
optional int32 package_fq_name = 171; optional int32 package_fq_name = 171;
} }
extend Class { extend Class {
repeated Annotation class_annotation = 170; repeated Annotation class_annotation = 170;
optional int32 class_index = 171; optional UniqId class_index = 171;
} }
extend Constructor { extend Constructor {
repeated Annotation constructor_annotation = 170; repeated Annotation constructor_annotation = 170;
optional int32 constructor_index = 171; optional UniqId constructor_index = 171;
optional int32 constructor_parent = 172; optional int32 constructor_parent = 172;
} }
extend Function { extend Function {
repeated Annotation function_annotation = 170; repeated Annotation function_annotation = 170;
optional int32 function_index = 171; optional UniqId function_index = 171;
optional int32 function_parent = 172; optional int32 function_parent = 172;
optional InlineIrBody inline_ir_body = 174; optional InlineIrBody inline_ir_body = 174;
} }
extend Property { extend Property {
repeated Annotation property_annotation = 170; repeated Annotation property_annotation = 170;
optional int32 property_index = 171; optional UniqId property_index = 171;
optional int32 property_parent = 172; optional int32 property_parent = 172;
optional bool used_as_variable = 173; optional bool used_as_variable = 173;
optional Annotation.Argument.Value compile_time_value = 174; optional Annotation.Argument.Value compile_time_value = 174;
@@ -47,24 +51,21 @@ extend Property {
extend EnumEntry { extend EnumEntry {
repeated Annotation enum_entry_annotation = 170; repeated Annotation enum_entry_annotation = 170;
optional int32 enum_entry_index = 171; optional UniqId enum_entry_index = 171;
} }
extend ValueParameter { extend ValueParameter {
repeated Annotation parameter_annotation = 170; repeated Annotation parameter_annotation = 170;
optional int32 value_parameter_index = 171;
} }
extend Type { extend Type {
repeated Annotation type_annotation = 170; repeated Annotation type_annotation = 170;
optional int32 type_index = 171; optional UniqId type_index = 171;
optional string type_text = 172; // TODO: remove me optional string type_text = 172; // TODO: remove me
} }
extend TypeParameter { extend TypeParameter {
repeated Annotation type_parameter_annotation = 170; repeated Annotation type_parameter_annotation = 170;
//optional int32 type_parameter_index = 171;
//optional int32 type_parameter_parent = 172;
} }
message InlineIrBody { message InlineIrBody {
@@ -62,10 +62,6 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
} }
override fun serializeValueParameter(descriptor: ValueParameterDescriptor, proto: ProtoBuf.ValueParameter.Builder) { override fun serializeValueParameter(descriptor: ValueParameterDescriptor, proto: ProtoBuf.ValueParameter.Builder) {
val index = inlineDescriptorTable.indexByValue(descriptor)
proto.setExtension(KonanLinkData.valueParameterIndex, index)
super.serializeValueParameter(descriptor, proto) super.serializeValueParameter(descriptor, proto)
} }
@@ -87,7 +83,7 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) { override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) {
proto.setExtension(KonanLinkData.constructorIndex, proto.setConstructorIndex(
inlineDescriptorTable.indexByValue(descriptor)) inlineDescriptorTable.indexByValue(descriptor))
val parentIndex = descriptor.parentFqNameIndex() val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.constructorParent, parentIndex) proto.setExtension(KonanLinkData.constructorParent, parentIndex)
@@ -97,13 +93,14 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) { override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
proto.setExtension(KonanLinkData.classIndex, inlineDescriptorTable.indexByValue(descriptor)) proto.setClassIndex(
inlineDescriptorTable.indexByValue(descriptor))
super.serializeClass(descriptor, proto) super.serializeClass(descriptor, proto)
} }
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) { override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
proto.setExtension(KonanLinkData.functionIndex, proto.setFunctionIndex(
inlineDescriptorTable.indexByValue(descriptor)) inlineDescriptorTable.indexByValue(descriptor))
val parentIndex = descriptor.parentFqNameIndex() val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.functionParent, parentIndex) proto.setExtension(KonanLinkData.functionParent, parentIndex)
@@ -137,10 +134,12 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
val variable = originalVariables[descriptor] val variable = originalVariables[descriptor]
if (variable != null) { if (variable != null) {
proto.setExtension(KonanLinkData.usedAsVariable, true) proto.setExtension(KonanLinkData.usedAsVariable, true)
proto.setExtension(KonanLinkData.propertyIndex, inlineDescriptorTable.indexByValue(variable)) proto.setPropertyIndex(
inlineDescriptorTable.indexByValue(variable))
} else { } else {
proto.setExtension(KonanLinkData.propertyIndex, inlineDescriptorTable.indexByValue(descriptor)) proto.setPropertyIndex(
inlineDescriptorTable.indexByValue(descriptor))
} }
super.serializeProperty(descriptor, proto) super.serializeProperty(descriptor, proto)