summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-12-12 20:22:26 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2015-12-13 09:41:50 +0100
commitb1fd1e83ab6ab3bf71b1a9c22794e8fd0c416d0f (patch)
tree5371e2b358cbf56ae93850d328b5d041975ccb54 /src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala
parentecbca547ac04ad33d336c0d41e72193a17dcf0ab (diff)
downloadscala-b1fd1e83ab6ab3bf71b1a9c22794e8fd0c416d0f.tar.gz
scala-b1fd1e83ab6ab3bf71b1a9c22794e8fd0c416d0f.tar.bz2
scala-b1fd1e83ab6ab3bf71b1a9c22794e8fd0c416d0f.zip
Fix push-pop elimination for values pushed by DUP
If a DUP is consumed by two POPs, ensure that the DUP and its producer are eliminated. Before, only the DUP was eliminated, leaving an unused value on the stack.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala
index 4e81018451..2181f00850 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala
@@ -27,7 +27,7 @@ object InstructionStackEffect {
* This method requires the `frame` to be in the state **before** executing / interpreting the
* `insn`.
*/
- def forAsmAnalysis[V <: Value](insn: AbstractInsnNode, frame: Frame[V]): Int = computeConsProd(insn, frame = frame)
+ def forAsmAnalysis[V <: Value](insn: AbstractInsnNode, frame: Frame[V]): Int = computeConsProd(insn, forClassfile = false, conservative = false, frame = frame)
/**
* Returns the maximal possible growth of the stack when executing `insn`. The returned value
@@ -41,7 +41,7 @@ object InstructionStackEffect {
* allows looking up the sizes of values on the stack.
*/
def maxStackGrowth(insn: AbstractInsnNode): Int = {
- val prodCons = computeConsProd(insn, conservative = true)
+ val prodCons = computeConsProd(insn, forClassfile = false, conservative = true)
prod(prodCons) - cons(prodCons)
}
@@ -50,7 +50,7 @@ object InstructionStackEffect {
* (the `cons` / `prod` extract individual values). The returned values are correct for writing
* into a classfile (see doc on the `analysis` package object).
*/
- def forClassfile(insn: AbstractInsnNode): Int = computeConsProd(insn, forClassfile = true)
+ def forClassfile(insn: AbstractInsnNode): Int = computeConsProd(insn, forClassfile = true, conservative = false)
private def invokeConsProd(methodDesc: String, insn: AbstractInsnNode, forClassfile: Boolean): Int = {
val consumesReceiver = insn.getOpcode != INVOKESTATIC && insn.getOpcode != INVOKEDYNAMIC
@@ -71,7 +71,7 @@ object InstructionStackEffect {
d == "J" || d == "D"
}
- private def computeConsProd[V <: Value](insn: AbstractInsnNode, forClassfile: Boolean = false, conservative: Boolean = false, frame: Frame[V] = null): Int = {
+ private def computeConsProd[V <: Value](insn: AbstractInsnNode, forClassfile: Boolean, conservative: Boolean, frame: Frame[V] = null): Int = {
// not used if `forClassfile || conservative`: in these cases, `frame` is allowed to be `null`
def peekStack(n: Int): V = frame.peekStack(n)