Deduplicate strings, Names and simple types, empty arrays and lists
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt
index e5aa1a7..3279e2c 100644
--- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt
+++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt
@@ -20,10 +20,7 @@
 import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
 import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
 import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.ir.util.SymbolTable
-import org.jetbrains.kotlin.ir.util.getPropertyGetter
-import org.jetbrains.kotlin.ir.util.getPropertySetter
-import org.jetbrains.kotlin.ir.util.isOverridableOrOverrides
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.scopes.MemberScope
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt
index 9f1064e..d7b4766 100644
--- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt
+++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt
@@ -5,10 +5,7 @@
 
 package org.jetbrains.kotlin.ir.backend.js.ic
 
-import org.jetbrains.kotlin.backend.common.serialization.IdSignatureDeserializer
-import org.jetbrains.kotlin.backend.common.serialization.IrLibraryBytesSource
-import org.jetbrains.kotlin.backend.common.serialization.IrLibraryFileFromBytes
-import org.jetbrains.kotlin.backend.common.serialization.codedInputStream
+import org.jetbrains.kotlin.backend.common.serialization.*
 import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile
 import org.jetbrains.kotlin.library.KotlinLibrary
 import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
@@ -25,6 +22,7 @@
             add(KotlinSourceFile(fileProto.fileEntry.name))
         }
 
+        val internationService = DefaultIrInternationService()
         val deserializers = buildMapUntil(filesCount) {
             put(files[it], IdSignatureDeserializer(IrLibraryFileFromBytes(object : IrLibraryBytesSource() {
                 private fun err(): Nothing = icError("Not supported")
@@ -34,7 +32,7 @@
                 override fun string(index: Int): ByteArray = library.string(index, it)
                 override fun body(index: Int): ByteArray = err()
                 override fun debugInfo(index: Int): ByteArray? = null
-            }), null))
+            }), null, internationService))
         }
 
         sourceFiles = files
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt
index 2d9a28e..485bafc 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt
@@ -12,10 +12,7 @@
 import org.jetbrains.kotlin.ir.symbols.*
 import org.jetbrains.kotlin.ir.types.IrType
 import org.jetbrains.kotlin.ir.types.typeWith
-import org.jetbrains.kotlin.ir.util.isImmutable
-import org.jetbrains.kotlin.ir.util.parentAsClass
-import org.jetbrains.kotlin.ir.util.primaryConstructor
-import org.jetbrains.kotlin.ir.util.render
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
 
 val IrBuilderWithScope.parent get() = scope.getLocalDeclarationParent()
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt
index ac67388..b7377a3 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt
@@ -583,7 +583,7 @@
     override fun getSource() = owner.source
 
     override fun getConstructors() =
-        owner.declarations.filterIsInstance<IrConstructor>().filter { !it.origin.isSynthetic }.map { it.toIrBasedDescriptor() }.toList()
+        owner.declarations.filterIsInstance<IrConstructor>().filter { !it.origin.isSynthetic }.map { it.toIrBasedDescriptor() }
 
     private val _defaultType: SimpleType by lazy {
         TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope, KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt
index b33e91b..125fecd 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltinFunctionDescriptor.kt
@@ -20,6 +20,7 @@
 import org.jetbrains.kotlin.descriptors.annotations.Annotations
 import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorNonRootImpl
 import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.constants.ConstantValue
 import org.jetbrains.kotlin.types.KotlinType
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallEmptyArrays.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallEmptyArrays.kt
new file mode 100644
index 0000000..e67acb1
--- /dev/null
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallEmptyArrays.kt
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2010-2023 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.ir.expressions.impl
+
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.types.IrType
+
+object IrCallEmptyArrays {
+    val types = arrayOfNulls<IrType?>(0)
+    val expressions = arrayOfNulls<IrExpression?>(0)
+}
\ No newline at end of file
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt
index 2d580ac..8e65593 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt
@@ -38,9 +38,11 @@
     override val superQualifierSymbol: IrClassSymbol? = null
 ) : IrCall() {
 
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
-    override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
+    override val argumentsByParameterIndex: Array<IrExpression?> =
+        if (valueArgumentsCount == 0) IrCallEmptyArrays.expressions else arrayOfNulls(valueArgumentsCount)
 
     override var contextReceiversCount = 0
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt
index 911db07..d1ea02d 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt
@@ -26,9 +26,11 @@
     override val origin: IrStatementOrigin? = null,
     override val source: SourceElement = SourceElement.NO_SOURCE
 ) : IrConstructorCall() {
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
-    override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
+    override val argumentsByParameterIndex: Array<IrExpression?> =
+        if (valueArgumentsCount == 0) IrCallEmptyArrays.expressions else arrayOfNulls(valueArgumentsCount)
 
     override var contextReceiversCount = 0
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt
index c61c9f1..9d7b55a 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt
@@ -36,9 +36,11 @@
     override val origin: IrStatementOrigin?
         get() = null
 
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
-    override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
+    override val argumentsByParameterIndex: Array<IrExpression?> =
+        if (valueArgumentsCount == 0) IrCallEmptyArrays.expressions else arrayOfNulls(valueArgumentsCount)
 
     override var contextReceiversCount = 0
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt
index 2a3a8b3..f0ef1a7 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt
@@ -34,9 +34,11 @@
     override val origin: IrStatementOrigin?
         get() = null
 
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
-    override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
+    override val argumentsByParameterIndex: Array<IrExpression?> =
+        if (valueArgumentsCount == 0) IrCallEmptyArrays.expressions else arrayOfNulls(valueArgumentsCount)
 
     override var contextReceiversCount = 0
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt
index a4d89cf..b0c7e6b 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt
@@ -37,9 +37,11 @@
     override val referencedName: Name
         get() = symbol.owner.name
 
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
-    override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
+    override val argumentsByParameterIndex: Array<IrExpression?> =
+        if (valueArgumentsCount == 0) IrCallEmptyArrays.expressions else arrayOfNulls(valueArgumentsCount)
 
     companion object {
         @ObsoleteDescriptorBasedAPI
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt
index e2a1bc5f..de78391 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt
@@ -35,7 +35,7 @@
     override val setter: IrSimpleFunctionSymbol?,
     override val origin: IrStatementOrigin? = null,
 ) : IrLocalDelegatedPropertyReference() {
-    override val typeArgumentsByIndex: Array<IrType?> = emptyArray()
+    override val typeArgumentsByIndex: Array<IrType?> = IrCallEmptyArrays.types
 
     override val argumentsByParameterIndex: Array<IrExpression?>
         get() = throw UnsupportedOperationException("Property reference $symbol has no value arguments")
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt
index 6a9a66b..4cf97e7 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt
@@ -36,7 +36,8 @@
     override val setter: IrSimpleFunctionSymbol?,
     override val origin: IrStatementOrigin? = null,
 ) : IrPropertyReference() {
-    override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
+    override val typeArgumentsByIndex: Array<IrType?> =
+        if (typeArgumentsCount == 0) IrCallEmptyArrays.types else arrayOfNulls(typeArgumentsCount)
 
     override val argumentsByParameterIndex: Array<IrExpression?>
         get() = throw UnsupportedOperationException("Property reference $symbol has no value arguments")
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt
index a7488a1..f5aca76 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt
@@ -5,8 +5,8 @@
 
 package org.jetbrains.kotlin.ir.types
 
-import org.jetbrains.kotlin.ir.IrBuiltIns
 import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.types.model.TypeConstructorMarker
 
 class IrTypeSystemContextWithAdditionalAxioms(
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt
index c97b7913..1c41a30 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt
@@ -8,7 +8,7 @@
 import org.jetbrains.kotlin.ir.IrBuiltIns
 import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
 import org.jetbrains.kotlin.ir.types.impl.*
-import org.jetbrains.kotlin.ir.util.render
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.types.Variance
 import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
index e69884d..626fb99 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt
@@ -610,7 +610,7 @@
                 else -> null
             }
     }
-    return result
+    return result.ifEmpty { emptyList() }
 }
 
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt
index 34e2aa8..e769f6c 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt
@@ -10,6 +10,7 @@
 import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
 import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
 import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlin.types.Variance
 
@@ -110,8 +111,8 @@
         kotlinType,
         classifier ?: throw AssertionError("Classifier not provided"),
         nullability,
-        arguments,
-        annotations,
+        arguments.ifEmpty { emptyList() },
+        annotations.ifEmpty { emptyList() },
         abbreviation
     )
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt
index 815726c..38690ed 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt
@@ -175,7 +175,7 @@
     get() = IrSimpleTypeImpl(
         this,
         SimpleTypeNullability.NOT_SPECIFIED,
-        arguments = owner.typeConstructorParameters.map { IrStarProjectionImpl }.toList(),
+        arguments = owner.typeConstructorParameters.map { IrStarProjectionImpl }.toList().ifEmpty { emptyList() },
         annotations = emptyList()
     )
 
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/CollectionUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/CollectionUtils.kt
new file mode 100644
index 0000000..9497b5e
--- /dev/null
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/CollectionUtils.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2023 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.ir.util
+
+inline fun <T, R> Collection<T>.map(transform: (T) -> R): List<R> {
+    if (isEmpty()) return emptyList()
+    return mapTo(ArrayList(size), transform)
+}
+
+inline fun <T, R : Any> Collection<T>.mapNotNull(transform: (T) -> R?): List<R> {
+    if (isEmpty()) return emptyList()
+    return mapNotNullTo(ArrayList(size), transform)
+}
+
+public inline fun <T> Collection<T>.filter(predicate: (T) -> Boolean): List<T> {
+    if (isEmpty()) return emptyList()
+    return filterTo(ArrayList(), predicate)
+}
+
+public inline fun <T> Collection<T>.filterNot(predicate: (T) -> Boolean): List<T> {
+    if (isEmpty()) return emptyList()
+    return filterNotTo(ArrayList(), predicate)
+}
\ No newline at end of file
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt
index 40da205..4588555 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt
@@ -27,14 +27,15 @@
     override val klib: IrLibrary,
     override val strategyResolver: (String) -> DeserializationStrategy,
     libraryAbiVersion: KotlinAbiVersion,
+    private val internationService: IrInternationService,
     private val containsErrorCode: Boolean = false
 ) : IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) {
 
-    private val fileToDeserializerMap = mutableMapOf<IrFile, IrFileDeserializer>()
+    private val fileToDeserializerMap = hashMapOf<IrFile, IrFileDeserializer>()
 
     private val moduleDeserializationState = ModuleDeserializationState()
 
-    protected val moduleReversedFileIndex = mutableMapOf<IdSignature, FileDeserializationState>()
+    protected val moduleReversedFileIndex = hashMapOf<IdSignature, FileDeserializationState>()
 
     override val moduleDependencies by lazy {
         moduleDescriptor.allDependencyModules
@@ -45,9 +46,7 @@
     override fun fileDeserializers(): Collection<IrFileDeserializer> {
         return fileToDeserializerMap.values.filterNot { strategyResolver(it.file.fileEntry.name).onDemand }
     }
-
-    protected lateinit var fileDeserializationStates: List<FileDeserializationState>
-
+    
     override fun init(delegate: IrModuleDeserializer) {
         val fileCount = klib.fileCount()
 
@@ -64,8 +63,6 @@
                 moduleFragment.files.add(file)
         }
 
-        this.fileDeserializationStates = fileDeserializationStates
-
         fileToDeserializerMap.values.forEach { it.symbolDeserializer.deserializeExpectActualMapping() }
     }
 
@@ -128,7 +125,8 @@
             fileStrategy.needBodies,
             allowErrorNodes,
             fileStrategy.inlineBodies,
-            moduleDeserializer
+            moduleDeserializer,
+            internationService
         )
 
         fileToDeserializerMap[file] = fileDeserializationState.fileDeserializer
@@ -197,6 +195,7 @@
     }
 }
 
+
 fun IrModuleDeserializer.findModuleDeserializerForTopLevelId(idSignature: IdSignature): IrModuleDeserializer? {
     if (idSignature in this) return this
     return moduleDependencies.firstOrNull { idSignature in it }
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt
index ea16cfa..8271591 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt
@@ -32,7 +32,7 @@
 ) {
     val publicIdSignatureComputer = PublicIdSignatureComputer(mangler)
 
-    protected val table = mutableMapOf<IrDeclaration, IdSignature>()
+    protected val table = hashMapOf<IrDeclaration, IdSignature>()
 
     constructor(mangler: KotlinMangler.IrMangler) : this(mangler, IdSignatureClashTracker.DEFAULT_TRACKER)
 
@@ -53,7 +53,7 @@
 }
 
 open class DeclarationTable(globalTable: GlobalDeclarationTable) {
-    protected val table = mutableMapOf<IrDeclaration, IdSignature>()
+    protected val table = hashMapOf<IrDeclaration, IdSignature>()
     protected open val globalDeclarationTable: GlobalDeclarationTable = globalTable
     // TODO: we need to disentangle signature construction with declaration tables.
     open val signaturer: IdSignatureSerializer = IdSignatureSerializer(globalTable.publicIdSignatureComputer, this)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt
index 630972d..4585cf1 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt
@@ -13,7 +13,7 @@
 import org.jetbrains.kotlin.resolve.multiplatform.findExpects
 
 class ExpectActualTable(val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>) {
-    val table = mutableMapOf<DeclarationDescriptor, IrSymbol>()
+    val table = hashMapOf<DeclarationDescriptor, IrSymbol>()
 
     private fun IrElement.recordActuals(rightHandSide: Map<DeclarationDescriptor, IrSymbol>, inModule: ModuleDescriptor) {
         this.acceptVoid(object : IrElementVisitorVoid {
@@ -62,7 +62,7 @@
     }
 
     private fun IrDeclaration.recordRightHandSide(): Map<DeclarationDescriptor, IrSymbol> {
-        val rightHandSide = mutableMapOf<DeclarationDescriptor, IrSymbol>()
+        val rightHandSide = hashMapOf<DeclarationDescriptor, IrSymbol>()
 
         this.acceptVoid(object : IrElementVisitorVoid {
             override fun visitElement(element: IrElement) {
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt
index 141295f..116aa86 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt
@@ -5,7 +5,6 @@
 
 package org.jetbrains.kotlin.backend.common.serialization
 
-import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
 import org.jetbrains.kotlin.ir.util.IdSignature
 import org.jetbrains.kotlin.ir.util.IdSignature.FileSignature
 import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
@@ -18,7 +17,8 @@
 
 class IdSignatureDeserializer(
     private val libraryFile: IrLibraryFile,
-    private val fileSignature: FileSignature?
+    private val fileSignature: FileSignature?,
+    private val internationService: IrInternationService
 ) {
 
     private fun loadSignatureProto(index: Int): ProtoIdSignature {
@@ -35,8 +35,8 @@
     }
 
     private fun deserializePublicIdSignature(proto: ProtoCommonIdSignature): IdSignature.CommonSignature {
-        val pkg = libraryFile.deserializeFqName(proto.packageFqNameList)
-        val cls = libraryFile.deserializeFqName(proto.declarationFqNameList)
+        val pkg = internationService.string(libraryFile.deserializeFqName(proto.packageFqNameList))
+        val cls = internationService.string(libraryFile.deserializeFqName(proto.declarationFqNameList))
         val memberId = if (proto.hasMemberUniqId()) proto.memberUniqId else null
 
         return IdSignature.CommonSignature(pkg, cls, memberId, proto.flags)
@@ -49,8 +49,9 @@
         val hash = proto.accessorHashId
         val mask = proto.flags
 
+        val declarationFqName = internationService.string("${propertySignature.declarationFqName}.$name")
         val accessorSignature =
-            IdSignature.CommonSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask)
+            IdSignature.CommonSignature(propertySignature.packageFqName, declarationFqName, hash, mask)
 
         return IdSignature.AccessorSignature(propertySignature, accessorSignature)
     }
@@ -70,7 +71,7 @@
     }
 
     private fun deserializeLocalIdSignature(proto: ProtoLocalSignature): IdSignature.LocalSignature {
-        val localFqn = libraryFile.deserializeFqName(proto.localFqNameList)
+        val localFqn = internationService.string(libraryFile.deserializeFqName(proto.localFqNameList))
         val localHash = if (proto.hasLocalHash()) proto.localHash else null
         val description = if (proto.hasDebugInfo()) libraryFile.debugInfo(proto.debugInfo) else null
         return IdSignature.LocalSignature(localFqn, localHash, description)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt
index 6da9c44..e2e81ea 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt
@@ -104,7 +104,7 @@
     icReaderFactory: (IrLibrary) -> IrModuleDeserializer) :
     IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) {
 
-    private val dirtyDeclarations = mutableMapOf<IdSignature, IrSymbol>()
+    private val dirtyDeclarations = hashMapOf<IdSignature, IrSymbol>()
     private val icKlib = ICKotlinLibrary(icData)
 
     private val icDeserializer: IrModuleDeserializer = icReaderFactory(icKlib)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt
index f8cb598..a55d9e4c 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt
@@ -20,6 +20,7 @@
 import org.jetbrains.kotlin.ir.symbols.*
 import org.jetbrains.kotlin.ir.types.*
 import org.jetbrains.kotlin.ir.types.impl.*
+import org.jetbrains.kotlin.ir.util.map
 import org.jetbrains.kotlin.ir.util.parentAsClass
 import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock
 import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody
@@ -78,7 +79,7 @@
     private val declarationDeserializer: IrDeclarationDeserializer,
 ) {
 
-    private val fileLoops = mutableMapOf<Int, IrLoop>()
+    private val fileLoops = hashMapOf<Int, IrLoop>()
 
     private fun deserializeLoopHeader(loopIndex: Int, loopBuilder: () -> IrLoop): IrLoop =
         fileLoops.getOrPut(loopIndex, loopBuilder)
@@ -88,13 +89,7 @@
         start: Int, end: Int
     ): IrBlockBody {
 
-        val statements = mutableListOf<IrStatement>()
-
-        val statementProtos = proto.statementList
-        statementProtos.forEach {
-            statements.add(deserializeStatement(it) as IrStatement)
-        }
-
+        val statements = proto.statementList.map { deserializeStatement(it) as IrStatement }
         return irFactory.createBlockBody(start, end, statements)
     }
 
@@ -160,14 +155,14 @@
 
     private fun deserializeMemberAccessCommon(access: IrMemberAccessExpression<*>, proto: ProtoMemberAccessCommon) {
 
-        proto.valueArgumentList.mapIndexed { i, arg ->
+        proto.valueArgumentList.forEachIndexed { i, arg ->
             if (arg.hasExpression()) {
                 val expr = deserializeExpression(arg.expression)
                 access.putValueArgument(i, expr)
             }
         }
 
-        proto.typeArgumentList.mapIndexed { i, arg ->
+        proto.typeArgumentList.forEachIndexed { i, arg ->
             access.putTypeArgument(i, declarationDeserializer.deserializeNullableIrType(arg))
         }
 
@@ -208,17 +203,20 @@
                 val klass = constructorCall.symbol.owner.parentAsClass
 
                 val typeParameters = extractTypeParameters(klass)
+                if (typeParameters.isEmpty()) {
+                    return IrSimpleTypeBuilder().apply {
+                        classifier = klass.symbol
+                    }.buildSimpleType()
+                }
 
                 val typeArguments = ArrayList<IrTypeArgument>(typeParameters.size)
                 val typeParameterSymbols = ArrayList<IrTypeParameterSymbol>(typeParameters.size)
                 val rawType = with(IrSimpleTypeBuilder()) {
-                    arguments = typeParameters.run {
-                        mapTo(ArrayList(size)) {
-                            classifier = it.symbol
-                            buildTypeProjection()
-                        }
-                    }
                     classifier = klass.symbol
+                    arguments = typeParameters.map {
+                        classifier = it.symbol
+                        buildTypeProjection()
+                    }
                     buildSimpleType()
                 }
 
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt
index ad3c12d..1042319 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt
@@ -74,26 +74,26 @@
     private val platformFakeOverrideClassFilter: FakeOverrideClassFilter,
     private val fakeOverrideBuilder: FakeOverrideBuilder,
     private val compatibilityMode: CompatibilityMode,
+    private val internationService: IrInternationService,
 ) {
 
     private val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, libraryFile, this)
 
+    private fun deserializeString(index: Int): String {
+        return internationService.string(libraryFile.string(index))
+    }
+
     private fun deserializeName(index: Int): Name {
-        val name = libraryFile.string(index)
-        return Name.guessByFirstCharacter(name)
+        return internationService.name(deserializeString(index))
     }
 
-    private val irTypeCache = mutableMapOf<Int, IrType>()
-
-    private fun loadTypeProto(index: Int): ProtoType {
-        return libraryFile.type(index)
-    }
+    private val irTypeCache = hashMapOf<Int, IrType>()
 
     fun deserializeNullableIrType(index: Int): IrType? = if (index == -1) null else deserializeIrType(index)
 
     fun deserializeIrType(index: Int): IrType {
         return irTypeCache.getOrPut(index) {
-            val typeData = loadTypeProto(index)
+            val typeData = libraryFile.type(index)
             deserializeIrTypeData(typeData)
         }
     }
@@ -123,14 +123,17 @@
 
         val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
         val annotations = deserializeAnnotations(proto.annotationList)
+        val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
 
-        return IrSimpleTypeImpl(
-            null,
-            symbol,
-            deserializeSimpleTypeNullability(proto.nullability),
-            arguments,
-            annotations,
-            if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
+        return internationService.simpleType(
+            IrSimpleTypeImpl(
+                null,
+                symbol,
+                deserializeSimpleTypeNullability(proto.nullability),
+                arguments,
+                annotations,
+                abbreviation
+            )
         )
     }
 
@@ -139,14 +142,17 @@
 
         val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
         val annotations = deserializeAnnotations(proto.annotationList)
+        val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
 
-        return IrSimpleTypeImpl(
-            null,
-            symbol,
-            SimpleTypeNullability.fromHasQuestionMark(proto.hasQuestionMark),
-            arguments,
-            annotations,
-            if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
+        return internationService.simpleType(
+            IrSimpleTypeImpl(
+                null,
+                symbol,
+                SimpleTypeNullability.fromHasQuestionMark(proto.hasQuestionMark),
+                arguments,
+                annotations,
+                abbreviation
+            )
         )
     }
 
@@ -200,7 +206,7 @@
         }
 
     // Delegating symbol maps to it's delegate only inside the declaration the symbol belongs to.
-    private val delegatedSymbolMap = mutableMapOf<IrSymbol, IrSymbol>()
+    private val delegatedSymbolMap = hashMapOf<IrSymbol, IrSymbol>()
 
     internal fun deserializeIrSymbol(code: Long): IrSymbol {
         return symbolDeserializer.deserializeIrSymbol(code)
@@ -444,6 +450,9 @@
     }
 
     private fun deserializeTypeParameters(protos: List<ProtoTypeParameter>, isGlobal: Boolean): List<IrTypeParameter> {
+        if (protos.size == 0)
+            return emptyList()
+        
         // NOTE: fun <C : MutableCollection<in T>, T : Any> Array<out T?>.filterNotNullTo(destination: C): C
         val result = ArrayList<IrTypeParameter>(protos.size)
         for (index in protos.indices) {
@@ -459,6 +468,9 @@
     }
 
     private fun deserializeValueParameters(protos: List<ProtoValueParameter>): List<IrValueParameter> {
+        if (protos.size == 0)
+            return emptyList()
+
         val result = ArrayList<IrValueParameter>(protos.size)
 
         for (i in protos.indices) {
@@ -559,7 +571,10 @@
             block(checkSymbolType(symbol), idSig, startOffset, endOffset, origin, fcode).usingParent {
                 typeParameters = deserializeTypeParameters(proto.typeParameterList, false)
                 val nameType = BinaryNameAndType.decode(proto.nameType)
-                returnType = deserializeIrType(nameType.typeIndex)
+                returnType = when (val type = deserializeIrType(nameType.typeIndex)) {
+                    is IrSimpleType -> internationService.simpleType(type)
+                    else -> type
+                }
 
                 withBodyGuard {
                     valueParameters = deserializeValueParameters(proto.valueParameterList)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt
index b45ace6..a872ac9 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt
@@ -64,7 +64,8 @@
     deserializeBodies: Boolean,
     allowErrorNodes: Boolean,
     deserializeInlineFunctions: Boolean,
-    moduleDeserializer: IrModuleDeserializer
+    moduleDeserializer: IrModuleDeserializer,
+    internationService: IrInternationService
 ) {
 
     val symbolDeserializer =
@@ -73,6 +74,7 @@
             fileProto.actualList,
             ::addIdSignature,
             linker::handleExpectActualMapping,
+            internationService,
             symbolProcessor = linker.symbolProcessor,
         ) { idSignature, symbolKind ->
             linker.deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled(idSignature, symbolKind, moduleDeserializer)
@@ -90,7 +92,8 @@
         symbolDeserializer,
         linker.fakeOverrideBuilder.platformSpecificClassFilter,
         linker.fakeOverrideBuilder,
-        compatibilityMode = moduleDeserializer.compatibilityMode
+        compatibilityMode = moduleDeserializer.compatibilityMode,
+        internationService
     )
 
     val fileDeserializer = IrFileDeserializer(file, fileReader, fileProto, symbolDeserializer, declarationDeserializer)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt
index ee99672..4c4f016 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt
@@ -123,7 +123,7 @@
     private val normalizeAbsolutePaths: Boolean = false,
     private val sourceBaseDirs: Collection<String>
 ) {
-    private val loopIndex = mutableMapOf<IrLoop, Int>()
+    private val loopIndex = hashMapOf<IrLoop, Int>()
     private var currentLoopIndex = 0
 
     // For every actual we keep a corresponding expects' uniqIds.
@@ -132,15 +132,15 @@
 
     // The same type can be used multiple times in a file
     // so use this index to store type data only once.
-    private val protoTypeMap = mutableMapOf<IrTypeKey, Int>()
+    private val protoTypeMap = hashMapOf<IrTypeKey, Int>()
     protected val protoTypeArray = arrayListOf<ProtoType>()
 
-    private val protoStringMap = mutableMapOf<String, Int>()
+    private val protoStringMap = hashMapOf<String, Int>()
     protected val protoStringArray = arrayListOf<String>()
 
     // The same signature could be used multiple times in a file
     // so use this index to store signature only once.
-    private val protoIdSignatureMap = mutableMapOf<IdSignature, Int>()
+    private val protoIdSignatureMap = hashMapOf<IdSignature, Int>()
     protected val protoIdSignatureArray = arrayListOf<ProtoIdSignature>()
 
     protected val protoBodyArray = mutableListOf<XStatementOrExpression>()
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInternationService.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInternationService.kt
new file mode 100644
index 0000000..1885e59
--- /dev/null
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInternationService.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2023 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.backend.common.serialization
+
+import org.jetbrains.kotlin.ir.types.IrSimpleType
+import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
+import org.jetbrains.kotlin.ir.util.IdSignature
+import org.jetbrains.kotlin.name.Name
+
+interface IrInternationService {
+    fun string(string: String): String {
+        return string
+    }
+
+    fun name(string: String): Name {
+        return Name.guessByFirstCharacter(string)
+    }
+
+    fun simpleType(type: IrSimpleType) : IrSimpleType {
+        return type
+    }
+
+    fun clear() {
+
+    }
+}
+
+class DefaultIrInternationService : IrInternationService {
+    private val strings = hashMapOf<String, String>()
+    private val names = hashMapOf<String, Name>()
+    private val simpleTypes = hashMapOf<Pair<IdSignature, SimpleTypeNullability>, IrSimpleType>()
+
+    override fun string(string: String): String {
+        return strings.getOrPut(string) { string }
+    }
+
+    override fun name(string: String): Name {
+        return names.getOrPut(string) { super.name(string) }
+    }
+
+    override fun simpleType(type: IrSimpleType): IrSimpleType {
+        val signature = type.classifier.signature
+        if (signature != null && type.arguments.isEmpty() && type.annotations.isEmpty() && type.abbreviation == null) {
+            // really simple type, intern it
+            return simpleTypes.getOrPut(signature to type.nullability) {
+                type
+            }
+        }
+        return super.simpleType(type)
+    }
+
+    override fun clear() {
+        strings.clear()
+        names.clear()
+        simpleTypes.clear()
+    }
+}
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt
index 1527f74..afe939d 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt
@@ -25,12 +25,13 @@
     val actuals: List<Actual>,
     val enqueueLocalTopLevelDeclaration: (IdSignature) -> Unit,
     val handleExpectActualMapping: (IdSignature, IrSymbol) -> IrSymbol,
+    internationService: IrInternationService,
     val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s },
     private val fileSignature: IdSignature.FileSignature = IdSignature.FileSignature(fileSymbol),
     val deserializePublicSymbol: (IdSignature, BinarySymbolData.SymbolKind) -> IrSymbol
 ) {
 
-    val deserializedSymbols: MutableMap<IdSignature, IrSymbol> = mutableMapOf()
+    val deserializedSymbols: MutableMap<IdSignature, IrSymbol> = hashMapOf()
 
     fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
         return deserializedSymbols.getOrPut(idSig) {
@@ -85,7 +86,7 @@
         }
     }
 
-    val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature)
+    val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature, internationService)
 
     fun deserializeIdSignature(index: Int): IdSignature {
         return signatureDeserializer.deserializeIdSignature(index)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt
index b961877..a26ec20 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt
@@ -33,21 +33,23 @@
     val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s },
 ) : IrDeserializer, FileLocalAwareLinker {
 
+    protected val internationService = DefaultIrInternationService()
+
     // Kotlin-MPP related data. Consider some refactoring
-    val expectUniqIdToActualUniqId = mutableMapOf<IdSignature, IdSignature>()
-    val topLevelActualUniqItToDeserializer = mutableMapOf<IdSignature, IrModuleDeserializer>()
-    internal val expectSymbols = mutableMapOf<IdSignature, IrSymbol>()
-    internal val actualSymbols = mutableMapOf<IdSignature, IrSymbol>()
+    val expectUniqIdToActualUniqId = hashMapOf<IdSignature, IdSignature>()
+    val topLevelActualUniqItToDeserializer = hashMapOf<IdSignature, IrModuleDeserializer>()
+    internal val expectSymbols = hashMapOf<IdSignature, IrSymbol>()
+    internal val actualSymbols = hashMapOf<IdSignature, IrSymbol>()
 
-    val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
+    val modulesWithReachableTopLevels = hashSetOf<IrModuleDeserializer>()
 
-    protected val deserializersForModules = mutableMapOf<String, IrModuleDeserializer>()
+    protected val deserializersForModules = hashMapOf<String, IrModuleDeserializer>()
 
     abstract val fakeOverrideBuilder: FakeOverrideBuilder
 
     abstract val translationPluginContext: TranslationPluginContext?
 
-    private val triedToDeserializeDeclarationForSymbol = mutableSetOf<IrSymbol>()
+    private val triedToDeserializeDeclarationForSymbol = hashSetOf<IrSymbol>()
 
     private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
 
@@ -227,6 +229,7 @@
             deserializersForModules.values.map { it.moduleFragment }
         }
 
+        internationService.clear()
         // TODO: fix IrPluginContext to make it not produce additional external reference
         // symbolTable.noUnboundLeft("unbound after fake overrides:")
     }
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/KotlinIrLinkerIssues.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/KotlinIrLinkerIssues.kt
index f2ef9a4..8cda849 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/KotlinIrLinkerIssues.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/KotlinIrLinkerIssues.kt
@@ -234,7 +234,7 @@
         return
     }
 
-    val incomingDependencyIdToDependencies: MutableMap<ResolvedDependencyId, MutableCollection<ResolvedDependency>> = mutableMapOf()
+    val incomingDependencyIdToDependencies: MutableMap<ResolvedDependencyId, MutableCollection<ResolvedDependency>> = hashMapOf()
     allModules.values.forEach { module ->
         module.requestedVersionsByIncomingDependencies.keys.forEach { incomingDependencyId ->
             incomingDependencyIdToDependencies.getOrPut(incomingDependencyId) { mutableListOf() } += module
@@ -352,7 +352,7 @@
     )
 
     // Reverse dependency index.
-    val outgoingDependenciesIndex: MutableMap<ResolvedDependencyId, MutableList<OutgoingDependency>> = mutableMapOf()
+    val outgoingDependenciesIndex: MutableMap<ResolvedDependencyId, MutableList<OutgoingDependency>> = hashMapOf()
 
     allModules.values.forEach { module ->
         module.requestedVersionsByIncomingDependencies.forEach { (incomingDependencyId, requestedVersion) ->
@@ -364,7 +364,7 @@
         }
     }
 
-    val dependencyStatesMap: MutableMap<ResolvedDependencyId, MutableSet<DependencyState>> = mutableMapOf()
+    val dependencyStatesMap: MutableMap<ResolvedDependencyId, MutableSet<DependencyState>> = hashMapOf()
 
     fun recurse(moduleId: ResolvedDependencyId, underConflictingDependency: Boolean) {
         val outgoingDependencies: List<OutgoingDependency> = outgoingDependenciesIndex[moduleId].orEmpty()
@@ -444,7 +444,7 @@
     sourceCodeModuleId: ResolvedDependencyId
 ): Map<ResolvedDependencyId, PotentialConflictDescription> {
 
-    val dependencyStatesMap: MutableMap<ResolvedDependencyId, MutableSet<DependencyState>> = mutableMapOf()
+    val dependencyStatesMap: MutableMap<ResolvedDependencyId, MutableSet<DependencyState>> = hashMapOf()
 
     fun recurse(moduleId: ResolvedDependencyId, aboveConflictingDependency: Boolean) {
         val module = allModules.findMatchingModule(moduleId)
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/UserVisibleIrModulesSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/UserVisibleIrModulesSupport.kt
index 6631761..ee2b78f 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/UserVisibleIrModulesSupport.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/linkerissues/UserVisibleIrModulesSupport.kt
@@ -88,7 +88,7 @@
                 selectedVersion = ResolvedDependencyVersion.EMPTY,
                 // Assumption: As we don't know for sure which modules the source code module depends on directly and which modules
                 // it depends on transitively, so let's assume it depends on all modules directly.
-                requestedVersionsByIncomingDependencies = mutableMapOf(
+                requestedVersionsByIncomingDependencies = hashMapOf(
                     ResolvedDependencyId.DEFAULT_SOURCE_CODE_MODULE_ID to ResolvedDependencyVersion.EMPTY
                 ),
                 artifactPaths = mutableSetOf()
@@ -108,7 +108,7 @@
      */
     protected fun mergedModules(deserializers: Collection<IrModuleDeserializer>): MutableMap<ResolvedDependencyId, ResolvedDependency> {
         val externalDependencyModulesByNames: Map</* unique name */ String, ResolvedDependency> =
-            mutableMapOf<String, ResolvedDependency>().apply {
+            hashMapOf<String, ResolvedDependency>().apply {
                 externalDependencyModules.forEach { externalDependency ->
                     externalDependency.id.uniqueNames.forEach { uniqueName ->
                         this[uniqueName] = externalDependency
@@ -122,7 +122,7 @@
         // The build system may express a group of modules where one module is a library KLIB and one or more modules
         // are just C-interop KLIBs as a single module with multiple artifacts. We need to expand them so that every particular
         // module/artifact will be represented as an individual [ResolvedDependency] instance.
-        val artifactPathsToOriginModules: MutableMap<ResolvedDependencyArtifactPath, ResolvedDependency> = mutableMapOf()
+        val artifactPathsToOriginModules: MutableMap<ResolvedDependencyArtifactPath, ResolvedDependency> = hashMapOf()
         externalDependencyModules.forEach { originModule ->
             originModule.artifactPaths.forEach { artifactPath -> artifactPathsToOriginModules[artifactPath] = originModule }
         }
@@ -180,7 +180,7 @@
             }
         }
 
-        return (externalDependencyModules + providedModules).associateByTo(mutableMapOf()) { it.id }
+        return (externalDependencyModules + providedModules).associateByTo(hashMapOf()) { it.id }
     }
 
     protected data class ModuleWithUninitializedDependencies(
diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt
index 8cb040a..fd3554b 100644
--- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt
+++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt
@@ -70,7 +70,7 @@
     }
 
     private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
-        BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode)
+        BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, internationService, allowErrorCode)
 
     override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer {
         val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies)
diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt
index ce0ec74..b5e0c68 100644
--- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt
+++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt
@@ -65,6 +65,7 @@
         fileSignature = dummyFileSignature,
         /* TODO */ actuals = emptyList(),
         enqueueLocalTopLevelDeclaration = {}, // just link to it in symbolTable
+        internationService = DefaultIrInternationService(),
         handleExpectActualMapping = { _, symbol -> symbol } // no expect declarations
     ) { idSignature, symbolKind ->
         referencePublicSymbol(symbolTable, idSignature, symbolKind)
@@ -85,6 +86,7 @@
         DefaultFakeOverrideClassFilter,
         fakeOverrideBuilder,
         compatibilityMode = CompatibilityMode.CURRENT,
+        DefaultIrInternationService(),
     )
     for (declarationProto in irProto.declarationList) {
         deserializer.deserializeDeclaration(declarationProto, setParent = false)
diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt
index cc57fd3..1d50a29 100644
--- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt
+++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt
@@ -62,7 +62,7 @@
     }
 
     private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategyResolver: (String) -> DeserializationStrategy) :
-        BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion)
+        BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, internationService)
 
     private fun DeclarationDescriptor.isJavaDescriptor(): Boolean {
         if (this is PackageFragmentDescriptor) {