summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-10-07 21:18:50 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2014-11-04 13:56:44 +0100
commit46653d6fd5b160e148894012c06f07461aa18edb (patch)
tree7ec8f56039efde28fd474956f2913d56fed59abb /test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
parent8c6327dd3893363719dabff8d1a74286a5f9a1da (diff)
downloadscala-46653d6fd5b160e148894012c06f07461aa18edb.tar.gz
scala-46653d6fd5b160e148894012c06f07461aa18edb.tar.bz2
scala-46653d6fd5b160e148894012c06f07461aa18edb.zip
GenBCode: Eliminate redundant labels and line number nodes
Cleanup optimizations - remove line number nodes that describe no executable instructions - squash sequences of label nodes, remove unreferenced labels Command-line flags that allow enabling these transformations are added in a later comimt.
Diffstat (limited to 'test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala101
1 files changed, 101 insertions, 0 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
new file mode 100644
index 0000000000..213af4bcc1
--- /dev/null
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
@@ -0,0 +1,101 @@
+package scala.tools.nsc
+package backend.jvm
+package opt
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import scala.tools.asm.Opcodes._
+import org.junit.Assert._
+import scala.tools.testing.AssertUtil._
+
+import CodeGenTools._
+import scala.tools.partest.ASMConverters
+import ASMConverters._
+
+@RunWith(classOf[JUnit4])
+class EmptyLabelsAndLineNumbersTest {
+ import UnreachableCodeTest._ // ".dead" extension method on instructions
+
+ @Test
+ def removeEmptyLineNumbers(): Unit = {
+ val ops = List[(Instruction, Boolean)](
+ Label(1),
+ LineNumber(1, Label(1)),
+ Label(2),
+ Label(3),
+ Op(RETURN),
+
+ Label(4),
+ LineNumber(4, Label(4)).dead,
+ LineNumber(5, Label(4)),
+ Op(RETURN),
+
+ Label(5),
+ LineNumber(6, Label(5)).dead,
+ Label(6),
+ Label(7),
+ LineNumber(7, Label(7)),
+ Op(RETURN),
+
+ Label(9),
+ LineNumber(8, Label(9)).dead,
+ Label(10)
+ )
+
+ val method = genMethod()(ops.map(_._1): _*)
+ assertTrue(LocalOpt.removeEmptyLineNumbers(method))
+ assertSameCode(instructionsFromMethod(method), ops.filter(_._2).map(_._1))
+ }
+
+ @Test
+ def badlyLocatedLineNumbers(): Unit = {
+ def t(ops: Instruction*) =
+ assertThrows[AssertionError](LocalOpt.removeEmptyLineNumbers(genMethod()(ops: _*)))
+
+ // line numbers have to be right after their referenced label node
+ t(LineNumber(0, Label(1)), Label(1))
+ t(Label(0), Label(1), LineNumber(0, Label(0)))
+ }
+
+ @Test
+ def removeEmptyLabels(): Unit = {
+ val handler = List(ExceptionHandler(Label(4), Label(5), Label(6), Some("java/lang/Throwable")))
+ def ops(target1: Int, target2: Int, target3: Int, target4: Int, target5: Int, target6: Int) = List[(Instruction, Boolean)](
+ Label(1),
+ Label(2).dead,
+ Label(3).dead,
+ LineNumber(3, Label(target1)),
+ VarOp(ILOAD, 1),
+ Jump(IFGE, Label(target2)),
+
+ Label(4),
+ Label(5).dead,
+ Label(6).dead,
+ VarOp(ILOAD, 2),
+ Jump(IFGE, Label(target3)),
+
+ Label(7),
+ Label(8).dead,
+ Label(9).dead,
+ Op(RETURN),
+
+ LookupSwitch(LOOKUPSWITCH, Label(target4), List(1,2), List(Label(target4), Label(target5))),
+ TableSwitch(TABLESWITCH, 1, 2, Label(target4), List(Label(target4), Label(target5))),
+
+ Label(10),
+ LineNumber(10, Label(10)),
+ Label(11).dead,
+ LineNumber(12, Label(target6))
+ )
+
+ val method = genMethod(handlers = handler)(ops(2, 3, 8, 8, 9, 11).map(_._1): _*)
+ assertTrue(LocalOpt.removeEmptyLabelNodes(method))
+ val m = convertMethod(method)
+ assertSameCode(m.instructions, ops(1, 1, 7, 7, 7, 10).filter(_._2).map(_._1))
+ assertTrue(m.handlers match {
+ case List(ExceptionHandler(Label(4), Label(4), Label(4), _)) => true
+ case _ => false
+ })
+ }
+}