From adc5a55d65304fc093eeadfb185eb323e4022bb3 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Sun, 16 Feb 2020 19:14:28 +0700 Subject: [PATCH] [Commonizer] Apply interner to avoid duplicated String objects --- .../descriptors/commonizer/utils/Interner.kt | 14 ++++++++++++++ .../kotlin/descriptors/commonizer/utils/type.kt | 9 ++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/Interner.kt diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/Interner.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/Interner.kt new file mode 100644 index 00000000000..127193bc19d --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/Interner.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.utils + +import java.util.WeakHashMap + +internal class Interner { + private val pool = WeakHashMap() + + fun intern(value: T): T = pool.computeIfAbsent(value) { value } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt index 5c83760b915..759a6ff56ea 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.makeNotNullable +import kotlin.collections.HashSet internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor")) @@ -20,7 +21,10 @@ internal inline val KotlinType.fqName: FqName get() = declarationDescriptor.fqNameSafe internal val KotlinType.fqNameWithTypeParameters: String - get() = buildString { buildFqNameWithTypeParameters(this@fqNameWithTypeParameters, HashSet()) } + get() { + // use of interner saves up to 95% of duplicates + return stringInterner.intern(buildString { buildFqNameWithTypeParameters(this@fqNameWithTypeParameters, HashSet()) }) + } private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, exploredTypeParameters: MutableSet) { append(type.fqName) @@ -64,3 +68,6 @@ private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, explor if (type.isMarkedNullable) append("?") } + +// dedicated to hold unique entries of "fqNameWithTypeParameters" +private val stringInterner = Interner()