diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-10-07 21:18:50 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-11-04 13:56:44 +0100 |
commit | 46653d6fd5b160e148894012c06f07461aa18edb (patch) | |
tree | 7ec8f56039efde28fd474956f2913d56fed59abb /test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala | |
parent | 8c6327dd3893363719dabff8d1a74286a5f9a1da (diff) | |
download | scala-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.scala | 101 |
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 + }) + } +} |