Do not calculate maxStack size manually when generating typeOf
This commit is contained in:
@@ -258,13 +258,18 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
|||||||
instructions: InsnList,
|
instructions: InsnList,
|
||||||
type: KT
|
type: KT
|
||||||
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
|
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
|
||||||
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
val newMethodNode = MethodNode(Opcodes.API_VERSION, "fake", "()V", null, null)
|
||||||
val stackSize = typeSystem.generateTypeOf(InstructionAdapter(newMethodNode), type, intrinsicsSupport)
|
val mv = wrapWithMaxLocalCalc(newMethodNode)
|
||||||
|
typeSystem.generateTypeOf(InstructionAdapter(mv), type, intrinsicsSupport)
|
||||||
|
|
||||||
instructions.insert(insn, newMethodNode.instructions)
|
// Adding a fake return (and removing it below) to trigger maxStack calculation
|
||||||
|
mv.visitInsn(Opcodes.RETURN)
|
||||||
|
mv.visitMaxs(-1, -1)
|
||||||
|
|
||||||
|
instructions.insert(insn, newMethodNode.instructions.apply { remove(last) })
|
||||||
instructions.remove(stubConstNull)
|
instructions.remove(stubConstNull)
|
||||||
|
|
||||||
maxStackSize = max(maxStackSize, stackSize)
|
maxStackSize = max(maxStackSize, newMethodNode.maxStack)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,9 @@ private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter(
|
|||||||
v.aconst(null)
|
v.aconst(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns some upper bound on maximum stack size
|
|
||||||
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||||
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
): Int {
|
) {
|
||||||
intrinsicsSupport.putClassInstance(v, type)
|
intrinsicsSupport.putClassInstance(v, type)
|
||||||
|
|
||||||
val argumentsSize = type.argumentsCount()
|
val argumentsSize = type.argumentsCount()
|
||||||
@@ -50,16 +49,13 @@ internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateType
|
|||||||
v.newarray(K_TYPE_PROJECTION)
|
v.newarray(K_TYPE_PROJECTION)
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxStackSize = 3
|
|
||||||
|
|
||||||
for (i in 0 until argumentsSize) {
|
for (i in 0 until argumentsSize) {
|
||||||
if (useArray) {
|
if (useArray) {
|
||||||
v.dup()
|
v.dup()
|
||||||
v.iconst(i)
|
v.iconst(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
val stackSize = doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport)
|
doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport)
|
||||||
maxStackSize = maxOf(maxStackSize, stackSize + i + 5)
|
|
||||||
|
|
||||||
if (useArray) {
|
if (useArray) {
|
||||||
v.astore(K_TYPE_PROJECTION)
|
v.astore(K_TYPE_PROJECTION)
|
||||||
@@ -77,30 +73,27 @@ internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateType
|
|||||||
val signature = Type.getMethodDescriptor(K_TYPE, JAVA_CLASS_TYPE, *projections)
|
val signature = Type.getMethodDescriptor(K_TYPE, JAVA_CLASS_TYPE, *projections)
|
||||||
|
|
||||||
v.invokestatic(REFLECTION, methodName, signature, false)
|
v.invokestatic(REFLECTION, methodName, signature, false)
|
||||||
|
|
||||||
return maxStackSize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
||||||
v: InstructionAdapter,
|
v: InstructionAdapter,
|
||||||
projection: TypeArgumentMarker,
|
projection: TypeArgumentMarker,
|
||||||
intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
): Int {
|
) {
|
||||||
// KTypeProjection members could be static, see KT-30083 and KT-30084
|
// KTypeProjection members could be static, see KT-30083 and KT-30084
|
||||||
v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor)
|
v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor)
|
||||||
|
|
||||||
if (projection.isStarProjection()) {
|
if (projection.isStarProjection()) {
|
||||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false)
|
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false)
|
||||||
return 1
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val type = projection.getType() as KT
|
val type = projection.getType() as KT
|
||||||
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
||||||
val stackSize = if (typeParameterClassifier != null) {
|
if (typeParameterClassifier != null) {
|
||||||
if (typeParameterClassifier.isReified()) {
|
if (typeParameterClassifier.isReified()) {
|
||||||
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
||||||
2
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: support non-reified type parameters in typeOf
|
// TODO: support non-reified type parameters in typeOf
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -116,6 +109,4 @@ private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTyp
|
|||||||
TypeVariance.OUT -> "covariant"
|
TypeVariance.OUT -> "covariant"
|
||||||
}
|
}
|
||||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false)
|
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false)
|
||||||
|
|
||||||
return stackSize + 1
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user