From ae29fc5e1a53bcddf564360bd810d1e7ca26cc5e Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 19 Feb 2019 12:21:41 +0500 Subject: [PATCH] [IrSerializer] Cached some heavy descriptor functions --- .../DeserializeDescriptorReference.kt | 71 ++++++++++++++----- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt index 93ff0c34422..5d1c8b04345 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt @@ -13,6 +13,47 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ // 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. class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap) { + + private val cache = mutableMapOf>() + + private fun getContributedDescriptors(packageFqNameString: String): Collection = + cache.getOrPut(packageFqNameString) { + val packageFqName = packageFqNameString.let { + if (it == "") 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, + val realMembers: Map) + + private val membersCache = mutableMapOf() + + private fun getMembers(packageFqNameString: String, classFqNameString: String, + members: Collection): ClassMembers = + membersCache.getOrPut(ClassName(packageFqNameString, classFqNameString)) { + val allMembersMap = mutableMapOf() + val realMembersMap = mutableMapOf() + 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( packageFqNameString: String, classFqNameString: String, @@ -33,7 +74,7 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r val protoIndex = index val (clazz, members) = if (classFqNameString == "") { - Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors()) + Pair(null, getContributedDescriptors(packageFqNameString)) } else { val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!! 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() } - members.forEach { member -> - if (isDefaultConstructor && member is ClassConstructorDescriptor) return member + val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members) - val realMembers = - if (isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) - member.resolveFakeOverrideMaybeAbstract() - else - setOf(member) + return when { + isDefaultConstructor -> membersWithIndices.defaultConstructor - val memberIndices = realMembers.map { it.getUniqId()?.index }.filterNotNull() - - if (memberIndices.contains(protoIndex)) { - return when { - member is PropertyDescriptor && isSetter -> member.setter!! - member is PropertyDescriptor && isGetter -> member.getter!! - else -> member + else -> { + val map = if (isFakeOverride) membersWithIndices.realMembers else membersWithIndices.members + map[protoIndex]?.let { member -> + when { + member is PropertyDescriptor && isSetter -> member.setter!! + member is PropertyDescriptor && isGetter -> member.getter!! + 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}") } } \ No newline at end of file