From 8dd5c2f895d9ca999b685dea2bab8a0170d17dc9 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 29 Nov 2017 12:26:26 +0300 Subject: [PATCH] Avoid serlialization for unrelated Java source-based classes There is no need to track unknown (not being tracked before) classes content of which we didn't request #KT-17621 Fixed --- .../kotlin/incremental/IncrementalJvmCache.kt | 5 +++++ .../kotlin/incremental/JavaClassesTrackerImpl.kt | 13 ++++++++++++- .../lazy/descriptors/LazyJavaClassDescriptor.kt | 5 +++++ .../load/java/lazy/descriptors/LazyJavaScope.kt | 2 ++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt index eb2b44f4111..5fdc6481773 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt @@ -194,6 +194,11 @@ open class IncrementalJvmCache( javaSourcesProtoMap[jvmClassName.internalName] == null } + fun isJavaClassAlreadyInCache(classId: ClassId): Boolean { + val jvmClassName = JvmClassName.byClassId(classId) + return javaSourcesProtoMap[jvmClassName.internalName] != null + } + fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) { val dirtyClasses = dirtyOutputClassesMap .getDirtyOutputClasses() diff --git a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt index a491ef277b2..88a4c70dec3 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite import org.jetbrains.kotlin.resolve.descriptorUtil.classId @@ -31,12 +32,15 @@ import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf +import org.jetbrains.kotlin.util.PerformanceCounter import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.sure import java.io.DataInput import java.io.DataOutput import java.io.File +val CONVERTING_JAVA_CLASSES_TO_PROTO = PerformanceCounter.create("Converting Java sources to proto") + class JavaClassesTrackerImpl(private val cache: IncrementalJvmCache) : JavaClassesTracker { private val classToSourceSerialized: MutableMap = hashMapOf() @@ -61,10 +65,17 @@ class JavaClassesTrackerImpl(private val cache: IncrementalJvmCache) : JavaClass } for (classDescriptor in classDescriptors.toList()) { - classToSourceSerialized[classDescriptor.classId!!] = + val classId = classDescriptor.classId!! + if (cache.isJavaClassAlreadyInCache(classId) || classDescriptor.wasContentRequested()) { + classToSourceSerialized[classId] = CONVERTING_JAVA_CLASSES_TO_PROTO.time { classDescriptor.convertToProto() + } + } } } + + private fun JavaClassDescriptor.wasContentRequested() = + this.safeAs()?.wasScopeContentRequested() != false } private val JavaClassDescriptor.javaSourceFile: File? diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 8303a709939..0ac09c45023 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -156,6 +156,11 @@ class LazyJavaClassDescriptor( } } + // Checks if any part of compiler has requested scope content + // It's necessary for IC to figure out if there is a need to track symbols in the class + fun wasScopeContentRequested() = + getUnsubstitutedMemberScope().wasContentRequested() || staticScope.wasContentRequested() + override fun getSealedSubclasses(): Collection = emptyList() override fun toString() = "Lazy Java class ${this.fqNameUnsafe}" diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index a81e46d39ae..d683e87b631 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -67,6 +67,8 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS protected val declaredMemberIndex: NotNullLazyValue = c.storageManager.createLazyValue { computeMemberIndex() } + fun wasContentRequested() = declaredMemberIndex.isComputed() + protected abstract fun computeMemberIndex(): DeclaredMemberIndex // Fake overrides, values()/valueOf(), etc.