Repository: JetBrains/kotlin
File: compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt (Kotlin)

Code before:
    override val typeContext: TypeSystemCommonBackendContextForTypeMapping = IrTypeCheckerContextForTypeMapping(typeSystem, context)

    override fun mapClass(classifier: ClassifierDescriptor): Type =
        when (classifier) {
            is ClassDescriptor ->
                mapClass(context.referenceClass(classifier).owner)
            is TypeParameterDescriptor ->
                mapType(context.referenceTypeParameter(classifier).defaultType)
            else ->
                error("Unknown descriptor: $classifier")
        }

    private fun computeClassInternalName(irClass: IrClass): StringBuilder {
        val shortName = SpecialNames.safeIdentifier(irClass.name).identifier

        when (val parent = irClass.parent) {
            is IrPackageFragment ->
                return StringBuilder().apply {
                    val fqName = parent.fqName
                    if (!fqName.isRoot) {
                        append(fqName.asString().replace('.', '/')).append("/")
                    }
                    append(shortName)
                }
            is IrClass ->
                return StringBuilder(classInternalName(parent)).append("$").append(shortName)
            is IrFunction ->
                if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
                    return StringBuilder(classInternalName(parent.parentAsClass.parentAsClass))
                        .append("$").append(parent.name.asString())
                }
        }

        val localClassType = context.getLocalClassType(irClass)
        if (localClassType != null) {
            return StringBuilder(localClassType.internalName)
        }

        error(
            "Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" +
                    "Ensure that any lowering that transforms elements with local class info (classes, function references) " +
                    "invokes `copyAttributes` on the transformed element."
        )
    }

    fun classInternalName(irClass: IrClass): String {
        context.getLocalClassType(irClass)?.internalName?.let { return it }
        context.classNameOverride[irClass]?.let { return it.internalName }

        return JvmCodegenUtil.sanitizeNameIfNeeded(
            computeClassInternalName(irClass).toString(),

Review comment (performance):
I suppose the problem started happening after f2b0d057b9ec17686deb5d25990624b378ef3e3a where I've tried to optimize this code to minimize string concatenations and map lookups for deeply nested classes. Is there any way we could keep the optimization and also fix the class names, maybe by storing the class names in the `context.getLocalClassType` map? It'd be great to have names for all local classes in that map, so that only one lookup would be necessary in the type mapper.

Code after:
    override val typeContext: TypeSystemCommonBackendContextForTypeMapping = IrTypeCheckerContextForTypeMapping(typeSystem, context)

    override fun mapClass(classifier: ClassifierDescriptor): Type =
        when (classifier) {
            is ClassDescriptor ->
                mapClass(context.referenceClass(classifier).owner)
            is TypeParameterDescriptor ->
                mapType(context.referenceTypeParameter(classifier).defaultType)
            else ->
                error("Unknown descriptor: $classifier")
        }

    private fun computeClassInternalName(irClass: IrClass): StringBuilder {
        context.getLocalClassType(irClass)?.internalName?.let {
            return StringBuilder(it)
        }

        val shortName = SpecialNames.safeIdentifier(irClass.name).identifier

        when (val parent = irClass.parent) {
            is IrPackageFragment ->
                return StringBuilder().apply {
                    val fqName = parent.fqName
                    if (!fqName.isRoot) {
                        append(fqName.asString().replace('.', '/')).append("/")
                    }
                    append(shortName)
                }
            is IrClass ->
                return computeClassInternalName(parent).append("$").append(shortName)
            is IrFunction ->
                if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
                    return computeClassInternalName(parent.parentAsClass.parentAsClass)
                        .append("$").append(parent.name.asString())
                }
        }

        error(
            "Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" +
                    "Ensure that any lowering that transforms elements with local class info (classes, function references) " +
                    "invokes `copyAttributes` on the transformed element."
        )
    }

    fun classInternalName(irClass: IrClass): String {
        context.getLocalClassType(irClass)?.internalName?.let { return it }
        context.classNameOverride[irClass]?.let { return it.internalName }

        return JvmCodegenUtil.sanitizeNameIfNeeded(
            computeClassInternalName(irClass).toString(),
            context.state.languageVersionSettings