[IrSerializer] Cached some heavy descriptor functions

This commit is contained in:
Igor Chevdar
2019-02-19 12:21:41 +05:00
parent e3efd75e55
commit ae29fc5e1a
@@ -13,6 +13,47 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
// packageFqName + classFqName + index allow to localize some deserialized descriptor. // packageFqName + classFqName + index allow to localize some deserialized descriptor.
// Then the rest of the fields allow to find the needed descriptor relative to the one with index. // Then the rest of the fields allow to find the needed descriptor relative to the one with index.
class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>) { class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>) {
private val cache = mutableMapOf<String, Collection<DeclarationDescriptor>>()
private fun getContributedDescriptors(packageFqNameString: String): Collection<DeclarationDescriptor> =
cache.getOrPut(packageFqNameString) {
val packageFqName = packageFqNameString.let {
if (it == "<root>") FqName.ROOT else FqName(it)
}// TODO: whould we store an empty string in the protobuf?
currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors()
}
private data class ClassName(val packageFqName: String, val classFqName: String)
private class ClassMembers(val defaultConstructor: ClassConstructorDescriptor?,
val members: Map<Long, DeclarationDescriptor>,
val realMembers: Map<Long, DeclarationDescriptor>)
private val membersCache = mutableMapOf<ClassName, ClassMembers>()
private fun getMembers(packageFqNameString: String, classFqNameString: String,
members: Collection<DeclarationDescriptor>): ClassMembers =
membersCache.getOrPut(ClassName(packageFqNameString, classFqNameString)) {
val allMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
val realMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
var classConstructorDescriptor: ClassConstructorDescriptor? = null
members.forEach { member ->
if (member is ClassConstructorDescriptor)
classConstructorDescriptor = member
val realMembers =
if (member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
member.resolveFakeOverrideMaybeAbstract()
else
setOf(member)
member.getUniqId()?.index?.let { allMembersMap[it] = member }
realMembers.mapNotNull { it.getUniqId()?.index }.forEach { realMembersMap[it] = member }
}
ClassMembers(classConstructorDescriptor, allMembersMap, realMembersMap)
}
fun deserializeDescriptorReference( fun deserializeDescriptorReference(
packageFqNameString: String, packageFqNameString: String,
classFqNameString: String, classFqNameString: String,
@@ -33,7 +74,7 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
val protoIndex = index val protoIndex = index
val (clazz, members) = if (classFqNameString == "") { val (clazz, members) = if (classFqNameString == "") {
Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors()) Pair(null, getContributedDescriptors(packageFqNameString))
} else { } else {
val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!! val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!!
Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors()) Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors())
@@ -69,25 +110,21 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single() .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
} }
members.forEach { member -> val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members)
if (isDefaultConstructor && member is ClassConstructorDescriptor) return member
val realMembers = return when {
if (isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) isDefaultConstructor -> membersWithIndices.defaultConstructor
member.resolveFakeOverrideMaybeAbstract()
else
setOf(member)
val memberIndices = realMembers.map { it.getUniqId()?.index }.filterNotNull() else -> {
val map = if (isFakeOverride) membersWithIndices.realMembers else membersWithIndices.members
if (memberIndices.contains(protoIndex)) { map[protoIndex]?.let { member ->
return when { when {
member is PropertyDescriptor && isSetter -> member.setter!! member is PropertyDescriptor && isSetter -> member.setter!!
member is PropertyDescriptor && isGetter -> member.getter!! member is PropertyDescriptor && isGetter -> member.getter!!
else -> member else -> member
}
} }
} }
} } ?: error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}")
error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}")
} }
} }