[Commonizer] Apply interner to avoid duplicated FqName objects

This commit is contained in:
Dmitriy Dolovov
2020-02-16 20:25:48 +07:00
parent adc5a55d65
commit 47d091702b
8 changed files with 22 additions and 14 deletions
@@ -6,12 +6,13 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.* import org.jetbrains.kotlin.resolve.constants.*
class CirAnnotation(original: AnnotationDescriptor) { class CirAnnotation(original: AnnotationDescriptor) {
val fqName: FqName = original.fqName ?: error("Annotation with no FQ name: ${original::class.java}, $original") val fqName: FqName = original.fqName?.intern() ?: error("Annotation with no FQ name: ${original::class.java}, $original")
val allValueArguments: Map<Name, ConstantValue<*>> = original.allValueArguments val allValueArguments: Map<Name, ConstantValue<*>> = original.allValueArguments
init { init {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -65,7 +66,7 @@ class CirClassImpl(original: ClassDescriptor) : CirClass {
override val annotations = original.annotations.map(::CirAnnotation) override val annotations = original.annotations.map(::CirAnnotation)
override val name = original.name override val name = original.name
override val typeParameters = original.declaredTypeParameters.map(::CirTypeParameterImpl) override val typeParameters = original.declaredTypeParameters.map(::CirTypeParameterImpl)
override val companion = original.companionObjectDescriptor?.fqNameSafe override val companion = original.companionObjectDescriptor?.fqNameSafe?.intern()
override val kind = original.kind override val kind = original.kind
override val modality = original.modality override val modality = original.modality
override val visibility = original.visibility override val visibility = original.visibility
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKi
import org.jetbrains.kotlin.descriptors.commonizer.utils.declarationDescriptor import org.jetbrains.kotlin.descriptors.commonizer.utils.declarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqName import org.jetbrains.kotlin.descriptors.commonizer.utils.fqName
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqNameWithTypeParameters import org.jetbrains.kotlin.descriptors.commonizer.utils.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -52,7 +53,7 @@ class CirSimpleType(original: SimpleType) : CirType() {
annotations = abbreviation.annotations.map(::CirAnnotation) annotations = abbreviation.annotations.map(::CirAnnotation)
kind = CirSimpleTypeKind.determineKind(abbreviation.declarationDescriptor) kind = CirSimpleTypeKind.determineKind(abbreviation.declarationDescriptor)
fqName = abbreviation.fqName fqName = abbreviation.fqNameInterned
arguments = abbreviation.arguments.map(::CirTypeProjection) arguments = abbreviation.arguments.map(::CirTypeProjection)
isMarkedNullable = abbreviation.isMarkedNullable isMarkedNullable = abbreviation.isMarkedNullable
isDefinitelyNotNullType = abbreviation.isDefinitelyNotNullType isDefinitelyNotNullType = abbreviation.isDefinitelyNotNullType
@@ -85,7 +86,7 @@ enum class CirSimpleTypeKind {
} }
data class CirTypeConstructorId(val fqName: FqName, val numberOfTypeParameters: Int) { data class CirTypeConstructorId(val fqName: FqName, val numberOfTypeParameters: Int) {
constructor(type: SimpleType) : this(type.fqName, type.constructor.parameters.size) constructor(type: SimpleType) : this(type.fqNameInterned, type.constructor.parameters.size)
} }
class CirTypeProjection(original: TypeProjection) { class CirTypeProjection(original: TypeProjection) {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.core.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode.ClassifiersCacheImpl import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -100,7 +101,7 @@ internal fun buildClassNode(
recursionMarker = CirClassRecursionMarker, recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode nodeProducer = ::CirClassNode
).also { node -> ).also { node ->
classes.firstNonNull().fqNameSafe.let { fqName -> classes.firstNonNull().fqNameSafe.intern().let { fqName ->
node.fqName = fqName node.fqName = fqName
cacheRW.classes.putSafe(fqName, node) cacheRW.classes.putSafe(fqName, node)
} }
@@ -132,7 +133,7 @@ internal fun buildTypeAliasNode(
recursionMarker = CirClassRecursionMarker, recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirTypeAliasNode nodeProducer = ::CirTypeAliasNode
).also { node -> ).also { node ->
typeAliases.firstNonNull().fqNameSafe.let { fqName -> typeAliases.firstNonNull().fqNameSafe.intern().let { fqName ->
node.fqName = fqName node.fqName = fqName
cacheRW.typeAliases.putSafe(fqName, node) cacheRW.typeAliases.putSafe(fqName, node)
} }
@@ -28,7 +28,7 @@ internal fun mergeModules(
modules.forEachIndexed { index, module -> modules.forEachIndexed { index, module ->
module?.collectNonEmptyPackageMemberScopes { packageFqName, memberScope -> module?.collectNonEmptyPackageMemberScopes { packageFqName, memberScope ->
packageMemberScopesMap[packageFqName][index] = memberScope packageMemberScopesMap[packageFqName.intern()][index] = memberScope
} }
} }
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.utils
import java.util.WeakHashMap import java.util.WeakHashMap
internal class Interner<T : Any> { internal class NonThreadSafeInterner<T : Any> {
private val pool = WeakHashMap<T, T>() private val pool = WeakHashMap<T, T>()
fun intern(value: T): T = pool.computeIfAbsent(value) { value } fun intern(value: T): T = pool.computeIfAbsent(value) { value }
@@ -17,8 +17,10 @@ import kotlin.collections.HashSet
internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor
get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor")) get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor"))
internal inline val KotlinType.fqName: FqName internal inline val KotlinType.fqNameInterned: FqName
get() = declarationDescriptor.fqNameSafe get() = declarationDescriptor.fqNameSafe.intern()
internal fun FqName.intern(): FqName = fqNameInterner.intern(this)
internal val KotlinType.fqNameWithTypeParameters: String internal val KotlinType.fqNameWithTypeParameters: String
get() { get() {
@@ -27,7 +29,7 @@ internal val KotlinType.fqNameWithTypeParameters: String
} }
private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, exploredTypeParameters: MutableSet<KotlinType>) { private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, exploredTypeParameters: MutableSet<KotlinType>) {
append(type.fqName) append(type.fqNameInterned)
val typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type) val typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type)
if (typeParameterDescriptor != null) { if (typeParameterDescriptor != null) {
@@ -70,4 +72,6 @@ private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, explor
} }
// dedicated to hold unique entries of "fqNameWithTypeParameters" // dedicated to hold unique entries of "fqNameWithTypeParameters"
private val stringInterner = Interner<String>() private val stringInterner = NonThreadSafeInterner<String>()
private val fqNameInterner = NonThreadSafeInterner<FqName>()
@@ -426,8 +426,8 @@ internal class ComparingDeclarationsVisitor(
context.nextLevel("Unwrapped/unabbreviated type annotations") context.nextLevel("Unwrapped/unabbreviated type annotations")
) )
val expectedFqName = expectedUnwrapped.fqName val expectedFqName = expectedUnwrapped.fqNameInterned
val actualFqName = actualUnwrapped.fqName val actualFqName = actualUnwrapped.fqNameInterned
context.assertEquals(expectedFqName, actualFqName, "type FQN") context.assertEquals(expectedFqName, actualFqName, "type FQN")