[JVM] Micro-optimize method signature mapping
This commit optimizes functions related to method signature mapping on the JVM backend. The most significant change is avoiding re-allocations in StringBuilder when building internal names. The commit also includes minor optimizations, such as removing redundant allocations of strings and other objects.
This commit is contained in:
committed by
Space Team
parent
70996035fc
commit
059046a2b1
@@ -151,9 +151,15 @@ object AbstractTypeMapper {
|
|||||||
materialized: Boolean
|
materialized: Boolean
|
||||||
): Type {
|
): Type {
|
||||||
val typeArgument = type.asArgumentList()[0]
|
val typeArgument = type.asArgumentList()[0]
|
||||||
val (variance, memberType) = when {
|
val variance: Variance
|
||||||
typeArgument.isStarProjection() -> Variance.OUT_VARIANCE to nullableAnyType()
|
val memberType: KotlinTypeMarker
|
||||||
else -> typeArgument.getVariance().toVariance() to typeArgument.getType()
|
|
||||||
|
if (typeArgument.isStarProjection()) {
|
||||||
|
variance = Variance.OUT_VARIANCE
|
||||||
|
memberType = nullableAnyType()
|
||||||
|
} else {
|
||||||
|
variance = typeArgument.getVariance().toVariance()
|
||||||
|
memberType = typeArgument.getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
val arrayElementType: Type
|
val arrayElementType: Type
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ val CallableDescriptor.arity: Int
|
|||||||
(if (extensionReceiverParameter != null) 1 else 0) +
|
(if (extensionReceiverParameter != null) 1 else 0) +
|
||||||
(if (dispatchReceiverParameter != null) 1 else 0)
|
(if (dispatchReceiverParameter != null) 1 else 0)
|
||||||
|
|
||||||
fun FqName.topLevelClassInternalName() = JvmClassName.byClassId(ClassId(parent(), shortName())).internalName
|
fun FqName.topLevelClassInternalName() = JvmClassName.internalNameByClassId(ClassId(parent(), shortName()))
|
||||||
fun FqName.topLevelClassAsmType(): Type = Type.getObjectType(topLevelClassInternalName())
|
fun FqName.topLevelClassAsmType(): Type = Type.getObjectType(topLevelClassInternalName())
|
||||||
|
|
||||||
fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodegen, valueParameters: List<ValueParameterDescriptor>, endLabel: Label?) {
|
fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodegen, valueParameters: List<ValueParameterDescriptor>, endLabel: Label?) {
|
||||||
|
|||||||
+22
-8
@@ -55,7 +55,15 @@ open class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapp
|
|||||||
override fun mapTypeCommon(type: KotlinTypeMarker, mode: TypeMappingMode): Type =
|
override fun mapTypeCommon(type: KotlinTypeMarker, mode: TypeMappingMode): Type =
|
||||||
mapType(type as IrType, mode)
|
mapType(type as IrType, mode)
|
||||||
|
|
||||||
private fun computeClassInternalName(irClass: IrClass): StringBuilder {
|
private fun computeClassInternalNameAsString(irClass: IrClass): String {
|
||||||
|
context.getLocalClassType(irClass)?.internalName?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
return computeClassInternalName(irClass, 0).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeClassInternalName(irClass: IrClass, capacity: Int): StringBuilder {
|
||||||
context.getLocalClassType(irClass)?.internalName?.let {
|
context.getLocalClassType(irClass)?.internalName?.let {
|
||||||
return StringBuilder(it)
|
return StringBuilder(it)
|
||||||
}
|
}
|
||||||
@@ -63,20 +71,26 @@ open class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapp
|
|||||||
val shortName = SpecialNames.safeIdentifier(irClass.name).identifier
|
val shortName = SpecialNames.safeIdentifier(irClass.name).identifier
|
||||||
|
|
||||||
when (val parent = irClass.parent) {
|
when (val parent = irClass.parent) {
|
||||||
is IrPackageFragment ->
|
is IrPackageFragment -> {
|
||||||
return StringBuilder().apply {
|
val fqName = parent.packageFqName
|
||||||
val fqName = parent.packageFqName
|
var ourCapacity = shortName.length
|
||||||
|
if (!fqName.isRoot) {
|
||||||
|
ourCapacity += fqName.asString().length + 1
|
||||||
|
}
|
||||||
|
return StringBuilder(ourCapacity + capacity).apply {
|
||||||
if (!fqName.isRoot) {
|
if (!fqName.isRoot) {
|
||||||
append(fqName.asString().replace('.', '/')).append("/")
|
append(fqName.asString().replace('.', '/')).append("/")
|
||||||
}
|
}
|
||||||
append(shortName)
|
append(shortName)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
is IrClass ->
|
is IrClass ->
|
||||||
return computeClassInternalName(parent).append("$").append(shortName)
|
return computeClassInternalName(parent, 1 + shortName.length).append("$").append(shortName)
|
||||||
is IrFunction ->
|
is IrFunction ->
|
||||||
if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
|
if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
|
||||||
return computeClassInternalName(parent.parentAsClass.parentAsClass)
|
val parentName = parent.name.asString()
|
||||||
.append("$").append(parent.name.asString())
|
return computeClassInternalName(parent.parentAsClass.parentAsClass, 1 + parentName.length)
|
||||||
|
.append("$").append(parentName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +106,7 @@ open class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapp
|
|||||||
context.classNameOverride[irClass]?.let { return it.internalName }
|
context.classNameOverride[irClass]?.let { return it.internalName }
|
||||||
|
|
||||||
return JvmCodegenUtil.sanitizeNameIfNeeded(
|
return JvmCodegenUtil.sanitizeNameIfNeeded(
|
||||||
computeClassInternalName(irClass).toString(),
|
computeClassInternalNameAsString(irClass),
|
||||||
context.state.languageVersionSettings
|
context.state.languageVersionSettings
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -79,7 +79,12 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
|||||||
if (property != null) {
|
if (property != null) {
|
||||||
val propertyName = property.name.asString()
|
val propertyName = property.name.asString()
|
||||||
val propertyParent = property.parentAsClass
|
val propertyParent = property.parentAsClass
|
||||||
if (propertyParent.isAnnotationClass || propertyParent.superTypes.any { it.isJavaLangRecord() }) return propertyName
|
|
||||||
|
if (propertyParent.isAnnotationClass) return propertyName
|
||||||
|
|
||||||
|
for (i in propertyParent.superTypes.indices) {
|
||||||
|
if (propertyParent.superTypes[i].isJavaLangRecord()) return propertyName
|
||||||
|
}
|
||||||
|
|
||||||
// The enum property getters <get-name> and <get-ordinal> have special names which also
|
// The enum property getters <get-name> and <get-ordinal> have special names which also
|
||||||
// apply to their fake overrides. Unfortunately, getJvmMethodNameIfSpecial does not handle
|
// apply to their fake overrides. Unfortunately, getJvmMethodNameIfSpecial does not handle
|
||||||
@@ -248,8 +253,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
|||||||
|
|
||||||
sw.writeParametersStart()
|
sw.writeParametersStart()
|
||||||
|
|
||||||
val contextReceivers = function.valueParameters.subList(0, function.contextReceiverParametersCount)
|
for (i in 0 until function.contextReceiverParametersCount) {
|
||||||
for (contextReceiver in contextReceivers) {
|
val contextReceiver = function.valueParameters[i]
|
||||||
writeParameter(sw, JvmMethodParameterKind.CONTEXT_RECEIVER, contextReceiver.type, function)
|
writeParameter(sw, JvmMethodParameterKind.CONTEXT_RECEIVER, contextReceiver.type, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,9 +263,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
|||||||
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.type, function)
|
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.type, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
val regularValueParameters =
|
for (i in function.contextReceiverParametersCount until function.valueParameters.size) {
|
||||||
function.valueParameters.subList(function.contextReceiverParametersCount, function.valueParameters.size)
|
val parameter = function.valueParameters[i]
|
||||||
for (parameter in regularValueParameters) {
|
|
||||||
val kind = when (parameter.origin) {
|
val kind = when (parameter.origin) {
|
||||||
JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS -> JvmMethodParameterKind.OUTER
|
JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS -> JvmMethodParameterKind.OUTER
|
||||||
JvmLoweredDeclarationOrigin.ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER -> JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL
|
JvmLoweredDeclarationOrigin.ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER -> JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL
|
||||||
@@ -468,11 +472,10 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
|||||||
if (!isBuiltIn) return null
|
if (!isBuiltIn) return null
|
||||||
return allOverridden(includeSelf = true)
|
return allOverridden(includeSelf = true)
|
||||||
.filter { it.isBuiltIn }
|
.filter { it.isBuiltIn }
|
||||||
.mapNotNull {
|
.firstNotNullOfOrNull {
|
||||||
val signature = it.computeJvmSignature()
|
val signature = it.computeJvmSignature()
|
||||||
SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME[signature]?.asString()
|
SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME[signature]?.asString()
|
||||||
}
|
}
|
||||||
.firstOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.getBuiltinSpecialPropertyGetterName(): String? {
|
private fun IrSimpleFunction.getBuiltinSpecialPropertyGetterName(): String? {
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ open class SpecialGenericSignatures {
|
|||||||
signatureAndName.copy(name = jdkName).signature
|
signatureAndName.copy(name = jdkName).signature
|
||||||
}
|
}
|
||||||
|
|
||||||
val ORIGINAL_SHORT_NAMES: List<Name> = NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.keys.map { it.name }
|
val ORIGINAL_SHORT_NAMES: Set<Name> = NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.keys.mapTo(HashSet()) { it.name }
|
||||||
|
|
||||||
val JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP: Map<Name, Name> =
|
val JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP: Map<Name, Name> =
|
||||||
NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.entries
|
NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.entries
|
||||||
|
|||||||
+1
-1
@@ -34,5 +34,5 @@ object SignatureBuildingComponents {
|
|||||||
|
|
||||||
val ClassId.internalName: String
|
val ClassId.internalName: String
|
||||||
get() {
|
get() {
|
||||||
return JvmClassName.byClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
return JvmClassName.internalNameByClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ fun <T : Any> TypeSystemCommonBackendContext.mapBuiltInType(
|
|||||||
if (!mode.kotlinCollectionsToJavaCollections && JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId })
|
if (!mode.kotlinCollectionsToJavaCollections && JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId })
|
||||||
return null
|
return null
|
||||||
|
|
||||||
return typeFactory.createObjectType(JvmClassName.byClassId(classId).internalName)
|
return typeFactory.createObjectType(JvmClassName.internalNameByClassId(classId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,16 @@ public class JvmClassName {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JvmClassName byClassId(@NotNull ClassId classId) {
|
public static JvmClassName byClassId(@NotNull ClassId classId) {
|
||||||
|
return new JvmClassName(internalNameByClassId(classId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String internalNameByClassId(@NotNull ClassId classId) {
|
||||||
FqName packageFqName = classId.getPackageFqName();
|
FqName packageFqName = classId.getPackageFqName();
|
||||||
String relativeClassName = classId.getRelativeClassName().asString().replace('.', '$');
|
String relativeClassName = classId.getRelativeClassName().asString().replace('.', '$');
|
||||||
return packageFqName.isRoot()
|
return packageFqName.isRoot()
|
||||||
? new JvmClassName(relativeClassName)
|
? relativeClassName
|
||||||
: new JvmClassName(packageFqName.asString().replace('.', '/') + "/" + relativeClassName);
|
: packageFqName.asString().replace('.', '/') + "/" + relativeClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ internal fun CallableDescriptor.computeJvmSignature(): String? = signatures {
|
|||||||
internal val ClassDescriptor.internalName: String
|
internal val ClassDescriptor.internalName: String
|
||||||
get() {
|
get() {
|
||||||
JavaToKotlinClassMap.mapKotlinToJava(fqNameSafe.toUnsafe())?.let {
|
JavaToKotlinClassMap.mapKotlinToJava(fqNameSafe.toUnsafe())?.let {
|
||||||
return JvmClassName.byClassId(it).internalName
|
return JvmClassName.internalNameByClassId(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return computeInternalName(this)
|
return computeInternalName(this)
|
||||||
|
|||||||
@@ -109,7 +109,10 @@ fun String.capitalizeAsciiOnly(): String {
|
|||||||
if (isEmpty()) return this
|
if (isEmpty()) return this
|
||||||
val c = this[0]
|
val c = this[0]
|
||||||
return if (c in 'a'..'z')
|
return if (c in 'a'..'z')
|
||||||
c.uppercaseChar() + substring(1)
|
buildString(length) {
|
||||||
|
append(c.uppercaseChar())
|
||||||
|
append(this@capitalizeAsciiOnly, 1, this@capitalizeAsciiOnly.length)
|
||||||
|
}
|
||||||
else
|
else
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user