Simplify reified operations on type parameters in ExpressionCodegen

Move the "without propagation" logic to ReifiedTypeInliner since it's
only used from inline intrinsics.
This commit is contained in:
Alexander Udalov
2019-09-04 19:14:38 +02:00
parent 8efbcc5350
commit ece09866f0
3 changed files with 29 additions and 39 deletions
@@ -4843,33 +4843,13 @@ The "returned" value of try expression with no finally is either the last expres
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, operationKind, v, this);
}
public static void putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v
) {
putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, null);
}
private static void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v,
@NotNull ExpressionCodegen codegen
) {
putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, codegen);
}
private static void putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v,
@Nullable ExpressionCodegen codegen
) {
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst();
if (codegen != null) {
codegen.consumeReifiedOperationMarker(typeParameterDescriptor);
}
if (typeParameterAndReificationArgument == null) return;
TypeParameterDescriptor typeParameter = typeParameterAndReificationArgument.getFirst();
if (typeParameter.isReified()) {
consumeReifiedOperationMarker(typeParameter);
ReifiedTypeInliner.putReifiedOperationMarker(operationKind, typeParameterAndReificationArgument.getSecond(), v);
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -109,6 +110,18 @@ class ReifiedTypeInliner(
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, AsmTypes.JAVA_STRING_TYPE), false
)
}
fun putReifiedOperationMarkerIfNeeded(
typeParameter: TypeParameterDescriptor,
isNullable: Boolean,
operationKind: OperationKind,
v: InstructionAdapter
) {
if (typeParameter.isReified) {
val argument = ReificationArgument(typeParameter.name.asString(), isNullable, 0)
putReifiedOperationMarker(operationKind, argument, v)
}
}
}
private var maxStackSize = 0
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForCoroutineContext
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn
@@ -41,9 +40,9 @@ internal fun generateInlineIntrinsic(
val typeMapper = state.typeMapper
return when {
isSpecialEnumMethod(descriptor) ->
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single().defaultType, typeMapper)
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper)
TypeOfChecker.isTypeOf(descriptor) ->
createTypeOfMethodBody(typeArguments!!.keys.single().defaultType)
createTypeOfMethodBody(typeArguments!!.keys.single())
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
@@ -70,15 +69,13 @@ private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean {
(name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type))
}
private fun createSpecialEnumMethodBody(name: String, type: KotlinType, typeMapper: KotlinTypeMapper): MethodNode {
private fun createSpecialEnumMethodBody(name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper): MethodNode {
val isValueOf = "enumValueOf" == name
val invokeType = typeMapper.mapType(type)
val invokeType = typeMapper.mapType(typeParameter.defaultType)
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(
type,
ReifiedTypeInliner.OperationKind.ENUM_REIFIED,
InstructionAdapter(node)
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node)
)
if (isValueOf) {
node.visitInsn(Opcodes.ACONST_NULL)
@@ -101,11 +98,11 @@ internal fun getSpecialEnumFunDescriptor(type: Type, isValueOf: Boolean): String
if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE)
else Type.getMethodDescriptor(AsmUtil.getArrayType(type))
private fun createTypeOfMethodBody(type: KotlinType): MethodNode {
private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): MethodNode {
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
val v = InstructionAdapter(node)
putTypeOfReifiedTypeParameter(v, type)
putTypeOfReifiedTypeParameter(v, typeParameter, false)
v.areturn(K_TYPE)
v.visitMaxs(2, 0)
@@ -113,8 +110,8 @@ private fun createTypeOfMethodBody(type: KotlinType): MethodNode {
return node
}
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, type: KotlinType) {
ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameterWithoutPropagation(type, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, typeParameter: TypeParameterDescriptor, isNullable: Boolean) {
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
v.aconst(null)
}
@@ -179,7 +176,7 @@ private fun doGenerateTypeProjection(
val descriptor = type.constructor.declarationDescriptor
val stackSize = if (descriptor is TypeParameterDescriptor) {
if (descriptor.isReified) {
putTypeOfReifiedTypeParameter(v, type)
putTypeOfReifiedTypeParameter(v, descriptor, type.isMarkedNullable)
2
} else {
// TODO: support non-reified type parameters in typeOf