From 05af72dc7a40db5c490b3c98789323551b216441 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 26 Apr 2016 16:42:49 +0300 Subject: [PATCH] Optimize class lookups in DeserializedPackageMemberScope Do not try to load classes (and litter in ClassDeserializer#classes cache with unsuccessful requests) which the deserialized scope knows nothing about. This is possible because deserialized scopes have the full list of their class names --- .../BuiltInFictitiousFunctionClassFactory.kt | 7 +++++++ .../deserialization/ClassDescriptorFactory.kt | 6 ++++++ .../DeserializedClassDescriptor.kt | 6 ++++-- .../descriptors/DeserializedMemberScope.kt | 9 +-------- .../DeserializedPackageMemberScope.kt | 19 ++++++++++++------- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt index 5736598864e..cb66beb854a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.storage.StorageManager @@ -63,6 +64,12 @@ class BuiltInFictitiousFunctionClassFactory( } } + override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean { + val string = name.asString() + return (string.startsWith("Function") || string.startsWith("KFunction")) // an optimization + && parseClassName(string, packageFqName) != null + } + override fun createClass(classId: ClassId): ClassDescriptor? { if (classId.isLocal || classId.isNestedClass) return null diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt index bda2c5b05fe..cde4ff91f77 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt @@ -18,11 +18,17 @@ package org.jetbrains.kotlin.serialization.deserialization import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name interface ClassDescriptorFactory { + fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean + fun createClass(classId: ClassId): ClassDescriptor? object EMPTY : ClassDescriptorFactory { + override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean = false + override fun createClass(classId: ClassId): ClassDescriptor? = null } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index ec92ac6b49d..39773dbfa23 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -245,8 +245,10 @@ class DeserializedClassDescriptor( } } - override fun getClassDescriptor(name: Name): ClassifierDescriptor? = - classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.nestedClasses?.findNestedClass(name) + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { + recordLookup(name, location) + return classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.nestedClasses?.findNestedClass(name) + } override fun addClassDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { result.addAll(classDescriptor.nestedClasses?.all().orEmpty()) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt index eb5acf26b3f..9336a125e6a 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt @@ -103,13 +103,6 @@ abstract class DeserializedMemberScope protected constructor( return properties.invoke(name) } - override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { - recordLookup(name, location) - return getClassDescriptor(name) - } - - protected abstract fun getClassDescriptor(name: Name): ClassifierDescriptor? - protected abstract fun addClassDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) protected fun computeDescriptors( @@ -185,7 +178,7 @@ abstract class DeserializedMemberScope protected constructor( p.println("}") } - private fun recordLookup(name: Name, from: LookupLocation) { + protected fun recordLookup(name: Name, from: LookupLocation) { c.components.lookupTracker.record(from, c.containingDeclaration, name) } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt index bd9161953a0..8c332c88c3c 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt @@ -16,10 +16,7 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.SourceElement +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId @@ -51,9 +48,17 @@ open class DeserializedPackageMemberScope( override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = computeDescriptors(kindFilter, nameFilter, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) - override fun getClassDescriptor(name: Name): ClassDescriptor? = - if (SpecialNames.isSafeIdentifier(name)) c.components.deserializeClass(ClassId(packageFqName, name)) - else null + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { + if (SpecialNames.isSafeIdentifier(name) && + (name in classNames || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name))) { + recordLookup(name, location) + return getClassDescriptor(name) + } + return null + } + + private fun getClassDescriptor(name: Name): ClassDescriptor? = + c.components.deserializeClass(ClassId(packageFqName, name)) override fun addClassDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { for (className in classNames) {