From 37cf7316bc49d6e0568f3f5c0153a5113a8d90d7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 6 May 2020 13:05:35 +0200 Subject: [PATCH] Do not calculate maxStack size manually when generating typeOf --- .../codegen/inline/ReifiedTypeInliner.kt | 13 +++++++++---- .../jetbrains/kotlin/codegen/inline/typeOf.kt | 19 +++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 10e2f8cb4ee..397f3273493 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -258,13 +258,18 @@ class ReifiedTypeInliner( instructions: InsnList, type: KT ) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode -> - val newMethodNode = MethodNode(Opcodes.API_VERSION) - val stackSize = typeSystem.generateTypeOf(InstructionAdapter(newMethodNode), type, intrinsicsSupport) + val newMethodNode = MethodNode(Opcodes.API_VERSION, "fake", "()V", null, null) + 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) - maxStackSize = max(maxStackSize, stackSize) + maxStackSize = max(maxStackSize, newMethodNode.maxStack) return true } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt index 47e093f7ca1..7260232e336 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt @@ -36,10 +36,9 @@ private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter( v.aconst(null) } -// Returns some upper bound on maximum stack size internal fun TypeSystemCommonBackendContext.generateTypeOf( v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport -): Int { +) { intrinsicsSupport.putClassInstance(v, type) val argumentsSize = type.argumentsCount() @@ -50,16 +49,13 @@ internal fun TypeSystemCommonBackendContext.generateType v.newarray(K_TYPE_PROJECTION) } - var maxStackSize = 3 - for (i in 0 until argumentsSize) { if (useArray) { v.dup() v.iconst(i) } - val stackSize = doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport) - maxStackSize = maxOf(maxStackSize, stackSize + i + 5) + doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport) if (useArray) { v.astore(K_TYPE_PROJECTION) @@ -77,30 +73,27 @@ internal fun TypeSystemCommonBackendContext.generateType val signature = Type.getMethodDescriptor(K_TYPE, JAVA_CLASS_TYPE, *projections) v.invokestatic(REFLECTION, methodName, signature, false) - - return maxStackSize } private fun TypeSystemCommonBackendContext.doGenerateTypeProjection( v: InstructionAdapter, projection: TypeArgumentMarker, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport -): Int { +) { // KTypeProjection members could be static, see KT-30083 and KT-30084 v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor) if (projection.isStarProjection()) { v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false) - return 1 + return } @Suppress("UNCHECKED_CAST") val type = projection.getType() as KT val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier() - val stackSize = if (typeParameterClassifier != null) { + if (typeParameterClassifier != null) { if (typeParameterClassifier.isReified()) { putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable()) - 2 } else { // TODO: support non-reified type parameters in typeOf @Suppress("UNCHECKED_CAST") @@ -116,6 +109,4 @@ private fun TypeSystemCommonBackendContext.doGenerateTyp TypeVariance.OUT -> "covariant" } v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false) - - return stackSize + 1 }