diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 2cc92d1d220..c4508b04ba3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -467,12 +467,9 @@ class MethodInliner( replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode) - val toDelete = SmartSet.create() - val sources = analyzeMethodNodeWithInterpreter(processingNode, FunctionalArgumentInterpreter(this)) val instructions = processingNode.instructions - - markObsoleteInstruction(instructions, toDelete, sources) + val toDelete = markObsoleteInstruction(instructions, sources) var awaitClassReification = false var currentFinallyDeep = 0 @@ -625,11 +622,9 @@ class MethodInliner( return processingNode } - private fun MethodInliner.markObsoleteInstruction( - instructions: InsnList, - toDelete: SmartSet, - sources: Array?> - ) { + private fun markObsoleteInstruction(instructions: InsnList, sources: Array?>): SmartSet { + val toDelete = SmartSet.create() + for (insn in instructions) { // Parameter checks are processed separately if (insn.isAloadBeforeCheckParameterIsNotNull()) continue @@ -658,6 +653,8 @@ class MethodInliner( } } } + + return toDelete } // Replace ALOAD 0 diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt index 6630cfdc8fd..779cbcea7b1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt @@ -110,10 +110,12 @@ internal class Aload0Interpreter(private val node: MethodNode) : BasicInterprete internal fun AbstractInsnNode.isAload0() = opcode == Opcodes.ALOAD && (this as VarInsnNode).`var` == 0 -internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: BasicInterpreter): Array?> { - val analyzer = object : FastMethodAnalyzer("fake", node, interpreter) { +internal fun analyzeMethodNodeWithInterpreter( + node: MethodNode, + interpreter: BasicInterpreter +): Array?> { + val analyzer = object : FastMethodAnalyzer("fake", node, interpreter, pruneExceptionEdges = true) { override fun newFrame(nLocals: Int, nStack: Int): Frame { - return object : Frame(nLocals, nStack) { @Throws(AnalyzerException::class) override fun execute(insn: AbstractInsnNode, interpreter: Interpreter) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt index a0cadeef3b7..8470707a75d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt @@ -78,7 +78,7 @@ open class FastMethodAnalyzer val isTcbStart = BooleanArray(nInsns) for (tcb in method.tryCatchBlocks) { - isTcbStart[tcb.start.indexOf()] = true + isTcbStart[tcb.start.indexOf() + 1] = true } val current = newFrame(method.maxLocals, method.maxStack) @@ -118,7 +118,11 @@ open class FastMethodAnalyzer // So, unless we have a store operation, anything we change on stack would be lost, // and there's no need to analyze exception handler again. // Add an exception edge from TCB start to make sure handler itself is still visited. - if (!pruneExceptionEdges || insnOpcode in Opcodes.ISTORE..Opcodes.ASTORE || insnOpcode == Opcodes.IINC || isTcbStart[insn]) { + if (!pruneExceptionEdges || + insnOpcode in Opcodes.ISTORE..Opcodes.ASTORE || + insnOpcode == Opcodes.IINC || + isTcbStart[insn] + ) { handlers[insn]?.forEach { tcb -> val exnType = Type.getObjectType(tcb.type ?: "java/lang/Throwable") val jump = tcb.handler.indexOf()