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.
This commit is contained in:
Alexander Udalov
2020-10-12 20:41:43 +02:00
parent b3e79d36df
commit f2b0d057b9
@@ -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<IrTypeParameter>, sw: JvmSignatureWriter) {
if (sw.skipGenericSignature()) return
with(KotlinTypeMapper) {