summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
diff options
context:
space:
mode:
Diffstat (limited to 'test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala52
1 files changed, 25 insertions, 27 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
index 46f06d1d39..63bbcc396b 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
@@ -2,17 +2,15 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+import org.junit.Test
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.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
+import scala.tools.testing.BytecodeTesting._
import scala.tools.testing.ClearAfterClass
@RunWith(classOf[JUnit4])
@@ -20,12 +18,12 @@ class UnreachableCodeTest extends ClearAfterClass {
// jvm-1.6 enables emitting stack map frames, which impacts the code generation wrt dead basic blocks,
// see comment in BCodeBodyBuilder
val methodOptCompiler = cached("methodOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:method"))
- val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
- val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
+ val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
+ val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
def assertEliminateDead(code: (Instruction, Boolean)*): Unit = {
val method = genMethod()(code.map(_._1): _*)
- dceCompiler.genBCode.bTypes.localOpt.removeUnreachableCodeImpl(method, "C")
+ dceCompiler.global.genBCode.bTypes.localOpt.removeUnreachableCodeImpl(method, "C")
val nonEliminated = instructionsFromMethod(method)
val expectedLive = code.filter(_._2).map(_._1).toList
assertSameCode(nonEliminated, expectedLive)
@@ -112,10 +110,10 @@ class UnreachableCodeTest extends ClearAfterClass {
@Test
def basicEliminationCompiler(): Unit = {
val code = "def f: Int = { return 1; 2 }"
- val withDce = singleMethodInstructions(dceCompiler)(code)
+ val withDce = dceCompiler.compileInstructions(code)
assertSameCode(withDce.dropNonOp, List(Op(ICONST_1), Op(IRETURN)))
- val noDce = singleMethodInstructions(noOptCompiler)(code)
+ val noDce = noOptCompiler.compileInstructions(code)
// The emitted code is ICONST_1, IRETURN, ICONST_2, IRETURN. The latter two are dead.
//
@@ -141,23 +139,23 @@ class UnreachableCodeTest extends ClearAfterClass {
def wrapInDefault(code: Instruction*) = List(Label(0), LineNumber(1, Label(0))) ::: code.toList ::: List(Label(1))
val code = "def f: Int = { return 0; try { 1 } catch { case _: Exception => 2 } }"
- val m = singleMethod(dceCompiler)(code)
+ val m = dceCompiler.compileMethod(code)
assertTrue(m.handlers.isEmpty) // redundant (if code is gone, handler is gone), but done once here for extra safety
assertSameCode(m.instructions,
wrapInDefault(Op(ICONST_0), Op(IRETURN)))
val code2 = "def f: Unit = { try { } catch { case _: Exception => () }; () }"
// requires fixpoint optimization of methodOptCompiler (dce alone is not enough): first the handler is eliminated, then it's dead catch block.
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code2), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code2), wrapInDefault(Op(RETURN)))
val code3 = "def f: Unit = { try { } catch { case _: Exception => try { } catch { case _: Exception => () } }; () }"
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code3), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code3), wrapInDefault(Op(RETURN)))
// this example requires two iterations to get rid of the outer handler.
// the first iteration of DCE cannot remove the inner handler. then the inner (empty) handler is removed.
// then the second iteration of DCE removes the inner catch block, and then the outer handler is removed.
val code4 = "def f: Unit = { try { try { } catch { case _: Exception => () } } catch { case _: Exception => () }; () }"
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code4), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code4), wrapInDefault(Op(RETURN)))
}
@Test // test the dce-testing tools
@@ -174,7 +172,7 @@ class UnreachableCodeTest extends ClearAfterClass {
}
@Test
- def bytecodeEquivalence: Unit = {
+ def bytecodeEquivalence(): Unit = {
assertTrue(List(VarOp(ILOAD, 1)) ===
List(VarOp(ILOAD, 2)))
assertTrue(List(VarOp(ILOAD, 1), VarOp(ISTORE, 1)) ===
@@ -216,35 +214,35 @@ class UnreachableCodeTest extends ClearAfterClass {
| def t4 = cons(nt)
|}
""".stripMargin
- val List(c) = compileClasses(noOptCompiler)(code)
+ val c = noOptCompiler.compileClass(code)
- assertSameSummary(getSingleMethod(c, "nl"), List(ACONST_NULL, ARETURN))
+ assertSameSummary(getMethod(c, "nl"), List(ACONST_NULL, ARETURN))
- assertSameSummary(getSingleMethod(c, "nt"), List(
+ assertSameSummary(getMethod(c, "nt"), List(
NEW, DUP, LDC, "<init>", ATHROW))
- assertSameSummary(getSingleMethod(c, "t1"), List(
+ assertSameSummary(getMethod(c, "t1"), List(
ALOAD, ACONST_NULL, "cons", RETURN))
// GenBCode introduces POP; ACONST_NULL after loading an expression of type scala.runtime.Null$,
// see comment in BCodeBodyBuilder.adapt
- assertSameSummary(getSingleMethod(c, "t2"), List(
+ assertSameSummary(getMethod(c, "t2"), List(
ALOAD, ALOAD, "nl", POP, ACONST_NULL, "cons", RETURN))
// the bytecode generated by GenBCode is ... ATHROW; INVOKEVIRTUAL C.cons; RETURN
// the ASM classfile writer creates a new basic block (creates a label) right after the ATHROW
// and replaces all instructions by NOP*; ATHROW, see comment in BCodeBodyBuilder.adapt
// NOTE: DCE is enabled by default and gets rid of the redundant code (tested below)
- assertSameSummary(getSingleMethod(c, "t3"), List(
+ assertSameSummary(getMethod(c, "t3"), List(
ALOAD, NEW, DUP, LDC, "<init>", ATHROW, NOP, NOP, NOP, ATHROW))
// GenBCode introduces an ATHROW after the invocation of C.nt, see BCodeBodyBuilder.adapt
// NOTE: DCE is enabled by default and gets rid of the redundant code (tested below)
- assertSameSummary(getSingleMethod(c, "t4"), List(
+ assertSameSummary(getMethod(c, "t4"), List(
ALOAD, ALOAD, "nt", ATHROW, NOP, NOP, NOP, ATHROW))
- val List(cDCE) = compileClasses(dceCompiler)(code)
- assertSameSummary(getSingleMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW))
- assertSameSummary(getSingleMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW))
+ val cDCE = dceCompiler.compileClass(code)
+ assertSameSummary(getMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW))
+ assertSameSummary(getMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW))
}
}