diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/opt/InstructionResultSize.scala | 8 |
2 files changed, 20 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala index aeb0f41237..efeaa54a7b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala @@ -303,6 +303,8 @@ class BackendUtils[BT <: BTypes](val btypes: BT) { r } + val subroutineRetTargets = new mutable.Stack[AbstractInsnNode] + // for each instruction in the queue, contains the stack height at this instruction. // once an instruction has been treated, contains -1 to prevent re-enqueuing val stackHeights = new Array[Int](size) @@ -353,21 +355,34 @@ class BackendUtils[BT <: BTypes](val btypes: BT) { insn match { case j: JumpInsnNode => - enqInsn(j.label, heightAfter) - val opc = j.getOpcode - if (opc != GOTO) enqInsnIndex(insnIndex + 1, heightAfter) // jump is conditional, so the successor is also a possible control flow target + if (j.getOpcode == JSR) { + val jsrTargetHeight = heightAfter + 1 + if (jsrTargetHeight > maxStack) maxStack = jsrTargetHeight + subroutineRetTargets.push(j.getNext) + enqInsn(j.label, jsrTargetHeight) + } else { + enqInsn(j.label, heightAfter) + val opc = j.getOpcode + if (opc != GOTO) enqInsnIndex(insnIndex + 1, heightAfter) // jump is conditional, so the successor is also a possible control flow target + } + case l: LookupSwitchInsnNode => var j = 0 while (j < l.labels.size) { enqInsn(l.labels.get(j), heightAfter); j += 1 } enqInsn(l.dflt, heightAfter) + case t: TableSwitchInsnNode => var j = 0 while (j < t.labels.size) { enqInsn(t.labels.get(j), heightAfter); j += 1 } enqInsn(t.dflt, heightAfter) + + case r: VarInsnNode if r.getOpcode == RET => + enqInsn(subroutineRetTargets.pop(), heightAfter) + case _ => val opc = insn.getOpcode if (opc != ATHROW && !isReturn(insn)) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InstructionResultSize.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InstructionResultSize.scala index 8d744f6d13..79e44a8503 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InstructionResultSize.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InstructionResultSize.scala @@ -33,14 +33,10 @@ object InstructionResultSize { case LDC => instruction.asInstanceOf[LdcInsnNode].cst match { - case _: java.lang.Integer | - _: java.lang.Float | - _: String | - _: Type | - _: Handle => 1 - case _: java.lang.Long | _: java.lang.Double => 2 + + case _ => 1 } case ILOAD | |