From f2b0d057b9ec17686deb5d25990624b378ef3e3a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 12 Oct 2020 20:41:43 +0200 Subject: [PATCH] JVM IR: minor optimizations in IrTypeMapper.classInternalName Replace cubic complexity with square when computing internal name for nested classes by using StringBuilder instead of concatenating strings, and don't do getLocalClassType/classNameOverride checks on each step of the recursion. --- .../backend/jvm/codegen/IrTypeMapper.kt | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt index 0c633f0ec7a..03c0bf9a014 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt @@ -52,44 +52,52 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas error("Unknown descriptor: $classifier") } - fun classInternalName(irClass: IrClass): String = getClassInternalName(irClass.symbol) + private fun computeClassInternalName(irClass: IrClass): StringBuilder { + val shortName = SpecialNames.safeIdentifier(irClass.name).identifier - override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String { - val irClass = (typeConstructor as IrClassSymbol).owner - fun report(): Nothing { - 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." - ) + 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()) + } } - context.getLocalClassType(irClass)?.internalName?.let { return it } + 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 } - val className = SpecialNames.safeIdentifier(irClass.name).identifier - - val internalName = when (val parent = irClass.parent) { - is IrPackageFragment -> { - val fqName = parent.fqName - val prefix = if (fqName.isRoot) "" else fqName.asString().replace('.', '/') + "/" - prefix + className - } - is IrClass -> { - getClassInternalName(parent.symbol) + "$" + className - } - is IrFunction -> { - if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { - val interfaceClass = parent.parentAsClass.parent as IrClass - getClassInternalName(interfaceClass.symbol) + "$" + parent.name.asString() - } else report() - } - else -> report() - } - return JvmCodegenUtil.sanitizeNameIfNeeded(internalName, context.state.languageVersionSettings) + return JvmCodegenUtil.sanitizeNameIfNeeded( + computeClassInternalName(irClass).toString(), + context.state.languageVersionSettings + ) } + override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String = + classInternalName((typeConstructor as IrClassSymbol).owner) + fun writeFormalTypeParameters(irParameters: List, sw: JvmSignatureWriter) { if (sw.skipGenericSignature()) return with(KotlinTypeMapper) {