[Commonizer] Apply interner to avoid duplicated String objects

This commit is contained in:
Dmitriy Dolovov
2020-02-16 19:14:28 +07:00
parent 667e96f971
commit adc5a55d65
2 changed files with 22 additions and 1 deletions
@@ -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<T : Any> {
private val pool = WeakHashMap<T, T>()
fun intern(value: T): T = pool.computeIfAbsent(value) { value }
}
@@ -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<KotlinType>) {
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<String>()