Don't do full type parameters erasure in PromisedValue::materializeAt
The only case when erasure matters in a context of materialization of `PromisedValue` is when the type is a type parameter which upper bound is an inline class. Since `PromisedValue::materializeAt` is a hot spot and `eraseTypeParameters` is an expensive operation, we should not do type erasure in other cases.
This commit is contained in:
committed by
Space Team
parent
5456ef3ad8
commit
8f2825506a
+3
-3
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.InlineClassAbi
|
||||
import org.jetbrains.kotlin.backend.jvm.inlineClassFieldName
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.eraseIfTypeParameter
|
||||
import org.jetbrains.kotlin.backend.jvm.mapping.IrTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
@@ -29,8 +29,8 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
|
||||
// If this value is immaterial, construct an object on the top of the stack. This
|
||||
// must always be done before generating other values or emitting raw bytecode.
|
||||
open fun materializeAt(target: Type, irTarget: IrType, castForReified: Boolean) {
|
||||
val erasedSourceType = irType.eraseTypeParameters()
|
||||
val erasedTargetType = irTarget.eraseTypeParameters()
|
||||
val erasedSourceType = irType.eraseIfTypeParameter()
|
||||
val erasedTargetType = irTarget.eraseIfTypeParameter()
|
||||
|
||||
// Coerce inline classes
|
||||
val isFromTypeUnboxed = InlineClassAbi.unboxType(erasedSourceType)?.let(typeMapper::mapType) == type
|
||||
|
||||
@@ -44,16 +44,7 @@ fun IrType.eraseTypeParameters(): IrType = when (this) {
|
||||
IrSimpleTypeImpl(classifier, nullability, emptyList(), annotations)
|
||||
}
|
||||
is IrClass -> IrSimpleTypeImpl(classifier, nullability, arguments.map { it.eraseTypeParameters() }, annotations)
|
||||
is IrTypeParameter -> {
|
||||
val upperBound = owner.erasedUpperBound
|
||||
IrSimpleTypeImpl(
|
||||
upperBound.symbol,
|
||||
isNullable(),
|
||||
// Should not affect JVM signature, but may result in an invalid type object
|
||||
List(upperBound.typeParameters.size) { IrStarProjectionImpl },
|
||||
owner.annotations
|
||||
)
|
||||
}
|
||||
is IrTypeParameter -> owner.erasedType(isNullable())
|
||||
else -> error("Unknown IrSimpleType classifier kind: $owner")
|
||||
}
|
||||
is IrErrorType ->
|
||||
@@ -61,6 +52,22 @@ fun IrType.eraseTypeParameters(): IrType = when (this) {
|
||||
else -> error("Unknown IrType kind: $this")
|
||||
}
|
||||
|
||||
fun IrType.eraseIfTypeParameter(): IrType {
|
||||
val typeParameter = (this as? IrSimpleType)?.classifier?.owner as? IrTypeParameter ?: return this
|
||||
return typeParameter.erasedType(isNullable())
|
||||
}
|
||||
|
||||
private fun IrTypeParameter.erasedType(isNullable: Boolean): IrType {
|
||||
val upperBound = erasedUpperBound
|
||||
return IrSimpleTypeImpl(
|
||||
upperBound.symbol,
|
||||
isNullable,
|
||||
// Should not affect JVM signature, but may result in an invalid type object
|
||||
List(upperBound.typeParameters.size) { IrStarProjectionImpl },
|
||||
annotations
|
||||
)
|
||||
}
|
||||
|
||||
private fun IrTypeArgument.eraseTypeParameters(): IrTypeArgument = when (this) {
|
||||
is IrStarProjection -> this
|
||||
is IrTypeProjection -> makeTypeProjection(type.eraseTypeParameters(), variance)
|
||||
|
||||
Reference in New Issue
Block a user