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 84e1786a113..599cb913980 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 @@ -54,7 +54,6 @@ open class FastMethodAnalyzer private val interpreter: Interpreter, private val pruneExceptionEdges: Boolean = false ) { - private val insnsArray = method.instructions.toArray() private val nInsns = method.instructions.size() private val isMergeNode = findMergeNodes(method) @@ -186,7 +185,7 @@ open class FastMethodAnalyzer frames[insn.indexOf()] private fun checkAssertions() { - if (insnsArray.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) + if (method.instructions.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) throw AssertionError("Subroutines are deprecated since Java 6") } @@ -222,16 +221,20 @@ open class FastMethodAnalyzer private fun computeExceptionHandlersForEachInsn(m: MethodNode) { for (tcb in m.tryCatchBlocks) { - val begin = tcb.start.indexOf() - val end = tcb.end.indexOf() - for (j in begin until end) { - if (!insnsArray[j].isMeaningful) continue - var insnHandlers: MutableList? = handlers[j] - if (insnHandlers == null) { - insnHandlers = SmartList() - handlers[j] = insnHandlers + var current: AbstractInsnNode = tcb.start + val end = tcb.end + + while (current != end) { + if (current.isMeaningful) { + val currentIndex = current.indexOf() + var insnHandlers: MutableList? = handlers[currentIndex] + if (insnHandlers == null) { + insnHandlers = SmartList() + handlers[currentIndex] = insnHandlers + } + insnHandlers.add(tcb) } - insnHandlers.add(tcb) + current = current.next } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FastStackAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FastStackAnalyzer.kt index 8fbf44cff55..7bbc080c1e8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FastStackAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FastStackAnalyzer.kt @@ -51,8 +51,7 @@ internal open class FastStackAnalyzer( val method: MethodNode, protected val interpreter: Interpreter ) { - protected val insnsArray: Array = method.instructions.toArray() - private val nInsns = insnsArray.size + private val nInsns = method.instructions.size() private val frames: Array?> = arrayOfNulls(nInsns) @@ -63,7 +62,7 @@ internal open class FastStackAnalyzer( protected open fun newFrame(nLocals: Int, nStack: Int): Frame = Frame(nLocals, nStack) - protected open fun visitControlFlowEdge(insn: Int, successor: Int): Boolean = true + protected open fun visitControlFlowEdge(insnNode: AbstractInsnNode, successor: Int): Boolean = true protected open fun visitControlFlowExceptionEdge(insn: Int, successor: Int): Boolean = true @@ -92,7 +91,7 @@ internal open class FastStackAnalyzer( try { if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) { - visitNopInsn(f, insn) + visitNopInsn(insnNode, f, insn) } else { current.init(f) if (insnOpcode != Opcodes.RETURN) { @@ -104,11 +103,11 @@ internal open class FastStackAnalyzer( insnType == AbstractInsnNode.JUMP_INSN -> visitJumpInsnNode(insnNode as JumpInsnNode, current, insn, insnOpcode) insnType == AbstractInsnNode.LOOKUPSWITCH_INSN -> - visitLookupSwitchInsnNode(insnNode as LookupSwitchInsnNode, current, insn) + visitLookupSwitchInsnNode(insnNode as LookupSwitchInsnNode, current) insnType == AbstractInsnNode.TABLESWITCH_INSN -> - visitTableSwitchInsnNode(insnNode as TableSwitchInsnNode, current, insn) + visitTableSwitchInsnNode(insnNode as TableSwitchInsnNode, current) insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN) -> - visitOpInsn(current, insn) + visitOpInsn(insnNode, current, insn) else -> { } } @@ -142,17 +141,21 @@ internal open class FastStackAnalyzer( frames[insn.indexOf()] private fun checkAssertions() { - if (insnsArray.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) + if (method.instructions.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) throw AssertionError("Subroutines are deprecated since Java 6") } - private fun visitOpInsn(current: Frame, insn: Int) { - processControlFlowEdge(current, insn, insn + 1) + private fun visitOpInsn(insnNode: AbstractInsnNode, current: Frame, insn: Int) { + processControlFlowEdge(current, insnNode, insn + 1) } - private fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: Frame, insn: Int) { + private fun visitNopInsn(insnNode: AbstractInsnNode, f: Frame, insn: Int) { + processControlFlowEdge(f, insnNode, insn + 1) + } + + private fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: Frame) { var jump = insnNode.dflt.indexOf() - processControlFlowEdge(current, insn, jump) + processControlFlowEdge(current, insnNode, jump) // In most cases order of visiting switch labels should not matter // The only one is a tableswitch being added in the beginning of coroutine method, these switch' labels may lead // in the middle of try/catch block, and FixStackAnalyzer is not ready for this (trying to restore stack before it was saved) @@ -160,33 +163,29 @@ internal open class FastStackAnalyzer( // Using 'reversed' is because nodes are processed in LIFO order for (label in insnNode.labels.reversed()) { jump = label.indexOf() - processControlFlowEdge(current, insn, jump) + processControlFlowEdge(current, insnNode, jump) } } - private fun visitLookupSwitchInsnNode(insnNode: LookupSwitchInsnNode, current: Frame, insn: Int) { + private fun visitLookupSwitchInsnNode(insnNode: LookupSwitchInsnNode, current: Frame) { var jump = insnNode.dflt.indexOf() - processControlFlowEdge(current, insn, jump) + processControlFlowEdge(current, insnNode, jump) for (label in insnNode.labels) { jump = label.indexOf() - processControlFlowEdge(current, insn, jump) + processControlFlowEdge(current, insnNode, jump) } } private fun visitJumpInsnNode(insnNode: JumpInsnNode, current: Frame, insn: Int, insnOpcode: Int) { if (insnOpcode != Opcodes.GOTO) { - processControlFlowEdge(current, insn, insn + 1) + processControlFlowEdge(current, insnNode, insn + 1) } val jump = insnNode.label.indexOf() - processControlFlowEdge(current, insn, jump) + processControlFlowEdge(current, insnNode, jump) } - private fun visitNopInsn(f: Frame, insn: Int) { - processControlFlowEdge(f, insn, insn + 1) - } - - private fun processControlFlowEdge(current: Frame, insn: Int, jump: Int) { - if (visitControlFlowEdge(insn, jump)) { + private fun processControlFlowEdge(current: Frame, insnNode: AbstractInsnNode, jump: Int) { + if (visitControlFlowEdge(insnNode, jump)) { mergeControlFlowEdge(jump, current) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt index 811900f7271..77a14e1467b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt @@ -95,9 +95,8 @@ internal class FixStackAnalyzer( val spilledStacks = hashMapOf>() var maxExtraStackSize = 0; private set - override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean { + override fun visitControlFlowEdge(insnNode: AbstractInsnNode, successor: Int): Boolean { if (!skipBreakContinueGotoEdges) return true - val insnNode = insnsArray[insn] return !(insnNode is JumpInsnNode && context.breakContinueGotoNodes.contains(insnNode)) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/FastStoreLoadAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/FastStoreLoadAnalyzer.kt index 9e35f4f47d1..e9d9c9f6133 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/FastStoreLoadAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/FastStoreLoadAnalyzer.kt @@ -107,7 +107,6 @@ class FastStoreLoadAnalyzer( private val method: MethodNode, private val interpreter: StoreLoadInterpreter ) { - private val insnsArray = method.instructions.toArray() private val nInsns = method.instructions.size() private val isMergeNode = BooleanArray(nInsns) @@ -182,7 +181,7 @@ class FastStoreLoadAnalyzer( method.instructions.indexOf(this) private fun checkAssertions() { - if (insnsArray.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) + if (method.instructions.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET }) throw AssertionError("Subroutines are deprecated since Java 6") } @@ -209,22 +208,26 @@ class FastStoreLoadAnalyzer( private fun computeExceptionHandlersForEachInsn(m: MethodNode) { for (tcb in m.tryCatchBlocks) { - val begin = tcb.start.indexOf() - val end = tcb.end.indexOf() - for (j in begin until end) { - if (!insnsArray[j].isMeaningful) continue - var insnHandlers: MutableList? = handlers[j] - if (insnHandlers == null) { - insnHandlers = SmartList() - handlers[j] = insnHandlers + var current: AbstractInsnNode = tcb.start + val end = tcb.end + + while (current != end) { + if (current.isMeaningful) { + val currentIndex = current.indexOf() + var insnHandlers: MutableList? = handlers[currentIndex] + if (insnHandlers == null) { + insnHandlers = SmartList() + handlers[currentIndex] = insnHandlers + } + insnHandlers.add(tcb) } - insnHandlers.add(tcb) + current = current.next } } } private fun initMergeNodes() { - for (insn in insnsArray) { + for (insn in method.instructions) { when (insn.type) { AbstractInsnNode.JUMP_INSN -> { val jumpInsn = insn as JumpInsnNode