Simplify and optimize BridgeLowering
This commit is contained in:
committed by
Alexander Udalov
parent
0d53e11851
commit
25bcd86552
+13
-30
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.SpecialMethodWithDefaultInfo
|
||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import kotlin.collections.set
|
||||
|
||||
/*
|
||||
* Generate bridge methods to fix virtual dispatch after type erasure and to adapt Kotlin collections to
|
||||
@@ -149,7 +147,9 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
original != null && context.defaultMethodSignatureMapper.shouldBoxSingleValueParameterForSpecialCaseOfRemove(original)
|
||||
}
|
||||
if (remove != null) {
|
||||
makeLastParameterNullable(remove)
|
||||
remove.valueParameters.last().let {
|
||||
it.type = it.type.makeNullable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,13 +185,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
return !isFakeOverride || resolvesToClass()
|
||||
}
|
||||
|
||||
private fun makeLastParameterNullable(irFunction: IrSimpleFunction) {
|
||||
val oldValueParameter = irFunction.valueParameters.last()
|
||||
val newValueParameter = oldValueParameter.copyTo(irFunction, type = oldValueParameter.type.makeNullable())
|
||||
irFunction.valueParameters = irFunction.valueParameters.dropLast(1) + newValueParameter
|
||||
irFunction.body?.transform(VariableRemapper(mapOf(oldValueParameter to newValueParameter)), null)
|
||||
}
|
||||
|
||||
private fun createBridges(irClass: IrClass, irFunction: IrSimpleFunction) {
|
||||
// Track final overrides and bridges to avoid clashes
|
||||
val blacklist = mutableSetOf<Method>()
|
||||
@@ -506,7 +499,9 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
}
|
||||
|
||||
if (context.defaultMethodSignatureMapper.shouldBoxSingleValueParameterForSpecialCaseOfRemove(this)) {
|
||||
makeLastParameterNullable(this)
|
||||
valueParameters.last().let {
|
||||
it.type = it.type.makeNullable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +512,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
) {
|
||||
// If there is an existing function that would conflict with a special bridge signature, insert the special bridge
|
||||
// code directly as a prelude in the existing method.
|
||||
val variableMap = mutableMapOf<IrValueParameter, IrValueParameter>()
|
||||
if (specialOverrideSignature == ourSignature) {
|
||||
val argumentsToCheck = valueParameters.take(specialOverrideInfo.argumentsToCheck)
|
||||
val shouldGenerateParameterChecks = argumentsToCheck.any { !it.type.isNullable() }
|
||||
@@ -528,21 +522,18 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
body = irBlockBody {
|
||||
// Change the parameter types to be Any? so that null checks are not generated. The checks
|
||||
// we insert here make them superfluous.
|
||||
val newValueParameters = ArrayList(valueParameters)
|
||||
argumentsToCheck.forEach {
|
||||
val parameterType = it.type
|
||||
argumentsToCheck.forEach { parameter ->
|
||||
val parameterType = parameter.type
|
||||
if (!parameterType.isNullable()) {
|
||||
val newParameter = it.copyTo(this@rewriteSpecialMethodBody, type = parameterType.makeNullable())
|
||||
variableMap[valueParameters[it.index]] = newParameter
|
||||
newValueParameters[it.index] = newParameter
|
||||
parameter.type = parameterType.makeNullable()
|
||||
+parameterTypeCheck(
|
||||
newParameter,
|
||||
parameter,
|
||||
parameterType,
|
||||
specialOverrideInfo.defaultValueGenerator(this@rewriteSpecialMethodBody)
|
||||
)
|
||||
}
|
||||
}
|
||||
valueParameters = newValueParameters
|
||||
|
||||
// After the checks, insert the original method body.
|
||||
if (body is IrExpressionBody) {
|
||||
+irReturn((body as IrExpressionBody).expression)
|
||||
@@ -555,20 +546,12 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
} else {
|
||||
// If the signature of this method will be changed in the output to take a boxed argument instead of a primitive,
|
||||
// rewrite the argument so that code will be generated for a boxed argument and not a primitive.
|
||||
valueParameters = valueParameters.mapIndexed { i, p ->
|
||||
valueParameters.forEachIndexed { i, p ->
|
||||
if (AsmUtil.isPrimitive(context.defaultTypeMapper.mapType(p.type)) && ourSignature.argumentTypes[i].sort == Type.OBJECT) {
|
||||
val newParameter = p.copyTo(this, type = p.type.makeNullable())
|
||||
variableMap[p] = newParameter
|
||||
newParameter
|
||||
} else {
|
||||
p
|
||||
p.type = p.type.makeNullable()
|
||||
}
|
||||
}
|
||||
}
|
||||
// If any parameters change, remap them in the function body.
|
||||
if (variableMap.isNotEmpty()) {
|
||||
body?.transform(VariableRemapper(variableMap), null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.parameterTypeCheck(parameter: IrValueParameter, type: IrType, defaultValue: IrExpression) =
|
||||
|
||||
Reference in New Issue
Block a user