From ba510abcdcf176c06ba93c8e9dc6398015877f5e Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 20 May 2016 12:22:06 +0200 Subject: Clean up bytecode testing methods. --- test/junit/scala/issues/BytecodeTest.scala | 84 ++++--- .../junit/scala/issues/OptimizedBytecodeTest.scala | 58 ++--- .../tools/nsc/backend/jvm/DefaultMethodTest.scala | 2 +- .../tools/nsc/backend/jvm/DirectCompileTest.scala | 16 +- .../tools/nsc/backend/jvm/IndyLambdaTest.scala | 10 +- .../tools/nsc/backend/jvm/IndySammyTest.scala | 14 +- .../tools/nsc/backend/jvm/StringConcatTest.scala | 4 +- .../jvm/analysis/NullnessAnalyzerTest.scala | 22 +- .../jvm/analysis/ProdConsAnalyzerTest.scala | 68 +++--- .../tools/nsc/backend/jvm/opt/AnalyzerTest.scala | 8 +- .../tools/nsc/backend/jvm/opt/CallGraphTest.scala | 10 +- .../nsc/backend/jvm/opt/ClosureOptimizerTest.scala | 20 +- .../jvm/opt/CompactLocalVariablesTest.scala | 4 +- .../jvm/opt/EmptyExceptionHandlersTest.scala | 8 +- .../nsc/backend/jvm/opt/InlineWarningTest.scala | 18 +- .../jvm/opt/InlinerSeparateCompilationTest.scala | 14 +- .../tools/nsc/backend/jvm/opt/InlinerTest.scala | 260 ++++++++++----------- .../nsc/backend/jvm/opt/MethodLevelOptsTest.scala | 156 ++++++------- .../nsc/backend/jvm/opt/UnreachableCodeTest.scala | 32 +-- .../backend/jvm/opt/UnusedLocalVariablesTest.scala | 17 +- .../nsc/transform/patmat/PatmatBytecodeTest.scala | 48 ++-- .../scala/tools/testing/BytecodeTesting.scala | 85 +++++-- 22 files changed, 496 insertions(+), 462 deletions(-) diff --git a/test/junit/scala/issues/BytecodeTest.scala b/test/junit/scala/issues/BytecodeTest.scala index 3fd5e3a222..0bb87a4ea6 100644 --- a/test/junit/scala/issues/BytecodeTest.scala +++ b/test/junit/scala/issues/BytecodeTest.scala @@ -36,10 +36,10 @@ class BytecodeTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) - assertTrue(getSingleMethod(c, "f").instructions.count(_.isInstanceOf[TableSwitch]) == 1) - assertTrue(getSingleMethod(c, "g").instructions.count(_.isInstanceOf[LookupSwitch]) == 1) + assertTrue(getInstructions(c, "f").count(_.isInstanceOf[TableSwitch]) == 1) + assertTrue(getInstructions(c, "g").count(_.isInstanceOf[LookupSwitch]) == 1) } @Test @@ -99,7 +99,7 @@ class BytecodeTest extends BytecodeTesting { """.stripMargin val List(mirror, module) = compileClasses(code) - val unapplyLineNumbers = getSingleMethod(module, "unapply").instructions.filter(_.isInstanceOf[LineNumber]) + val unapplyLineNumbers = getInstructions(module, "unapply").filter(_.isInstanceOf[LineNumber]) assert(unapplyLineNumbers == List(LineNumber(2, Label(0))), unapplyLineNumbers) val expected = List( @@ -122,7 +122,7 @@ class BytecodeTest extends BytecodeTesting { Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false) ) - val mainIns = getSingleMethod(module, "main").instructions filter { + val mainIns = getInstructions(module, "main") filter { case _: LineNumber | _: Invoke | _: Jump => true case _ => false } @@ -144,24 +144,24 @@ class BytecodeTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) // t1: no unnecessary GOTOs - assertSameCode(getSingleMethod(c, "t1"), List( + assertSameCode(getMethod(c, "t1"), List( VarOp(ILOAD, 1), Jump(IFEQ, Label(6)), Op(ICONST_1), Jump(GOTO, Label(9)), Label(6), Op(ICONST_2), Label(9), Op(IRETURN))) // t2: no unnecessary GOTOs - assertSameCode(getSingleMethod(c, "t2"), List( + assertSameCode(getMethod(c, "t2"), List( VarOp(ILOAD, 1), IntOp(SIPUSH, 393), Jump(IF_ICMPNE, Label(7)), Op(ICONST_1), Jump(GOTO, Label(10)), Label(7), Op(ICONST_2), Label(10), Op(IRETURN))) // t3: Array == is translated to reference equality, AnyRef == to null checks and equals - assertSameCode(getSingleMethod(c, "t3"), List( + assertSameCode(getMethod(c, "t3"), List( // Array == VarOp(ALOAD, 1), VarOp(ALOAD, 2), Jump(IF_ACMPEQ, Label(23)), // AnyRef == @@ -180,13 +180,13 @@ class BytecodeTest extends BytecodeTesting { Label(13), Op(IRETURN)) // t4: one side is known null, so just a null check on the other - assertSameCode(getSingleMethod(c, "t4"), t4t5) + assertSameCode(getMethod(c, "t4"), t4t5) // t5: one side known null, so just a null check on the other - assertSameCode(getSingleMethod(c, "t5"), t4t5) + assertSameCode(getMethod(c, "t5"), t4t5) // t6: no unnecessary GOTOs - assertSameCode(getSingleMethod(c, "t6"), List( + assertSameCode(getMethod(c, "t6"), List( VarOp(ILOAD, 1), IntOp(BIPUSH, 10), Jump(IF_ICMPNE, Label(7)), VarOp(ILOAD, 2), Jump(IFNE, Label(12)), Label(7), VarOp(ILOAD, 1), Op(ICONST_1), Jump(IF_ICMPEQ, Label(16)), @@ -195,10 +195,10 @@ class BytecodeTest extends BytecodeTesting { Label(19), Op(IRETURN))) // t7: universal equality - assertInvoke(getSingleMethod(c, "t7"), "scala/runtime/BoxesRunTime", "equals") + assertInvoke(getMethod(c, "t7"), "scala/runtime/BoxesRunTime", "equals") // t8: no null checks invoking equals on modules and constants - assertSameCode(getSingleMethod(c, "t8"), List( + assertSameCode(getMethod(c, "t8"), List( Field(GETSTATIC, "scala/collection/immutable/Nil$", "MODULE$", "Lscala/collection/immutable/Nil$;"), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(10)), Ldc(LDC, ""), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(14)), Label(10), Op(ICONST_1), Jump(GOTO, Label(17)), @@ -207,13 +207,11 @@ class BytecodeTest extends BytecodeTesting { } object forwarderTestUtils { - def findMethods(cls: ClassNode, name: String): List[Method] = cls.methods.iterator.asScala.find(_.name == name).map(convertMethod).toList - import language.implicitConversions implicit def s2c(s: Symbol)(implicit classes: Map[String, ClassNode]): ClassNode = classes(s.name) def checkForwarder(c: ClassNode, target: String) = { - val List(f) = findMethods(c, "f") + val List(f) = getMethods(c, "f") assertSameCode(f, List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, target, "f", "()I", false), Op(IRETURN))) } } @@ -273,7 +271,7 @@ class BytecodeTest extends BytecodeTesting { implicit val classes = compileClasses(code).map(c => (c.name, c)).toMap val noForwarder = List('C1, 'C2, 'C3, 'C4, 'C10, 'C11, 'C12, 'C13, 'C16, 'C17) - for (c <- noForwarder) assertEquals(findMethods(c, "f"), Nil) + for (c <- noForwarder) assertEquals(getMethods(c, "f"), Nil) checkForwarder('C5, "T3") checkForwarder('C6, "T4") @@ -282,10 +280,10 @@ class BytecodeTest extends BytecodeTesting { checkForwarder('C9, "T5") checkForwarder('C14, "T4") checkForwarder('C15, "T5") - assertSameSummary(getSingleMethod('C18, "f"), List(BIPUSH, IRETURN)) + assertSameSummary(getMethod('C18, "f"), List(BIPUSH, IRETURN)) checkForwarder('C19, "T7") - assertSameCode(getSingleMethod('C19, "T7$$super$f"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "C18", "f", "()I", false), Op(IRETURN))) - assertInvoke(getSingleMethod('C20, "clone"), "T8", "clone") // mixin forwarder + assertSameCode(getMethod('C19, "T7$$super$f"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "C18", "f", "()I", false), Op(IRETURN))) + assertInvoke(getMethod('C20, "clone"), "T8", "clone") // mixin forwarder } @Test @@ -297,7 +295,7 @@ class BytecodeTest extends BytecodeTesting { |class C extends T1 with T2 """.stripMargin val List(c, t1, t2) = compileClasses(code) - assertEquals(findMethods(c, "f"), Nil) + assertEquals(getMethods(c, "f"), Nil) } @Test @@ -331,7 +329,7 @@ class BytecodeTest extends BytecodeTesting { implicit val classes = compileClasses(code, List(j1, j2, j3, j4)).map(c => (c.name, c)).toMap val noForwarder = List('K1, 'K2, 'K3, 'K4, 'K5, 'K6, 'K7, 'K8, 'K9, 'K10, 'K11) - for (c <- noForwarder) assertEquals(findMethods(c, "f"), Nil) + for (c <- noForwarder) assertEquals(getMethods(c, "f"), Nil) checkForwarder('K12, "T2") } @@ -340,13 +338,13 @@ class BytecodeTest extends BytecodeTesting { def invocationReceivers(): Unit = { val List(c1, c2, t, u) = compileClasses(invocationReceiversTestCode.definitions("Object")) // mixin forwarder in C1 - assertSameCode(getSingleMethod(c1, "clone"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "T", "clone", "()Ljava/lang/Object;", false), Op(ARETURN))) - assertInvoke(getSingleMethod(c1, "f1"), "T", "clone") - assertInvoke(getSingleMethod(c1, "f2"), "T", "clone") - assertInvoke(getSingleMethod(c1, "f3"), "C1", "clone") - assertInvoke(getSingleMethod(c2, "f1"), "T", "clone") - assertInvoke(getSingleMethod(c2, "f2"), "T", "clone") - assertInvoke(getSingleMethod(c2, "f3"), "C1", "clone") + assertSameCode(getMethod(c1, "clone"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "T", "clone", "()Ljava/lang/Object;", false), Op(ARETURN))) + assertInvoke(getMethod(c1, "f1"), "T", "clone") + assertInvoke(getMethod(c1, "f2"), "T", "clone") + assertInvoke(getMethod(c1, "f3"), "C1", "clone") + assertInvoke(getMethod(c2, "f1"), "T", "clone") + assertInvoke(getMethod(c2, "f2"), "T", "clone") + assertInvoke(getMethod(c2, "f3"), "C1", "clone") val List(c1b, c2b, tb, ub) = compileClasses(invocationReceiversTestCode.definitions("String")) def ms(c: ClassNode, n: String) = c.methods.asScala.toList.filter(_.name == n) @@ -357,11 +355,11 @@ class BytecodeTest extends BytecodeTesting { assert((c1Clone.access | Opcodes.ACC_BRIDGE) != 0) assertSameCode(convertMethod(c1Clone), List(VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C1", "clone", "()Ljava/lang/String;", false), Op(ARETURN))) - def iv(m: Method) = getSingleMethod(c1b, "f1").instructions.collect({case i: Invoke => i}) - assertSameCode(iv(getSingleMethod(c1b, "f1")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) - assertSameCode(iv(getSingleMethod(c1b, "f2")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) + def iv(m: Method) = getInstructions(c1b, "f1").collect({case i: Invoke => i}) + assertSameCode(iv(getMethod(c1b, "f1")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) + assertSameCode(iv(getMethod(c1b, "f2")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) // invokeinterface T.clone in C1 is OK here because it is not an override of Object.clone (different siganture) - assertSameCode(iv(getSingleMethod(c1b, "f3")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) + assertSameCode(iv(getMethod(c1b, "f3")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true))) } @Test @@ -395,9 +393,9 @@ class BytecodeTest extends BytecodeTesting { | def f3(j: a.J) = j.f |} """.stripMargin - val List(c) = compileClasses(cC, javaCode = List((aC, "A.java"), (bC, "B.java"), (iC, "I.java"), (jC, "J.java"))) - assertInvoke(getSingleMethod(c, "f1"), "a/B", "f") // receiver needs to be B (A is not accessible in class C, package b) - assertInvoke(getSingleMethod(c, "f3"), "a/J", "f") // receiver needs to be J + val c = compileClass(cC, javaCode = List((aC, "A.java"), (bC, "B.java"), (iC, "I.java"), (jC, "J.java"))) + assertInvoke(getMethod(c, "f1"), "a/B", "f") // receiver needs to be B (A is not accessible in class C, package b) + assertInvoke(getMethod(c, "f3"), "a/J", "f") // receiver needs to be J } @Test @@ -411,11 +409,11 @@ class BytecodeTest extends BytecodeTesting { | |} """.stripMargin - val List(c) = compileClasses(code) - assertInvoke(getSingleMethod(c, "f1"), "[Ljava/lang/String;", "clone") // array descriptor as receiver - assertInvoke(getSingleMethod(c, "f2"), "java/lang/Object", "hashCode") // object receiver - assertInvoke(getSingleMethod(c, "f3"), "java/lang/Object", "hashCode") - assertInvoke(getSingleMethod(c, "f4"), "java/lang/Object", "toString") + val c = compileClass(code) + assertInvoke(getMethod(c, "f1"), "[Ljava/lang/String;", "clone") // array descriptor as receiver + assertInvoke(getMethod(c, "f2"), "java/lang/Object", "hashCode") // object receiver + assertInvoke(getMethod(c, "f3"), "java/lang/Object", "hashCode") + assertInvoke(getMethod(c, "f4"), "java/lang/Object", "toString") } @Test @@ -423,7 +421,7 @@ class BytecodeTest extends BytecodeTesting { // see comment in SpecializeTypes.forwardCtorCall val code = "case class C[@specialized(Int) T](_1: T)" val List(c, cMod, cSpec) = compileClasses(code) - assertSameSummary(getSingleMethod(cSpec, ""), + assertSameSummary(getMethod(cSpec, ""), // pass `null` to super constructor, no box-unbox, no Integer created List(ALOAD, ILOAD, PUTFIELD, ALOAD, ACONST_NULL, "", RETURN)) } diff --git a/test/junit/scala/issues/OptimizedBytecodeTest.scala b/test/junit/scala/issues/OptimizedBytecodeTest.scala index b074215534..af1c50acac 100644 --- a/test/junit/scala/issues/OptimizedBytecodeTest.scala +++ b/test/junit/scala/issues/OptimizedBytecodeTest.scala @@ -27,8 +27,8 @@ class OptimizedBytecodeTest extends BytecodeTesting { | def t(): Unit = while (true) m("...") |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List(Label(0), Jump(GOTO, Label(0)))) + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List(Label(0), Jump(GOTO, Label(0)))) } @Test @@ -45,12 +45,12 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) - assertSameSummary(getSingleMethod(c, "t"), List( + assertSameSummary(getMethod(c, "t"), List( LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "C$$$anonfun$1", IRETURN)) - assertSameSummary(getSingleMethod(c, "C$$$anonfun$1"), List(LDC, "C$$$anonfun$2", IRETURN)) - assertSameSummary(getSingleMethod(c, "C$$$anonfun$2"), List(-1 /*A*/, GOTO /*A*/)) + assertSameSummary(getMethod(c, "C$$$anonfun$1"), List(LDC, "C$$$anonfun$2", IRETURN)) + assertSameSummary(getMethod(c, "C$$$anonfun$2"), List(-1 /*A*/, GOTO /*A*/)) } @Test @@ -72,7 +72,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { |} """.stripMargin val List(c, t, tMod) = compileClasses(code, allowMessage = _.msg.contains("not be exhaustive")) - assertSameSummary(getSingleMethod(c, "t"), List(GETSTATIC, "$qmark$qmark$qmark", ATHROW)) + assertSameSummary(getMethod(c, "t"), List(GETSTATIC, "$qmark$qmark$qmark", ATHROW)) } @Test @@ -109,7 +109,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - compileClasses(code) + compileToBytes(code) } @Test @@ -120,7 +120,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { """.stripMargin val c2 = "class C { def t = warmup.Warmup.filter[Any](x => false) }" val List(c, _, _) = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs) - assertInvoke(getSingleMethod(c, "t"), "warmup/Warmup$", "filter") + assertInvoke(getMethod(c, "t"), "warmup/Warmup$", "filter") } @Test @@ -134,7 +134,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - compileClasses(code) + compileToBytes(code) } @Test @@ -162,7 +162,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - compileClasses(code) + compileToBytes(code) } @Test @@ -178,7 +178,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - compileClasses(code) + compileToBytes(code) } @Test @@ -217,8 +217,8 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameSummary(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameSummary(getMethod(c, "t"), List( ALOAD /*1*/, INSTANCEOF /*Some*/, IFNE /*A*/, ALOAD /*0*/, "getInt", POP, -1 /*A*/, BIPUSH, IRETURN)) @@ -236,8 +236,8 @@ class OptimizedBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameSummary(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameSummary(getMethod(c, "t"), List( -1 /*A*/, ILOAD /*1*/, TABLESWITCH, -1, ALOAD, "pr", RETURN, -1, ALOAD, "pr", RETURN, @@ -261,8 +261,8 @@ class OptimizedBytecodeTest extends BytecodeTesting { """.stripMargin val cls = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs) - val c = cls.find(_.name == "C").get - assertSameSummary(getSingleMethod(c, "t"), List( + val c = findClass(cls, "C") + assertSameSummary(getMethod(c, "t"), List( GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW, // module load and null checks not yet eliminated -1, ICONST_1, GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW, -1, ICONST_2, IADD, IRETURN)) @@ -299,11 +299,11 @@ class OptimizedBytecodeTest extends BytecodeTesting { | def f2b() = identity(wrapper2(5)) // not inlined |} """.stripMargin - val List(c) = compileClasses(code, allowMessage = _.msg.contains("exception handler declared in the inlined method")) - assertInvoke(getSingleMethod(c, "f1a"), "C", "C$$$anonfun$1") - assertInvoke(getSingleMethod(c, "f1b"), "C", "wrapper1") - assertInvoke(getSingleMethod(c, "f2a"), "C", "C$$$anonfun$3") - assertInvoke(getSingleMethod(c, "f2b"), "C", "wrapper2") + val c = compileClass(code, allowMessage = _.msg.contains("exception handler declared in the inlined method")) + assertInvoke(getMethod(c, "f1a"), "C", "C$$$anonfun$1") + assertInvoke(getMethod(c, "f1b"), "C", "wrapper1") + assertInvoke(getMethod(c, "f2a"), "C", "C$$$anonfun$3") + assertInvoke(getMethod(c, "f2b"), "C", "wrapper2") } @Test @@ -317,8 +317,8 @@ class OptimizedBytecodeTest extends BytecodeTesting { | def t = mbarray_apply_minibox(null, 0) |} """.stripMargin - val List(c) = compileClasses(code) - assertNoInvoke(getSingleMethod(c, "t")) + val c = compileClass(code) + assertNoInvoke(getMethod(c, "t")) } @Test @@ -336,7 +336,7 @@ class OptimizedBytecodeTest extends BytecodeTesting { |class Listt """.stripMargin val List(c, nil, nilMod, listt) = compileClasses(code) - assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1") + assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1") } @Test @@ -355,13 +355,13 @@ class OptimizedBytecodeTest extends BytecodeTesting { |} """.stripMargin val List(c, f) = compileClasses(code) - assertInvoke(getSingleMethod(c, "crash"), "C", "map") + assertInvoke(getMethod(c, "crash"), "C", "map") } @Test def optimiseEnablesNewOpt(): Unit = { val code = """class C { def t = (1 to 10) foreach println }""" - val List(c) = readAsmClasses(newCompiler(extraArgs = "-optimise -deprecation").compile(code, allowMessage = _.msg.contains("is deprecated"))) - assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath + val List(c) = readAsmClasses(newCompiler(extraArgs = "-optimise -deprecation").compileToBytes(code, allowMessage = _.msg.contains("is deprecated"))) + assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala index b538ae0bc6..c9a958ee4f 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala @@ -26,7 +26,7 @@ class DefaultMethodTest extends BytecodeTesting { case _ => super.transform(tree) } } - val asmClasses: List[ClassNode] = readAsmClasses(compiler.compileTransformed(code, Nil, makeFooDefaultMethod.transform(_))) + val asmClasses: List[ClassNode] = compiler.compileClassesTransformed(code, Nil, makeFooDefaultMethod.transform(_)) val foo = asmClasses.head.methods.iterator.asScala.toList.last assertTrue("default method should not be abstract", (foo.access & Opcodes.ACC_ABSTRACT) == 0) assertTrue("default method body emitted", foo.instructions.size() > 0) diff --git a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala index 65b4264ee9..7fdfb31577 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala @@ -17,7 +17,7 @@ class DirectCompileTest extends BytecodeTesting { @Test def testCompile(): Unit = { - val List(("C.class", bytes)) = compile( + val List(("C.class", bytes)) = compileToBytes( """class C { | def f = 1 |} @@ -45,21 +45,19 @@ class DirectCompileTest extends BytecodeTesting { """def f = 10 |def g = f """.stripMargin) - assertTrue(f.name == "f") - assertTrue(g.name == "g") - assertSameCode(instructionsFromMethod(f).dropNonOp, + assertSameCode(f.instructions.dropNonOp, List(IntOp(BIPUSH, 10), Op(IRETURN))) - assertSameCode(instructionsFromMethod(g).dropNonOp, + assertSameCode(g.instructions.dropNonOp, List(VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "f", "()I", itf = false), Op(IRETURN))) } @Test def testDropNonOpAliveLabels(): Unit = { // makes sure that dropNoOp doesn't drop labels that are being used - val List(f) = compileMethods("""def f(x: Int) = if (x == 0) "a" else "b"""") - assertSameCode(instructionsFromMethod(f).dropLinesFrames, List( + val is = compileInstructions("""def f(x: Int) = if (x == 0) "a" else "b"""") + assertSameCode(is.dropLinesFrames, List( Label(0), VarOp(ILOAD, 1), Op(ICONST_0), @@ -79,7 +77,7 @@ class DirectCompileTest extends BytecodeTesting { val codeA = "class A { def f = 1 }" val codeB = "class B extends A { def g = f }" val List(a, b) = compileClassesSeparately(List(codeA, codeB)) - val ins = getSingleMethod(b, "g").instructions + val ins = getInstructions(b, "g") assert(ins exists { case Invoke(_, "B", "f", _, _) => true case _ => false @@ -88,6 +86,6 @@ class DirectCompileTest extends BytecodeTesting { @Test def compileErroneous(): Unit = { - compileClasses("class C { def f: String = 1 }", allowMessage = _.msg contains "type mismatch") + compileToBytes("class C { def f: String = 1 }", allowMessage = _.msg contains "type mismatch") } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala index 22ced47a02..ac2aab01dc 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala @@ -13,7 +13,7 @@ class IndyLambdaTest extends BytecodeTesting { @Test def boxingBridgeMethodUsedSelectively(): Unit = { def implMethodDescriptorFor(code: String): String = { - val method = compileMethods(s"""def f = $code """).find(_.name == "f").get + val method = compileAsmMethods(s"""def f = $code """).find(_.name == "f").get val x = method.instructions.iterator.asScala.toList x.flatMap { case insn : InvokeDynamicInsnNode => insn.bsmArgs.collect { case h : Handle => h.getDesc } @@ -46,17 +46,17 @@ class IndyLambdaTest extends BytecodeTesting { assertEquals("(I)I", implMethodDescriptorFor("(x: Int) => x")) // non-builtin sams are like specialized functions - compileClasses("class VC(private val i: Int) extends AnyVal; trait FunVC { def apply(a: VC): VC }") + compileToBytes("class VC(private val i: Int) extends AnyVal; trait FunVC { def apply(a: VC): VC }") assertEquals("(I)I", implMethodDescriptorFor("((x: VC) => x): FunVC")) - compileClasses("trait Fun1[T, U] { def apply(a: T): U }") + compileToBytes("trait Fun1[T, U] { def apply(a: T): U }") assertEquals(s"($obj)$str", implMethodDescriptorFor("(x => x.toString): Fun1[Int, String]")) assertEquals(s"($obj)$obj", implMethodDescriptorFor("(x => println(x)): Fun1[Int, Unit]")) assertEquals(s"($obj)$str", implMethodDescriptorFor("((x: VC) => \"\") : Fun1[VC, String]")) assertEquals(s"($str)$obj", implMethodDescriptorFor("((x: String) => new VC(0)) : Fun1[String, VC]")) - compileClasses("trait Coll[A, Repr] extends Any") - compileClasses("final class ofInt(val repr: Array[Int]) extends AnyVal with Coll[Int, Array[Int]]") + compileToBytes("trait Coll[A, Repr] extends Any") + compileToBytes("final class ofInt(val repr: Array[Int]) extends AnyVal with Coll[Int, Array[Int]]") assertEquals(s"([I)$obj", implMethodDescriptorFor("((xs: Array[Int]) => new ofInt(xs)): Array[Int] => Coll[Int, Array[Int]]")) } diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala index d7c1f191d0..2bcbcc870c 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala @@ -39,13 +39,13 @@ class IndySammyTest extends BytecodeTesting { def test(from: String, to: String, arg: String, body: String => String = x => x) (expectedSig: String, lamBody: List[Instruction], appArgs: List[Instruction], ret: Instruction) (allowMessage: StoreReporter#Info => Boolean = _ => false) = { - val cls = compileClasses(s"${classPrologue(from, to)}") - val methodNodes = compileMethods(lamDef(from, to, body) +";"+ appDef(arg), allowMessage) + val List(funClass, vcClass, vcCompanion) = compileClasses(s"${classPrologue(from, to)}") + val c = compileClass(s"class C { ${lamDef(from, to, body)}; ${appDef(arg)} }", allowMessage = allowMessage) - val applySig = cls.head.methods.get(0).desc - val anonfun = methodNodes.find(_.name contains "$anonfun$").map(convertMethod).get - val lamInsn = methodNodes.find(_.name == "lam").map(instructionsFromMethod).get.dropNonOp - val applyInvoke = methodNodes.find(_.name == "app").map(convertMethod).get + val applySig = getAsmMethod(funClass, "apply").desc + val anonfun = getMethod(c, "C$$$anonfun$1") + val lamInsn = getInstructions(c, "lam").dropNonOp + val applyInvoke = getMethod(c, "app") assertEquals(expectedSig, applySig) assert(lamInsn.length == 2 && lamInsn.head.isInstanceOf[InvokeDynamic], lamInsn) @@ -140,7 +140,7 @@ class IndySammyTest extends BytecodeTesting { // Tests ThisReferringMethodsTraverser @Test def testStaticIfNoThisReference: Unit = { - val methodNodes = compileMethods("def foo = () => () => () => 42") + val methodNodes = compileAsmMethods("def foo = () => () => () => 42") methodNodes.forall(m => !m.name.contains("anonfun") || (m.access & ACC_STATIC) == ACC_STATIC) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala b/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala index f231df8af0..af2c8f9ce0 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala @@ -50,9 +50,9 @@ class StringConcatTest extends BytecodeTesting { | chrs: Array[Char]) = this + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) - def invokeNameDesc(m: String): List[String] = getSingleMethod(c, m).instructions collect { + def invokeNameDesc(m: String): List[String] = getInstructions(c, m) collect { case Invoke(_, _, name, desc, _) => name + desc } assertEquals(invokeNameDesc("t1"), List( diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala index 358a461026..b0a86dfd28 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala @@ -24,7 +24,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { def newNullnessAnalyzer(methodNode: MethodNode, classInternalName: InternalName = "C") = new AsmAnalyzer(methodNode, classInternalName, new NullnessAnalyzer(global.genBCode.bTypes)) def testNullness(analyzer: AsmAnalyzer[NullnessValue], method: MethodNode, query: String, index: Int, nullness: NullnessValue): Unit = { - for (i <- findInstr(method, query)) { + for (i <- findInstrs(method, query)) { val r = analyzer.frameAt(i).getValue(index) assertTrue(s"Expected: $nullness, found: $r. At instr ${textify(i)}", nullness == r) } @@ -50,7 +50,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { @Test def showNullnessFramesTest(): Unit = { - val List(m) = compileMethods("def f = this.toString") + val m = compileAsmMethod("def f = this.toString") // NOTE: the frame for an instruction represents the state *before* executing that instr. // So in the frame for `ALOAD 0`, the stack is still empty. @@ -68,14 +68,14 @@ class NullnessAnalyzerTest extends BytecodeTesting { @Test def thisNonNull(): Unit = { - val List(m) = compileMethods("def f = this.toString") + val m = compileAsmMethod("def f = this.toString") val a = newNullnessAnalyzer(m) testNullness(a, m, "ALOAD 0", 0, NotNullValue) } @Test def instanceMethodCall(): Unit = { - val List(m) = compileMethods("def f(a: String) = a.trim") + val m = compileAsmMethod("def f(a: String) = a.trim") val a = newNullnessAnalyzer(m) testNullness(a, m, "INVOKEVIRTUAL java/lang/String.trim", 1, UnknownValue1) testNullness(a, m, "ARETURN", 1, NotNullValue) @@ -83,7 +83,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { @Test def constructorCall(): Unit = { - val List(m) = compileMethods("def f = { val a = new Object; a.toString }") + val m = compileAsmMethod("def f = { val a = new Object; a.toString }") val a = newNullnessAnalyzer(m) // for reference, the output of showAllNullnessFrames(a, m) - note that the frame represents the state *before* executing the instr. @@ -108,7 +108,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { @Test def explicitNull(): Unit = { - val List(m) = compileMethods("def f = { var a: Object = null; a }") + val m = compileAsmMethod("def f = { var a: Object = null; a }") val a = newNullnessAnalyzer(m) for ((insn, index, nullness) <- List( ("+ACONST_NULL", 2, NullValue), @@ -119,14 +119,14 @@ class NullnessAnalyzerTest extends BytecodeTesting { @Test def stringLiteralsNotNull(): Unit = { - val List(m) = compileMethods("""def f = { val a = "hi"; a.trim }""") + val m = compileAsmMethod("""def f = { val a = "hi"; a.trim }""") val a = newNullnessAnalyzer(m) testNullness(a, m, "+ASTORE 1", 1, NotNullValue) } @Test def newArraynotNull() { - val List(m) = compileMethods("def f = { val a = new Array[Int](2); a(0) }") + val m = compileAsmMethod("def f = { val a = new Array[Int](2); a(0) }") val a = newNullnessAnalyzer(m) testNullness(a, m, "+NEWARRAY T_INT", 2, NotNullValue) // new array on stack testNullness(a, m, "+ASTORE 1", 1, NotNullValue) // local var (a) @@ -144,7 +144,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { | a.toString |} """.stripMargin - val List(m) = compileMethods(code) + val m = compileAsmMethod(code) val a = newNullnessAnalyzer(m) val toSt = "+INVOKEVIRTUAL java/lang/Object.toString" testNullness(a, m, toSt, 3, UnknownValue1) @@ -170,7 +170,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { | // d is null here, assinged in both branches. |} """.stripMargin - val List(m) = compileMethods(code) + val m = compileAsmMethod(code) val a = newNullnessAnalyzer(m) val trim = "INVOKEVIRTUAL java/lang/String.trim" @@ -206,7 +206,7 @@ class NullnessAnalyzerTest extends BytecodeTesting { | a.asInstanceOf[String].trim // the stack value (LOAD of local a) is still not-null after the CHECKCAST |} """.stripMargin - val List(m) = compileMethods(code) + val m = compileAsmMethod(code) val a = newNullnessAnalyzer(m) val instof = "+INSTANCEOF" diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala index be10370312..fc26785237 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala @@ -49,9 +49,9 @@ class ProdConsAnalyzerTest extends BytecodeTesting { @Test def parameters(): Unit = { - val List(m) = compileMethods("def f = this.toString") + val m = compileAsmMethod("def f = this.toString") val a = new ProdConsAnalyzer(m, "C") - val call = findInstr(m, "INVOKEVIRTUAL").head + val call = findInstr(m, "INVOKEVIRTUAL") testSingleInsn(a.producersForValueAt(call, 1), "ALOAD 0") // producer of stack value testSingleInsn(a.producersForInputsOf(call), "ALOAD 0") @@ -84,55 +84,55 @@ class ProdConsAnalyzerTest extends BytecodeTesting { m.maxStack = 1 val a = new ProdConsAnalyzer(m, "C") - val ifne = findInstr(m, "IFNE").head + val ifne = findInstr(m, "IFNE") testSingleInsn(a.producersForValueAt(ifne, 1), "ParameterProducer") - val ret = findInstr(m, "IRETURN").head + val ret = findInstr(m, "IRETURN") testMultiInsns(a.producersForValueAt(ret, 1), List("ParameterProducer", "ISTORE 1")) } @Test def branching(): Unit = { - val List(m) = compileMethods("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }") + val m = compileAsmMethod("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }") val a = new ProdConsAnalyzer(m, "C") - val List(ret) = findInstr(m, "IRETURN") + val ret = findInstr(m, "IRETURN") testMultiInsns(a.producersForValueAt(ret, 2), List("ISTORE 2", "ISTORE 2")) testMultiInsns(a.initialProducersForValueAt(ret, 2), List("BIPUSH 12", "ParameterProducer")) - val List(bipush) = findInstr(m, "BIPUSH 12") + val bipush = findInstr(m, "BIPUSH 12") testSingleInsn(a.consumersOfOutputsFrom(bipush), "ISTORE 2") testSingleInsn(a.ultimateConsumersOfValueAt(bipush.getNext, 3), "IRETURN") } @Test def checkCast(): Unit = { - val List(m) = compileMethods("def f(o: Object) = o.asInstanceOf[String]") + val m = compileAsmMethod("def f(o: Object) = o.asInstanceOf[String]") val a = new ProdConsAnalyzer(m, "C") - assert(findInstr(m, "CHECKCAST java/lang/String").length == 1) + assert(findInstrs(m, "CHECKCAST java/lang/String").length == 1) - val List(ret) = findInstr(m, "ARETURN") + val ret = findInstr(m, "ARETURN") testSingleInsn(a.initialProducersForInputsOf(ret), "ParameterProducer(1)") } @Test def instanceOf(): Unit = { - val List(m) = compileMethods("def f(o: Object) = o.isInstanceOf[String]") + val m = compileAsmMethod("def f(o: Object) = o.isInstanceOf[String]") val a = new ProdConsAnalyzer(m, "C") - assert(findInstr(m, "INSTANCEOF java/lang/String").length == 1) + assert(findInstrs(m, "INSTANCEOF java/lang/String").length == 1) - val List(ret) = findInstr(m, "IRETURN") + val ret = findInstr(m, "IRETURN") testSingleInsn(a.initialProducersForInputsOf(ret), "INSTANCEOF") } @Test def unInitLocal(): Unit = { - val List(m) = compileMethods("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }") + val m = compileAsmMethod("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }") val a = new ProdConsAnalyzer(m, "C") - val List(store) = findInstr(m, "ISTORE") - val List(call) = findInstr(m, "INVOKEVIRTUAL") - val List(ret) = findInstr(m, "IRETURN") + val store = findInstr(m, "ISTORE") + val call = findInstr(m, "INVOKEVIRTUAL") + val ret = findInstr(m, "IRETURN") testSingleInsn(a.producersForValueAt(store, 2), "UninitializedLocalProducer(2)") testSingleInsn(a.producersForValueAt(call, 2), "ISTORE") @@ -141,11 +141,11 @@ class ProdConsAnalyzerTest extends BytecodeTesting { @Test def dupCopying(): Unit = { - val List(m) = compileMethods("def f = new Object") + val m = compileAsmMethod("def f = new Object") val a = new ProdConsAnalyzer(m, "C") - val List(newO) = findInstr(m, "NEW") - val List(constr) = findInstr(m, "INVOKESPECIAL") + val newO = findInstr(m, "NEW") + val constr = findInstr(m, "INVOKESPECIAL") testSingleInsn(a.producersForInputsOf(constr), "DUP") testSingleInsn(a.initialProducersForInputsOf(constr), "NEW") @@ -170,11 +170,11 @@ class ProdConsAnalyzerTest extends BytecodeTesting { m.maxStack = 4 val a = new ProdConsAnalyzer(m, "C") - val List(dup2) = findInstr(m, "DUP2") - val List(add) = findInstr(m, "IADD") - val List(swap) = findInstr(m, "SWAP") - val List(store) = findInstr(m, "ISTORE") - val List(ret) = findInstr(m, "IRETURN") + val dup2 = findInstr(m, "DUP2") + val add = findInstr(m, "IADD") + val swap = findInstr(m, "SWAP") + val store = findInstr(m, "ISTORE") + val ret = findInstr(m, "IRETURN") testMultiInsns(a.producersForInputsOf(dup2), List("ILOAD", "ILOAD")) testSingleInsn(a.consumersOfValueAt(dup2.getNext, 4), "IADD") @@ -205,9 +205,9 @@ class ProdConsAnalyzerTest extends BytecodeTesting { m.maxStack = 1 val a = new ProdConsAnalyzer(m, "C") - val List(inc) = findInstr(m, "IINC") - val List(load) = findInstr(m, "ILOAD") - val List(ret) = findInstr(m, "IRETURN") + val inc = findInstr(m, "IINC") + val load = findInstr(m, "ILOAD") + val ret = findInstr(m, "IRETURN") testSingleInsn(a.producersForInputsOf(inc), "ParameterProducer(1)") testSingleInsn(a.consumersOfOutputsFrom(inc), "ILOAD") @@ -223,12 +223,12 @@ class ProdConsAnalyzerTest extends BytecodeTesting { @Test def copyingInsns(): Unit = { - val List(m) = compileMethods("def f = 0l.asInstanceOf[Int]") + val m = compileAsmMethod("def f = 0l.asInstanceOf[Int]") val a = new ProdConsAnalyzer(m, "C") - val List(cnst) = findInstr(m, "LCONST_0") - val List(l2i) = findInstr(m, "L2I") // l2i is not a copying instruction - val List(ret) = findInstr(m, "IRETURN") + val cnst = findInstr(m, "LCONST_0") + val l2i = findInstr(m, "L2I") // l2i is not a copying instruction + val ret = findInstr(m, "IRETURN") testSingleInsn(a.consumersOfOutputsFrom(cnst), "L2I") testSingleInsn(a.ultimateConsumersOfOutputsFrom(cnst), "L2I") @@ -264,10 +264,10 @@ class ProdConsAnalyzerTest extends BytecodeTesting { m.maxStack = 2 val a = new ProdConsAnalyzer(m, "C") - val List(iadd) = findInstr(m, "IADD") + val iadd = findInstr(m, "IADD") val firstLoad = iadd.getPrevious.getPrevious assert(firstLoad.getOpcode == ILOAD) - val secondLoad = findInstr(m, "ISTORE").head.getPrevious + val secondLoad = findInstr(m, "ISTORE").getPrevious assert(secondLoad.getOpcode == ILOAD) testSingleInsn(a.producersForValueAt(iadd, 2), "ILOAD") diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala index a5fb1e7d17..025248ac28 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala @@ -32,17 +32,17 @@ class AnalyzerTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) val a = new AliasingAnalyzer(new BasicInterpreter) - val f = findAsmMethod(c, "f") + val f = getAsmMethod(c, "f") a.analyze("C", f) - val List(_, i2l) = findInstr(f, "I2L") + val List(_, i2l) = findInstrs(f, "I2L") val aliasesAtI2l = a.frameAt(i2l, f).asInstanceOf[AliasingFrame[_]].aliases assertEquals(aliasesAtI2l(1).iterator.toList, List(1, 8, 9)) // a, e and stack top assertEquals(aliasesAtI2l(4).iterator.toList, List(4, 6)) - val List(add) = findInstr(f, "LADD") + val add = findInstr(f, "LADD") val aliasesAtAdd = a.frameAt(add, f).asInstanceOf[AliasingFrame[_]].aliases assertEquals(aliasesAtAdd(1).iterator.toList, List(1, 8)) // after i2l the value on the stack is no longer an alias assertEquals(aliasesAtAdd(4).iterator.toList, List(4, 6, 10)) // c, d and stack top diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala index 900608837f..630416a925 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala @@ -104,10 +104,10 @@ class CallGraphTest extends BytecodeTesting { val List(cCls, cMod, dCls, testCls) = compile(code, checkMsg) assert(msgCount == 6, msgCount) - val List(cf1, cf2, cf3, cf4, cf5, cf6, cf7) = findAsmMethods(cCls, _.startsWith("f")) - val List(df1, df3) = findAsmMethods(dCls, _.startsWith("f")) - val g1 = findAsmMethod(cMod, "g1") - val List(t1, t2) = findAsmMethods(testCls, _.startsWith("t")) + val List(cf1, cf2, cf3, cf4, cf5, cf6, cf7) = getAsmMethods(cCls, _.startsWith("f")) + val List(df1, df3) = getAsmMethods(dCls, _.startsWith("f")) + val g1 = getAsmMethod(cMod, "g1") + val List(t1, t2) = getAsmMethods(testCls, _.startsWith("t")) val List(cf1Call, cf2Call, cf3Call, cf4Call, cf5Call, cf6Call, cf7Call, cg1Call) = callsInMethod(t1) val List(df1Call, df2Call, df3Call, df4Call, df5Call, df6Call, df7Call, dg1Call) = callsInMethod(t2) @@ -143,7 +143,7 @@ class CallGraphTest extends BytecodeTesting { |} """.stripMargin val List(c) = compile(code) - val m = findAsmMethod(c, "m") + val m = getAsmMethod(c, "m") val List(fn) = callsInMethod(m) val forNameMeth = byteCodeRepository.methodNode("java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;").get._1 val classTp = classBTypeFromInternalName("java/lang/Class") diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala index ddd95ddc02..218b02f822 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala @@ -26,9 +26,9 @@ class ClosureOptimizerTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - val t = findAsmMethod(c, "t") - val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Nothing$") + val c = compileClass(code) + val t = getAsmMethod(c, "t") + val bodyCall = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Nothing$") assert(bodyCall.getNext.getOpcode == ATHROW) } @@ -42,9 +42,9 @@ class ClosureOptimizerTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - val t = findAsmMethod(c, "t") - val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Null$") + val c = compileClass(code) + val t = getAsmMethod(c, "t") + val bodyCall = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Null$") assert(bodyCall.getNext.getOpcode == POP) assert(bodyCall.getNext.getNext.getOpcode == ACONST_NULL) } @@ -59,8 +59,8 @@ class ClosureOptimizerTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List(VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "scala/collection/immutable/List", "head", "()Ljava/lang/Object;", false), TypeOp(CHECKCAST, "java/lang/String"), Invoke(INVOKESTATIC, "C", "C$$$anonfun$1", "(Ljava/lang/String;)Ljava/lang/String;", false), Op(ARETURN))) @@ -80,7 +80,7 @@ class ClosureOptimizerTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameSummary(getSingleMethod(c, "t"), List(NEW, DUP, LDC, "", ATHROW)) + val c = compileClass(code) + assertSameSummary(getMethod(c, "t"), List(NEW, DUP, LDC, "", ATHROW)) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala index 50e3af6ee5..c3748a05bd 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala @@ -56,8 +56,8 @@ class CompactLocalVariablesTest extends ClearAfterClass { |} |""".stripMargin - val List(noCompact) = noCompactVarsCompiler.compileMethods(code) - val List(withCompact) = methodOptCompiler.compileMethods(code) + val noCompact = noCompactVarsCompiler.compileAsmMethod(code) + val withCompact = methodOptCompiler.compileAsmMethod(code) // code is the same, except for local var indices assertTrue(noCompact.instructions.size == withCompact.instructions.size) diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala index 9fb4aa1658..3324058cb7 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala @@ -60,8 +60,8 @@ class EmptyExceptionHandlersTest extends BytecodeTesting { def eliminateUnreachableHandler(): Unit = { val code = "def f: Unit = try { } catch { case _: Exception => println(0) }; println(1)" - assertTrue(noOptCompiler.singleMethod(code).handlers.length == 1) - val optMethod = dceCompiler.singleMethod(code) + assertTrue(noOptCompiler.compileMethod(code).handlers.length == 1) + val optMethod = dceCompiler.compileMethod(code) assertTrue(optMethod.handlers.isEmpty) val code2 = @@ -73,7 +73,7 @@ class EmptyExceptionHandlersTest extends BytecodeTesting { | println(2) |}""".stripMargin - assertTrue(dceCompiler.singleMethod(code2).handlers.isEmpty) + assertTrue(dceCompiler.compileMethod(code2).handlers.isEmpty) } @Test @@ -85,6 +85,6 @@ class EmptyExceptionHandlersTest extends BytecodeTesting { | catch { case _: Exception => 2 } |}""".stripMargin - assertTrue(dceCompiler.singleMethod(code).handlers.length == 1) + assertTrue(dceCompiler.compileMethod(code).handlers.length == 1) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala index 876c47a84e..f0913f3631 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala @@ -38,7 +38,7 @@ class InlineWarningTest extends BytecodeTesting { "C::m1()I is annotated @inline but cannot be inlined: the method is not final and may be overridden", "T::m2()I is annotated @inline but cannot be inlined: the method is not final and may be overridden", "D::m2()I is annotated @inline but cannot be inlined: the method is not final and may be overridden") - compile(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)}) + compileToBytes(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)}) assert(count == 4, count) } @@ -53,7 +53,7 @@ class InlineWarningTest extends BytecodeTesting { """.stripMargin var c = 0 - compile(code, allowMessage = i => {c += 1; i.msg contains "operand stack at the callsite in C::t1()V contains more values"}) + compileToBytes(code, allowMessage = i => {c += 1; i.msg contains "operand stack at the callsite in C::t1()V contains more values"}) assert(c == 1, c) } @@ -83,14 +83,14 @@ class InlineWarningTest extends BytecodeTesting { |Note that the parent class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin) var c = 0 - val List(b) = compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.tail.exists(i.msg contains _)}) + val List(b) = compileToBytes(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.tail.exists(i.msg contains _)}) assert(c == 1, c) // no warnings here - newCompiler(extraArgs = s"$optCp -Yopt-warnings:none").compile(scalaCode, List((javaCode, "A.java"))) + newCompiler(extraArgs = s"$optCp -Yopt-warnings:none").compileToBytes(scalaCode, List((javaCode, "A.java"))) c = 0 - newCompiler(extraArgs = s"$optCp -Yopt-warnings:no-inline-mixed").compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)}) + newCompiler(extraArgs = s"$optCp -Yopt-warnings:no-inline-mixed").compileToBytes(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)}) assert(c == 2, c) } @@ -117,7 +117,7 @@ class InlineWarningTest extends BytecodeTesting { |that would cause an IllegalAccessError when inlined into class N""".stripMargin var c = 0 - compile(code, allowMessage = i => { c += 1; i.msg contains warn }) + compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn }) assert(c == 1, c) } @@ -136,7 +136,7 @@ class InlineWarningTest extends BytecodeTesting { | def t(a: M) = a.f(x => x + 1) |} """.stripMargin - compile(code, allowMessage = _ => false) // no warnings allowed + compileToBytes(code, allowMessage = _ => false) // no warnings allowed val warn = """M::f(Lscala/Function1;)I could not be inlined: @@ -144,7 +144,7 @@ class InlineWarningTest extends BytecodeTesting { |that would cause an IllegalAccessError when inlined into class N""".stripMargin var c = 0 - compilerWarnAll.compile(code, allowMessage = i => { c += 1; i.msg contains warn }) + compilerWarnAll.compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn }) assert(c == 1, c) } @@ -165,7 +165,7 @@ class InlineWarningTest extends BytecodeTesting { |does not have the same strictfp mode as the callee C::f()I.""".stripMargin var c = 0 - compile(code, allowMessage = i => { c += 1; i.msg contains warn }) + compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn }) assert(c == 1, c) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala index 8a44f12045..e7c3bab62f 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala @@ -37,9 +37,9 @@ class InlinerSeparateCompilationTest { val warn = "T::f()I is annotated @inline but cannot be inlined: the method is not final and may be overridden" val List(c, o, oMod, t) = compileClassesSeparately(List(codeA, codeB), args + " -Yopt-warnings", _.msg contains warn) - assertInvoke(getSingleMethod(c, "t1"), "T", "f") - assertNoInvoke(getSingleMethod(c, "t2")) - assertNoInvoke(getSingleMethod(c, "t3")) + assertInvoke(getMethod(c, "t1"), "T", "f") + assertNoInvoke(getMethod(c, "t2")) + assertNoInvoke(getMethod(c, "t3")) } @Test @@ -57,7 +57,7 @@ class InlinerSeparateCompilationTest { """.stripMargin val List(c, t) = compileClassesSeparately(List(codeA, codeB), args) - assertNoInvoke(getSingleMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t1")) } @Test @@ -80,7 +80,7 @@ class InlinerSeparateCompilationTest { """.stripMargin val List(c, t, u) = compileClassesSeparately(List(codeA, codeB), args) - for (m <- List("t1", "t2", "t3")) assertNoInvoke(getSingleMethod(c, m)) + for (m <- List("t1", "t2", "t3")) assertNoInvoke(getMethod(c, m)) } @Test @@ -101,7 +101,7 @@ class InlinerSeparateCompilationTest { """.stripMargin val List(a, t) = compileClassesSeparately(List(codeA, assembly), args) - assertNoInvoke(getSingleMethod(t, "f")) - assertNoInvoke(getSingleMethod(a, "n")) + assertNoInvoke(getMethod(t, "f")) + assertNoInvoke(getMethod(a, "n")) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala index 4db7695fdd..24e889cf18 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -39,7 +39,7 @@ class InlinerTest extends BytecodeTesting { def compile(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = { notPerRun.foreach(_.clear()) - compileClasses(scalaCode, javaCode, allowMessage) + compileToBytes(scalaCode, javaCode, allowMessage) // Use the class nodes stored in the byteCodeRepository. The ones returned by compileClasses are not the same, // these are created new from the classfile byte array. They are completely separate instances which cannot // be used to look up methods / callsites in the callGraph hash maps for example. @@ -60,7 +60,7 @@ class InlinerTest extends BytecodeTesting { def gMethAndFCallsite(code: String, mod: ClassNode => Unit = _ => ()) = { val List(c) = compile(code) mod(c) - val gMethod = findAsmMethod(c, "g") + val gMethod = getAsmMethod(c, "g") val fCall = getCallsite(gMethod, "f") (gMethod, fCall) } @@ -148,7 +148,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val can = canInlineTest(code, cls => { - val f = cls.methods.asScala.find(_.name == "f").get + val f = getAsmMethod(cls, "f") f.access |= ACC_SYNCHRONIZED }) assert(can.nonEmpty && can.get.isInstanceOf[SynchronizedMethod], can) @@ -197,7 +197,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, d) = compile(code) - val hMeth = findAsmMethod(d, "h") + val hMeth = getAsmMethod(d, "h") val gCall = getCallsite(hMeth, "g") val r = inliner.canInlineBody(gCall) assert(r.nonEmpty && r.get.isInstanceOf[IllegalAccessInstruction], r) @@ -214,7 +214,7 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(cCls) = compile(code) - val instructions = getSingleMethod(cCls, "test").instructions + val instructions = getInstructions(cCls, "test") assert(instructions.contains(Op(ICONST_0)), instructions.stringLines) assert(!instructions.contains(Op(ICONST_1)), instructions) } @@ -280,7 +280,7 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, _, _) = compile(code) - val ins = getSingleMethod(c, "f").instructions + val ins = getInstructions(c, "f") val invokeSysArraycopy = Invoke(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", false) assert(ins contains invokeSysArraycopy, ins.stringLines) } @@ -312,7 +312,7 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, t) = compile(code) - assertNoInvoke(getSingleMethod(c, "g")) + assertNoInvoke(getMethod(c, "g")) } @Test @@ -325,7 +325,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) // no more invoke, f is inlined - assertNoInvoke(getSingleMethod(c, "g")) + assertNoInvoke(getMethod(c, "g")) } @Test @@ -337,7 +337,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - val fMeth = findAsmMethod(c, "f") + val fMeth = getAsmMethod(c, "f") val call = getCallsite(fMeth, "lowestOneBit") val warning = inliner.canInlineBody(call) @@ -376,7 +376,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin // use a compiler without local optimizations (cleanups) - val List(c) = inlineOnlyCompiler.compileClasses(code) + val c = inlineOnlyCompiler.compileClass(code) val ms @ List(f1, f2, g1, g2) = c.methods.asScala.filter(_.name.length == 2).toList // stack height at callsite of f1 is 1, so max of g1 after inlining is max of f1 + 1 @@ -421,7 +421,7 @@ class InlinerTest extends BytecodeTesting { var c = 0 val List(b) = compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; i.msg contains warn}) assert(c == 1, c) - val ins = getSingleMethod(b, "g").instructions + val ins = getInstructions(b, "g") val invokeFlop = Invoke(INVOKEVIRTUAL, "B", "flop", "()I", false) assert(ins contains invokeFlop, ins.stringLines) } @@ -441,8 +441,8 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, t) = compile(code) // both are just `return 1`, no more calls - assertNoInvoke(getSingleMethod(c, "t1")) - assertNoInvoke(getSingleMethod(c, "t2")) + assertNoInvoke(getMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t2")) } @Test @@ -460,8 +460,8 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, t, u) = compile(code) - assertNoInvoke(getSingleMethod(c, "t1")) - assertNoInvoke(getSingleMethod(c, "t2")) + assertNoInvoke(getMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t2")) } @Test @@ -481,8 +481,8 @@ class InlinerTest extends BytecodeTesting { var count = 0 val List(c, t) = compile(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)}) assert(count == 2, count) - assertInvoke(getSingleMethod(c, "t1"), "T", "f") - assertInvoke(getSingleMethod(c, "t2"), "C", "f") + assertInvoke(getMethod(c, "t1"), "T", "f") + assertInvoke(getMethod(c, "t2"), "C", "f") } @Test @@ -496,7 +496,7 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, t) = compile(code) - assertNoInvoke(getSingleMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t1")) } @Test @@ -520,11 +520,11 @@ class InlinerTest extends BytecodeTesting { val List(c, oMirror, oModule, t) = compile(code, allowMessage = i => {count += 1; i.msg contains warn}) assert(count == 1, count) - assertNoInvoke(getSingleMethod(t, "f")) + assertNoInvoke(getMethod(t, "f")) - assertNoInvoke(getSingleMethod(c, "t1")) - assertNoInvoke(getSingleMethod(c, "t2")) - assertInvoke(getSingleMethod(c, "t3"), "T", "f") + assertNoInvoke(getMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t2")) + assertInvoke(getMethod(c, "t3"), "T", "f") } @Test @@ -546,12 +546,12 @@ class InlinerTest extends BytecodeTesting { val List(assembly, c, t) = compile(code) - assertNoInvoke(getSingleMethod(t, "f")) + assertNoInvoke(getMethod(t, "f")) - assertNoInvoke(getSingleMethod(assembly, "n")) + assertNoInvoke(getMethod(assembly, "n")) - assertNoInvoke(getSingleMethod(c, "t1")) - assertNoInvoke(getSingleMethod(c, "t2")) + assertNoInvoke(getMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t2")) } @Test @@ -624,20 +624,20 @@ class InlinerTest extends BytecodeTesting { val List(ca, cb, t1, t2a, t2b) = compile(code, allowMessage = i => {count += 1; i.msg contains warning}) assert(count == 4, count) // see comments, f is not inlined 4 times - assertNoInvoke(getSingleMethod(t2a, "g2a")) - assertInvoke(getSingleMethod(t2b, "g2b"), "T1", "f") + assertNoInvoke(getMethod(t2a, "g2a")) + assertInvoke(getMethod(t2b, "g2b"), "T1", "f") - assertInvoke(getSingleMethod(ca, "m1a"), "T1", "f") - assertNoInvoke(getSingleMethod(ca, "m2a")) // no invoke, see comment on def g2a - assertNoInvoke(getSingleMethod(ca, "m3a")) - assertInvoke(getSingleMethod(ca, "m4a"), "T1", "f") - assertNoInvoke(getSingleMethod(ca, "m5a")) + assertInvoke(getMethod(ca, "m1a"), "T1", "f") + assertNoInvoke(getMethod(ca, "m2a")) // no invoke, see comment on def g2a + assertNoInvoke(getMethod(ca, "m3a")) + assertInvoke(getMethod(ca, "m4a"), "T1", "f") + assertNoInvoke(getMethod(ca, "m5a")) - assertInvoke(getSingleMethod(cb, "m1b"), "T1", "f") - assertInvoke(getSingleMethod(cb, "m2b"), "T1", "f") // invoke, see comment on def g2b - assertNoInvoke(getSingleMethod(cb, "m3b")) - assertInvoke(getSingleMethod(cb, "m4b"), "T1", "f") - assertNoInvoke(getSingleMethod(cb, "m5b")) + assertInvoke(getMethod(cb, "m1b"), "T1", "f") + assertInvoke(getMethod(cb, "m2b"), "T1", "f") // invoke, see comment on def g2b + assertNoInvoke(getMethod(cb, "m3b")) + assertInvoke(getMethod(cb, "m4b"), "T1", "f") + assertNoInvoke(getMethod(cb, "m5b")) } @Test @@ -654,7 +654,7 @@ class InlinerTest extends BytecodeTesting { |} // so d.f can be resolved statically. same for E.f """.stripMargin val List(c, d, e, eModule, t) = compile(code) - assertNoInvoke(getSingleMethod(t, "t1")) + assertNoInvoke(getMethod(t, "t1")) } @Test @@ -669,8 +669,8 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, d, t) = compile(code) - assertNoInvoke(getSingleMethod(d, "m")) - assertNoInvoke(getSingleMethod(c, "m")) + assertNoInvoke(getMethod(d, "m")) + assertNoInvoke(getMethod(c, "m")) } @Test @@ -684,8 +684,8 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c, t) = compile(code) - val t1 = getSingleMethod(t, "t1") - val t2 = getSingleMethod(t, "t2") + val t1 = getMethod(t, "t1") + val t2 = getMethod(t, "t2") val cast = TypeOp(CHECKCAST, "C") Set(t1, t2).foreach(m => assert(m.instructions.contains(cast), m.instructions)) } @@ -765,27 +765,27 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, t, u) = compile(code, allowMessage = _.msg contains "i()I is annotated @inline but cannot be inlined") - val m1 = getSingleMethod(c, "m1") + val m1 = getMethod(c, "m1") assertInvoke(m1, "T", "a") assertInvoke(m1, "T", "b") assertInvoke(m1, "T", "c") - assertNoInvoke(getSingleMethod(c, "m2")) + assertNoInvoke(getMethod(c, "m2")) - val m3 = getSingleMethod(c, "m3") + val m3 = getMethod(c, "m3") assertInvoke(m3, "T", "f") assertInvoke(m3, "T", "g") assertInvoke(m3, "T", "h") assertInvoke(m3, "T", "i") - val m4 = getSingleMethod(c, "m4") + val m4 = getMethod(c, "m4") assertInvoke(m4, "U", "a") assertInvoke(m4, "U", "b") assertInvoke(m4, "U", "c") - assertNoInvoke(getSingleMethod(c, "m5")) + assertNoInvoke(getMethod(c, "m5")) - val m6 = getSingleMethod(c, "m6") + val m6 = getMethod(c, "m6") assertInvoke(m6, "U", "f") assertInvoke(m6, "U", "g") assertInvoke(m6, "U", "h") @@ -869,15 +869,15 @@ class InlinerTest extends BytecodeTesting { val List(a, b, t) = compile(code, allowMessage = i => {c += 1; i.msg contains warn}) assert(c == 1, c) - assertInvoke(getSingleMethod(b, "t1"), "Aa", "f1") - assertInvoke(getSingleMethod(b, "t2"), "B", "B$$f2m") - assertInvoke(getSingleMethod(b, "t3"), "B", "") - assertInvoke(getSingleMethod(b, "t4"), "B", "") + assertInvoke(getMethod(b, "t1"), "Aa", "f1") + assertInvoke(getMethod(b, "t2"), "B", "B$$f2m") + assertInvoke(getMethod(b, "t3"), "B", "") + assertInvoke(getMethod(b, "t4"), "B", "") - assertInvoke(getSingleMethod(t, "t1"), "B", "f1") - assertInvoke(getSingleMethod(t, "t2"), "B", "B$$f2m") - assertInvoke(getSingleMethod(t, "t3"), "B", "") - assertInvoke(getSingleMethod(t, "t4"), "B", "") + assertInvoke(getMethod(t, "t1"), "B", "f1") + assertInvoke(getMethod(t, "t2"), "B", "B$$f2m") + assertInvoke(getMethod(t, "t3"), "B", "") + assertInvoke(getMethod(t, "t4"), "B", "") } @Test @@ -887,8 +887,8 @@ class InlinerTest extends BytecodeTesting { | def t = System.arraycopy(null, 0, null, 0, 0) |} """.stripMargin - val List(c) = newCompiler(extraArgs = compilerArgs + " -Yopt-inline-heuristics:everything").compileClasses(code) - assertInvoke(getSingleMethod(c, "t"), "java/lang/System", "arraycopy") + val c = newCompiler(extraArgs = compilerArgs + " -Yopt-inline-heuristics:everything").compileClass(code) + assertInvoke(getMethod(c, "t"), "java/lang/System", "arraycopy") } @Test @@ -902,7 +902,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - assertInvoke(getSingleMethod(c, "t"), "java/lang/Error", "") + assertInvoke(getMethod(c, "t"), "java/lang/Error", "") } @Test @@ -915,7 +915,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - val t = getSingleMethod(c, "t").instructions + val t = getInstructions(c, "t") assertNoInvoke(t) assert(1 == t.collect({case Ldc(_, "hai!") => }).size) // push-pop eliminates the first LDC("hai!") assert(1 == t.collect({case Jump(IFNONNULL, _) => }).size) // one single null check @@ -942,12 +942,12 @@ class InlinerTest extends BytecodeTesting { val List(c, _, _) = compile(code) - val t1 = getSingleMethod(c, "t1") + val t1 = getMethod(c, "t1") assertNoIndy(t1) // the indy call is inlined into t, and the closure elimination rewrites the closure invocation to the body method assertInvoke(t1, "C", "C$$$anonfun$2") - val t2 = getSingleMethod(c, "t2") + val t2 = getMethod(c, "t2") assertNoIndy(t2) assertInvoke(t2, "M$", "M$$$anonfun$1") } @@ -964,9 +964,9 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - val hMeth = findAsmMethod(c, "h") - val gMeth = findAsmMethod(c, "g") - val iMeth = findAsmMethod(c, "i") + val hMeth = getAsmMethod(c, "h") + val gMeth = getAsmMethod(c, "g") + val iMeth = getAsmMethod(c, "i") val fCall = getCallsite(gMeth, "f") val gCall = getCallsite(hMeth, "g") val hCall = getCallsite(iMeth, "h") @@ -993,7 +993,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(cl) = compile(code) - val List(b, c, d) = List("b", "c", "d").map(findAsmMethod(cl, _)) + val List(b, c, d) = List("b", "c", "d").map(getAsmMethod(cl, _)) val aCall = getCallsite(b, "a") val bCall = getCallsite(c, "b") val cCall = getCallsite(d, "c") @@ -1033,15 +1033,15 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - assertInvoke(getSingleMethod(c, "t1"), "C", "C$$$anonfun$1") - assertInvoke(getSingleMethod(c, "t2"), "C", "a") - assertInvoke(getSingleMethod(c, "t3"), "C", "b") - assertNoInvoke(getSingleMethod(c, "t4")) - assertNoInvoke(getSingleMethod(c, "t5")) - assertNoInvoke(getSingleMethod(c, "t6")) - assertInvoke(getSingleMethod(c, "t7"), "C", "c") - assertInvoke(getSingleMethod(c, "t8"), "scala/Predef$", "println") - assertNoInvoke(getSingleMethod(c, "t9")) + assertInvoke(getMethod(c, "t1"), "C", "C$$$anonfun$1") + assertInvoke(getMethod(c, "t2"), "C", "a") + assertInvoke(getMethod(c, "t3"), "C", "b") + assertNoInvoke(getMethod(c, "t4")) + assertNoInvoke(getMethod(c, "t5")) + assertNoInvoke(getMethod(c, "t6")) + assertInvoke(getMethod(c, "t7"), "C", "c") + assertInvoke(getMethod(c, "t8"), "scala/Predef$", "println") + assertNoInvoke(getMethod(c, "t9")) } @Test @@ -1066,15 +1066,15 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - assertNoInvoke(getSingleMethod(c, "t1")) - assertInvoke(getSingleMethod(c, "t2"), "C", "f2") - assertInvoke(getSingleMethod(c, "t3"), "C", "f1") - assertInvoke(getSingleMethod(c, "t4"), "C", "f2") - assertNoInvoke(getSingleMethod(c, "t5")) - assertInvoke(getSingleMethod(c, "t6"), "C", "f3") - assertNoInvoke(getSingleMethod(c, "t7")) - assertInvoke(getSingleMethod(c, "t8"), "C", "f1") - assertNoInvoke(getSingleMethod(c, "t9")) + assertNoInvoke(getMethod(c, "t1")) + assertInvoke(getMethod(c, "t2"), "C", "f2") + assertInvoke(getMethod(c, "t3"), "C", "f1") + assertInvoke(getMethod(c, "t4"), "C", "f2") + assertNoInvoke(getMethod(c, "t5")) + assertInvoke(getMethod(c, "t6"), "C", "f3") + assertNoInvoke(getMethod(c, "t7")) + assertInvoke(getMethod(c, "t8"), "C", "f1") + assertNoInvoke(getMethod(c, "t9")) } @Test @@ -1097,11 +1097,11 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c) = compile(code) - assertInvoke(getSingleMethod(c, "t1"), "C", "C$$$anonfun$1") - assertInvoke(getSingleMethod(c, "t2"), "C", "C$$$anonfun$2") - assertInvoke(getSingleMethod(c, "t3"), "scala/Function1", "apply$mcII$sp") - assertInvoke(getSingleMethod(c, "t4"), "scala/Function1", "apply$mcII$sp") - assertInvoke(getSingleMethod(c, "t5"), "C", "h") + assertInvoke(getMethod(c, "t1"), "C", "C$$$anonfun$1") + assertInvoke(getMethod(c, "t2"), "C", "C$$$anonfun$2") + assertInvoke(getMethod(c, "t3"), "scala/Function1", "apply$mcII$sp") + assertInvoke(getMethod(c, "t4"), "scala/Function1", "apply$mcII$sp") + assertInvoke(getMethod(c, "t5"), "C", "h") } @Test @@ -1121,7 +1121,7 @@ class InlinerTest extends BytecodeTesting { |when entering an exception handler declared in the inlined method.""".stripMargin val List(c) = compile(code, allowMessage = _.msg contains warn) - assertInvoke(getSingleMethod(c, "t"), "C", "g") + assertInvoke(getMethod(c, "t"), "C", "g") } @Test @@ -1145,8 +1145,8 @@ class InlinerTest extends BytecodeTesting { |that would cause an IllegalAccessError when inlined into class D.""".stripMargin val List(c, d) = compile(code, allowMessage = _.msg contains warn) - assertInvoke(getSingleMethod(c, "h"), "C", "f$1") - assertInvoke(getSingleMethod(d, "t"), "C", "h") + assertInvoke(getMethod(c, "h"), "C", "f$1") + assertInvoke(getMethod(d, "t"), "C", "h") } @Test @@ -1164,8 +1164,8 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, d) = compile(code) - assertNoInvoke(getSingleMethod(c, "g")) - assertNoInvoke(getSingleMethod(d, "t")) + assertNoInvoke(getMethod(c, "g")) + assertNoInvoke(getMethod(d, "t")) } @Test @@ -1273,40 +1273,40 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, _, _) = compile(code) - assertSameSummary(getSingleMethod(c, "t1"), List(BIPUSH, "C$$$anonfun$1", IRETURN)) - assertSameSummary(getSingleMethod(c, "t1a"), List(LCONST_1, "C$$$anonfun$2", IRETURN)) - assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, ICONST_2, "C$$$anonfun$3",IRETURN)) + assertSameSummary(getMethod(c, "t1"), List(BIPUSH, "C$$$anonfun$1", IRETURN)) + assertSameSummary(getMethod(c, "t1a"), List(LCONST_1, "C$$$anonfun$2", IRETURN)) + assertSameSummary(getMethod(c, "t2"), List(ICONST_1, ICONST_2, "C$$$anonfun$3",IRETURN)) // val a = new ValKl(n); new ValKl(anonfun(a.x)).x // value class instantiation-extraction should be optimized by boxing elim - assertSameSummary(getSingleMethod(c, "t3"), List( + assertSameSummary(getMethod(c, "t3"), List( NEW, DUP, ICONST_1, "", ASTORE, NEW, DUP, ALOAD, "x", "C$$$anonfun$4", "", "x", IRETURN)) - assertSameSummary(getSingleMethod(c, "t4"), List(BIPUSH, "C$$$anonfun$5", "boxToInteger", ARETURN)) - assertSameSummary(getSingleMethod(c, "t4a"), List(ICONST_1, LDC, "C$$$anonfun$6", LRETURN)) - assertSameSummary(getSingleMethod(c, "t5"), List(BIPUSH, ICONST_3, "C$$$anonfun$7", "boxToInteger", ARETURN)) - assertSameSummary(getSingleMethod(c, "t5a"), List(BIPUSH, BIPUSH, I2B, "C$$$anonfun$8", IRETURN)) - assertSameSummary(getSingleMethod(c, "t6"), List(BIPUSH, "C$$$anonfun$9", RETURN)) - assertSameSummary(getSingleMethod(c, "t7"), List(ICONST_1, "C$$$anonfun$10", RETURN)) - assertSameSummary(getSingleMethod(c, "t8"), List(ICONST_1, LDC, "C$$$anonfun$11", LRETURN)) - assertSameSummary(getSingleMethod(c, "t9"), List(ICONST_1, "boxToInteger", "C$$$anonfun$12", RETURN)) + assertSameSummary(getMethod(c, "t4"), List(BIPUSH, "C$$$anonfun$5", "boxToInteger", ARETURN)) + assertSameSummary(getMethod(c, "t4a"), List(ICONST_1, LDC, "C$$$anonfun$6", LRETURN)) + assertSameSummary(getMethod(c, "t5"), List(BIPUSH, ICONST_3, "C$$$anonfun$7", "boxToInteger", ARETURN)) + assertSameSummary(getMethod(c, "t5a"), List(BIPUSH, BIPUSH, I2B, "C$$$anonfun$8", IRETURN)) + assertSameSummary(getMethod(c, "t6"), List(BIPUSH, "C$$$anonfun$9", RETURN)) + assertSameSummary(getMethod(c, "t7"), List(ICONST_1, "C$$$anonfun$10", RETURN)) + assertSameSummary(getMethod(c, "t8"), List(ICONST_1, LDC, "C$$$anonfun$11", LRETURN)) + assertSameSummary(getMethod(c, "t9"), List(ICONST_1, "boxToInteger", "C$$$anonfun$12", RETURN)) // t9a inlines Range.foreach, which is quite a bit of code, so just testing the core - assertInvoke(getSingleMethod(c, "t9a"), "C", "C$$$anonfun$13") - assertInvoke(getSingleMethod(c, "t9a"), "scala/runtime/BoxesRunTime", "boxToInteger") + assertInvoke(getMethod(c, "t9a"), "C", "C$$$anonfun$13") + assertInvoke(getMethod(c, "t9a"), "scala/runtime/BoxesRunTime", "boxToInteger") - assertSameSummary(getSingleMethod(c, "t10"), List( + assertSameSummary(getMethod(c, "t10"), List( ICONST_1, ISTORE, ALOAD, ILOAD, "C$$$anonfun$14", RETURN)) // t10a inlines Range.foreach - assertInvoke(getSingleMethod(c, "t10a"), "C", "C$$$anonfun$15") - assertDoesNotInvoke(getSingleMethod(c, "t10a"), "boxToInteger") + assertInvoke(getMethod(c, "t10a"), "C", "C$$$anonfun$15") + assertDoesNotInvoke(getMethod(c, "t10a"), "boxToInteger") } @Test @@ -1329,8 +1329,8 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c) = compile(code) - assertSameCode(getSingleMethod(c, "t1"), List(Op(ICONST_0), Op(ICONST_1), Op(IADD), Op(IRETURN))) - assertEquals(getSingleMethod(c, "t2").instructions collect { case i: Invoke => i.owner +"."+ i.name }, List( + assertSameCode(getMethod(c, "t1"), List(Op(ICONST_0), Op(ICONST_1), Op(IADD), Op(IRETURN))) + assertEquals(getInstructions(c, "t2") collect { case i: Invoke => i.owner +"."+ i.name }, List( "scala/runtime/IntRef.create", "C.C$$$anonfun$1")) } @@ -1370,11 +1370,11 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c) = compile(code) - assertSameCode(getSingleMethod(c, "t1"), List(Op(ICONST_3), Op(ICONST_4), Op(IADD), Op(IRETURN))) - assertSameCode(getSingleMethod(c, "t2"), List(Op(ICONST_1), Op(ICONST_2), Op(IADD), Op(IRETURN))) - assertSameCode(getSingleMethod(c, "t3"), List(Op(ICONST_1), Op(ICONST_3), Op(ISUB), Op(IRETURN))) - assertNoInvoke(getSingleMethod(c, "t4")) - assertNoInvoke(getSingleMethod(c, "t5")) + assertSameCode(getMethod(c, "t1"), List(Op(ICONST_3), Op(ICONST_4), Op(IADD), Op(IRETURN))) + assertSameCode(getMethod(c, "t2"), List(Op(ICONST_1), Op(ICONST_2), Op(IADD), Op(IRETURN))) + assertSameCode(getMethod(c, "t3"), List(Op(ICONST_1), Op(ICONST_3), Op(ISUB), Op(IRETURN))) + assertNoInvoke(getMethod(c, "t4")) + assertNoInvoke(getMethod(c, "t5")) } @Test @@ -1400,10 +1400,10 @@ class InlinerTest extends BytecodeTesting { |class D extends C """.stripMargin val List(c, _) = compile(code) - def casts(m: String) = getSingleMethod(c, m).instructions collect { case TypeOp(CHECKCAST, tp) => tp } - assertSameCode(getSingleMethod(c, "t1"), List(VarOp(ALOAD, 1), Op(ARETURN))) - assertSameCode(getSingleMethod(c, "t2"), List(VarOp(ALOAD, 1), Op(ARETURN))) - assertSameCode(getSingleMethod(c, "t3"), List(VarOp(ALOAD, 1), TypeOp(CHECKCAST, "C"), Op(ARETURN))) + def casts(m: String) = getInstructions(c, m) collect { case TypeOp(CHECKCAST, tp) => tp } + assertSameCode(getMethod(c, "t1"), List(VarOp(ALOAD, 1), Op(ARETURN))) + assertSameCode(getMethod(c, "t2"), List(VarOp(ALOAD, 1), Op(ARETURN))) + assertSameCode(getMethod(c, "t3"), List(VarOp(ALOAD, 1), TypeOp(CHECKCAST, "C"), Op(ARETURN))) assertEquals(casts("t4"), List("C")) assertEquals(casts("t5"), Nil) assertEquals(casts("t6"), Nil) @@ -1428,8 +1428,8 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val cls = compile(code) - val test = cls.find(_.name == "Test$").get - assertSameSummary(getSingleMethod(test, "f"), List( + val test = findClass(cls, "Test$") + assertSameSummary(getMethod(test, "f"), List( GETSTATIC, "mkFoo", BIPUSH, ISTORE, IFNONNULL, ACONST_NULL, ATHROW, -1 /*label*/, @@ -1448,7 +1448,7 @@ class InlinerTest extends BytecodeTesting { val List(c) = compile(code) // box-unbox will clean it up - assertSameSummary(getSingleMethod(c, "t"), List( + assertSameSummary(getMethod(c, "t"), List( ALOAD, "C$$$anonfun$1", IFEQ /*A*/, "C$$$anonfun$2", IRETURN, -1 /*A*/, "C$$$anonfun$3", IRETURN)) @@ -1460,7 +1460,7 @@ class InlinerTest extends BytecodeTesting { val codeB = "class B { def t(a: A) = a.f }" // tests that no warning is emitted val List(a, b) = compileClassesSeparately(List(codeA, codeB), extraArgs = "-Yopt:l:project -Yopt-warnings") - assertInvoke(getSingleMethod(b, "t"), "A", "f") + assertInvoke(getMethod(b, "t"), "A", "f") } @Test @@ -1472,7 +1472,7 @@ class InlinerTest extends BytecodeTesting { """.stripMargin val List(c, t1, t2) = compile(code, allowMessage = _ => true) // the forwarder C.f is inlined, so there's no invocation - assertSameSummary(getSingleMethod(c, "f"), List(ICONST_1, IRETURN)) + assertSameSummary(getMethod(c, "f"), List(ICONST_1, IRETURN)) } @Test @@ -1485,7 +1485,7 @@ class InlinerTest extends BytecodeTesting { |class C { def t = (new K).f } """.stripMargin val c :: _ = compile(code) - assertSameSummary(getSingleMethod(c, "t"), List(NEW, "", ICONST_1, IRETURN)) // ICONST_1, U.f is inlined (not T.f) + assertSameSummary(getMethod(c, "t"), List(NEW, "", ICONST_1, IRETURN)) // ICONST_1, U.f is inlined (not T.f) } @Test @@ -1497,7 +1497,7 @@ class InlinerTest extends BytecodeTesting { |} """.stripMargin val List(c) = compile(code) - val t = getSingleMethod(c, "t") + val t = getMethod(c, "t") assertNoIndy(t) assertInvoke(t, "C", "C$$$anonfun$1") } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala index 3867f10145..fa76c0d930 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala @@ -22,20 +22,20 @@ class MethodLevelOptsTest extends BytecodeTesting { def wrapInDefault(code: Instruction*) = List(Label(0), LineNumber(1, Label(0))) ::: code.toList ::: List(Label(1)) - def locals(c: ClassNode, m: String) = findAsmMethod(c, m).localVariables.asScala.toList.map(l => (l.name, l.index)).sortBy(_._2) + def locals(c: ClassNode, m: String) = getAsmMethod(c, m).localVariables.asScala.toList.map(l => (l.name, l.index)).sortBy(_._2) @Test def eliminateEmptyTry(): Unit = { val code = "def f = { try {} catch { case _: Throwable => 0; () }; 1 }" val warn = "a pure expression does nothing in statement position" - assertSameCode(singleMethodInstructions(code, allowMessage = _.msg contains warn), wrapInDefault(Op(ICONST_1), Op(IRETURN))) + assertSameCode(compileInstructions(code, allowMessage = _.msg contains warn), wrapInDefault(Op(ICONST_1), Op(IRETURN))) } @Test def eliminateLoadBoxedUnit(): Unit = { // the compiler inserts a boxed into the try block. it's therefore non-empty (and live) and not eliminated. val code = "def f = { try {} catch { case _: Throwable => 0 }; 1 }" - val m = singleMethod(code) + val m = compileMethod(code) assertTrue(m.handlers.length == 0) assertSameCode(m, List(Op(ICONST_1), Op(IRETURN))) } @@ -44,7 +44,7 @@ class MethodLevelOptsTest extends BytecodeTesting { def inlineThrowInCatchNotTry(): Unit = { // the try block does not contain the `ATHROW` instruction, but in the catch block, `ATHROW` is inlined val code = "def f(e: Exception) = throw { try e catch { case _: Throwable => e } }" - val m = singleMethod(code) + val m = compileMethod(code) assertHandlerLabelPostions(m.handlers.head, m.instructions, 0, 3, 5) assertSameCode(m.instructions, wrapInDefault(VarOp(ALOAD, 1), Label(3), Op(ATHROW), Label(5), FrameEntry(4, List(), List("java/lang/Throwable")), Op(POP), VarOp(ALOAD, 1), Op(ATHROW)) @@ -55,7 +55,7 @@ class MethodLevelOptsTest extends BytecodeTesting { def inlineReturnInCatchNotTry(): Unit = { val code = "def f: Int = return { try 1 catch { case _: Throwable => 2 } }" // cannot inline the IRETURN into the try block (because RETURN may throw IllegalMonitorState) - val m = singleMethod(code) + val m = compileMethod(code) assertHandlerLabelPostions(m.handlers.head, m.instructions, 0, 3, 5) assertSameCode(m.instructions, wrapInDefault(Op(ICONST_1), Label(3), Op(IRETURN), Label(5), FrameEntry(4, List(), List("java/lang/Throwable")), Op(POP), Op(ICONST_2), Op(IRETURN))) @@ -77,7 +77,7 @@ class MethodLevelOptsTest extends BytecodeTesting { | println(x) | } """.stripMargin - val m = singleMethod(code) + val m = compileMethod(code) assertTrue(m.handlers.isEmpty) assertSameCode(m, List(Op(ICONST_3), Op(IRETURN))) } @@ -97,8 +97,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List( Op(ACONST_NULL), Invoke(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false), Op(ARETURN))) } @@ -114,9 +114,9 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) assertSameCode( - getSingleMethod(c, "t"), List(Ldc(LDC, "c"), Op(ARETURN))) + getMethod(c, "t"), List(Ldc(LDC, "c"), Op(ARETURN))) } @Test @@ -134,9 +134,9 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) - assertSameCode(getSingleMethod(c, "t"), List( + assertSameCode(getMethod(c, "t"), List( Ldc(LDC, "el"), VarOp(ASTORE, 1), Field(GETSTATIC, "scala/Predef$", "MODULE$", "Lscala/Predef$;"), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false), Op(ACONST_NULL), VarOp(ASTORE, 1), @@ -158,8 +158,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List( IntOp(BIPUSH, 23), IntOp(NEWARRAY, 5), Op(POP), VarOp(ILOAD, 1), VarOp(ILOAD, 2), Op(IADD), Op(IRETURN))) } @@ -173,8 +173,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List( TypeOp(NEW, "java/lang/Integer"), Ldc(LDC, "nono"), Invoke(INVOKESPECIAL, "java/lang/Integer", "", "(Ljava/lang/String;)V", false), VarOp(ILOAD, 1), VarOp(ILOAD, 2), Op(IADD), Op(IRETURN))) } @@ -199,8 +199,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List(Op(ICONST_0), Op(IRETURN))) + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List(Op(ICONST_0), Op(IRETURN))) } @Test @@ -215,8 +215,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameCode(getSingleMethod(c, "t"), List( + val c = compileClass(code) + assertSameCode(getMethod(c, "t"), List( IntOp(BIPUSH, 30), VarOp(ISTORE, 3), // no constant propagation, so we keep the store (and load below) of a const VarOp(ILOAD, 1), VarOp(ILOAD, 2), @@ -236,8 +236,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - val t = getSingleMethod(c, "t") + val c = compileClass(code) + val t = getMethod(c, "t") assert(!t.instructions.exists(_.opcode == INVOKEDYNAMIC), t) } @@ -317,23 +317,23 @@ class MethodLevelOptsTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - - assertNoInvoke(getSingleMethod(c, "t1")) - assertNoInvoke(getSingleMethod(c, "t2")) - assertInvoke(getSingleMethod(c, "t3"), "scala/runtime/BoxesRunTime", "unboxToInt") - assertInvoke(getSingleMethod(c, "t4"), "scala/runtime/BoxesRunTime", "boxToLong") - assertNoInvoke(getSingleMethod(c, "t5")) - assertNoInvoke(getSingleMethod(c, "t6")) - assertNoInvoke(getSingleMethod(c, "t7")) - assertSameSummary(getSingleMethod(c, "t8"), List(ICONST_0, IRETURN)) - assertNoInvoke(getSingleMethod(c, "t9")) + val c = compileClass(code) + + assertNoInvoke(getMethod(c, "t1")) + assertNoInvoke(getMethod(c, "t2")) + assertInvoke(getMethod(c, "t3"), "scala/runtime/BoxesRunTime", "unboxToInt") + assertInvoke(getMethod(c, "t4"), "scala/runtime/BoxesRunTime", "boxToLong") + assertNoInvoke(getMethod(c, "t5")) + assertNoInvoke(getMethod(c, "t6")) + assertNoInvoke(getMethod(c, "t7")) + assertSameSummary(getMethod(c, "t8"), List(ICONST_0, IRETURN)) + assertNoInvoke(getMethod(c, "t9")) // t10: no invocation of unbox - assertEquals(getSingleMethod(c, "t10").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( + assertEquals(getInstructions(c, "t10") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( ("java/lang/Integer", "valueOf"), ("C", "escape"))) - assertSameSummary(getSingleMethod(c, "t11"), List( + assertSameSummary(getMethod(c, "t11"), List( BIPUSH, "valueOf", ASTORE /*2*/, BIPUSH, "valueOf", ASTORE /*3*/, ALOAD /*0*/, ALOAD /*2*/, "escape", @@ -341,7 +341,7 @@ class MethodLevelOptsTest extends BytecodeTesting { ASTORE /*4*/, GETSTATIC /*Predef*/, ALOAD /*4*/, "Integer2int", IRETURN)) // no unbox invocations - assertEquals(getSingleMethod(c, "t12").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( + assertEquals(getInstructions(c, "t12") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( ("java/lang/Integer", "valueOf"), ("java/lang/Integer", "valueOf"), ("C", "escape"))) @@ -393,14 +393,14 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameSummary(getSingleMethod(c, "t1"), List(ICONST_0, IRETURN)) - assertNoInvoke(getSingleMethod(c, "t2")) - assertSameSummary(getSingleMethod(c, "t3"), List(LDC, LDC, LADD, LRETURN)) - assertNoInvoke(getSingleMethod(c, "t4")) - assertEquals(getSingleMethod(c, "t5").instructions collect { case Field(_, owner, name, _) => s"$owner.$name" }, + val c = compileClass(code) + assertSameSummary(getMethod(c, "t1"), List(ICONST_0, IRETURN)) + assertNoInvoke(getMethod(c, "t2")) + assertSameSummary(getMethod(c, "t3"), List(LDC, LDC, LADD, LRETURN)) + assertNoInvoke(getMethod(c, "t4")) + assertEquals(getInstructions(c, "t5") collect { case Field(_, owner, name, _) => s"$owner.$name" }, List("scala/runtime/IntRef.elem")) - assertEquals(getSingleMethod(c, "t6").instructions collect { case Field(op, owner, name, _) => s"$op $owner.$name" }, + assertEquals(getInstructions(c, "t6") collect { case Field(op, owner, name, _) => s"$op $owner.$name" }, List(s"$PUTFIELD scala/runtime/IntRef.elem", s"$GETFIELD scala/runtime/IntRef.elem")) } @@ -457,23 +457,23 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertNoInvoke(getSingleMethod(c, "t1")) - assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, ICONST_3, IADD, IRETURN)) - assertSameSummary(getSingleMethod(c, "t3"), List(ICONST_3, ICONST_4, IADD, IRETURN)) - assertSameSummary(getSingleMethod(c, "t4"), List(ICONST_3, "boxToInteger", ARETURN)) - assertEquals(getSingleMethod(c, "t5").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( + val c = compileClass(code) + assertNoInvoke(getMethod(c, "t1")) + assertSameSummary(getMethod(c, "t2"), List(ICONST_1, ICONST_3, IADD, IRETURN)) + assertSameSummary(getMethod(c, "t3"), List(ICONST_3, ICONST_4, IADD, IRETURN)) + assertSameSummary(getMethod(c, "t4"), List(ICONST_3, "boxToInteger", ARETURN)) + assertEquals(getInstructions(c, "t5") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List( ("scala/runtime/BoxesRunTime", "boxToInteger"), ("scala/runtime/BoxesRunTime", "boxToInteger"), ("C", "tpl"), ("scala/Tuple2", "_1$mcI$sp"))) - assertSameSummary(getSingleMethod(c, "t6"), List(ICONST_1, ICONST_2, ISUB, IRETURN)) - assertSameSummary(getSingleMethod(c, "t7"), List( + assertSameSummary(getMethod(c, "t6"), List(ICONST_1, ICONST_2, ISUB, IRETURN)) + assertSameSummary(getMethod(c, "t7"), List( ICONST_1, ICONST_2, ISTORE, ISTORE, ICONST_3, ISTORE, ILOAD, ILOAD, IADD, ILOAD, IADD, IRETURN)) - assertNoInvoke(getSingleMethod(c, "t8")) - assertNoInvoke(getSingleMethod(c, "t9")) + assertNoInvoke(getMethod(c, "t8")) + assertNoInvoke(getMethod(c, "t9")) } @Test @@ -522,14 +522,14 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertSameSummary(getSingleMethod(c, "t1"), List(NEW, DUP, "", ARETURN)) - assertSameCode(getSingleMethod(c, "t2"), List(Op(LCONST_0), Op(LRETURN))) - assertSameCode(getSingleMethod(c, "t3"), List(Op(ICONST_1), Op(IRETURN))) - assertSameCode(getSingleMethod(c, "t4"), List(Op(ICONST_1), Op(IRETURN))) - assertSameCode(getSingleMethod(c, "t5"), List(Op(DCONST_0), Op(DRETURN))) - assertSameCode(getSingleMethod(c, "t6"), List(Op(ACONST_NULL), Op(ARETURN))) - assertSameCode(getSingleMethod(c, "t7"), List(Op(ICONST_0), Op(IRETURN))) + val c = compileClass(code) + assertSameSummary(getMethod(c, "t1"), List(NEW, DUP, "", ARETURN)) + assertSameCode(getMethod(c, "t2"), List(Op(LCONST_0), Op(LRETURN))) + assertSameCode(getMethod(c, "t3"), List(Op(ICONST_1), Op(IRETURN))) + assertSameCode(getMethod(c, "t4"), List(Op(ICONST_1), Op(IRETURN))) + assertSameCode(getMethod(c, "t5"), List(Op(DCONST_0), Op(DRETURN))) + assertSameCode(getMethod(c, "t6"), List(Op(ACONST_NULL), Op(ARETURN))) + assertSameCode(getMethod(c, "t7"), List(Op(ICONST_0), Op(IRETURN))) } @Test @@ -542,9 +542,9 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) assertSameCode( - getSingleMethod(c, "t"), List( + getMethod(c, "t"), List( VarOp(ALOAD, 1), Jump(IFNULL, Label(6)), Op(ICONST_1), Op(IRETURN), Label(6), Op(ICONST_0), Op(IRETURN))) } @@ -613,28 +613,28 @@ class MethodLevelOptsTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - def stores(m: String) = getSingleMethod(c, m).instructions.filter(_.opcode == ASTORE) + val c = compileClass(code) + def stores(m: String) = getInstructions(c, m).filter(_.opcode == ASTORE) assertEquals(locals(c, "t1"), List(("this",0), ("kept1",1), ("result",2))) assert(stores("t1") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 2), VarOp(ASTORE, 1), VarOp(ASTORE, 1)), - textify(findAsmMethod(c, "t1"))) + textify(getAsmMethod(c, "t1"))) assertEquals(locals(c, "t2"), List(("this",0), ("kept2",1), ("kept3",2))) assert(stores("t2") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 2), VarOp(ASTORE, 1)), - textify(findAsmMethod(c, "t2"))) + textify(getAsmMethod(c, "t2"))) assertEquals(locals(c, "t3"), List(("this",0), ("kept4",1))) assert(stores("t3") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)), - textify(findAsmMethod(c, "t3"))) + textify(getAsmMethod(c, "t3"))) assertEquals(locals(c, "t4"), List(("this",0), ("kept5",1))) assert(stores("t4") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)), - textify(findAsmMethod(c, "t4"))) + textify(getAsmMethod(c, "t4"))) assertEquals(locals(c, "t5"), List(("this",0), ("kept6",1))) assert(stores("t5") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)), - textify(findAsmMethod(c, "t5"))) + textify(getAsmMethod(c, "t5"))) } @Test @@ -681,13 +681,13 @@ class MethodLevelOptsTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) assertEquals(locals(c, "t1"), List(("this", 0), ("x", 1))) assertEquals(locals(c, "t2"), List(("this", 0), ("x", 1))) // we don't have constant propagation (yet). // the local var can't be optimized as a store;laod sequence, there's a GETSTATIC between the two - assertSameSummary(getSingleMethod(c, "t2"), List( + assertSameSummary(getMethod(c, "t2"), List( ICONST_2, ISTORE, GETSTATIC, ILOAD, "boxToInteger", "println", RETURN)) assertEquals(locals(c, "t3"), List(("this", 0))) @@ -709,8 +709,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - val t = getSingleMethod(c, "t") + val c = compileClass(code) + val t = getMethod(c, "t") assertEquals(t.handlers, Nil) assertEquals(locals(c, "t"), List(("this", 0))) assertSameSummary(t, List(GETSTATIC, LDC, "print", -1, GOTO)) @@ -727,8 +727,8 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) - assertNoInvoke(getSingleMethod(c, "compare")) + val c = compileClass(code) + assertNoInvoke(getMethod(c, "compare")) } @Test @@ -741,9 +741,9 @@ class MethodLevelOptsTest extends BytecodeTesting { | } |} """.stripMargin - val List(c) = compileClasses(code) + val c = compileClass(code) - assertSameSummary(getSingleMethod(c, "t"), List( + assertSameSummary(getMethod(c, "t"), List( BIPUSH, ILOAD, IF_ICMPNE, BIPUSH, ILOAD, IF_ICMPNE, LDC, ASTORE, GOTO, 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 99a662b897..63bbcc396b 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala @@ -110,10 +110,10 @@ class UnreachableCodeTest extends ClearAfterClass { @Test def basicEliminationCompiler(): Unit = { val code = "def f: Int = { return 1; 2 }" - val withDce = dceCompiler.singleMethodInstructions(code) + val withDce = dceCompiler.compileInstructions(code) assertSameCode(withDce.dropNonOp, List(Op(ICONST_1), Op(IRETURN))) - val noDce = noOptCompiler.singleMethodInstructions(code) + val noDce = noOptCompiler.compileInstructions(code) // The emitted code is ICONST_1, IRETURN, ICONST_2, IRETURN. The latter two are dead. // @@ -139,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 = dceCompiler.singleMethod(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(methodOptCompiler.singleMethodInstructions(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(methodOptCompiler.singleMethodInstructions(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(methodOptCompiler.singleMethodInstructions(code4), wrapInDefault(Op(RETURN))) + assertSameCode(methodOptCompiler.compileInstructions(code4), wrapInDefault(Op(RETURN))) } @Test // test the dce-testing tools @@ -214,35 +214,35 @@ class UnreachableCodeTest extends ClearAfterClass { | def t4 = cons(nt) |} """.stripMargin - val List(c) = noOptCompiler.compileClasses(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, "", 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, "", 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) = dceCompiler.compileClasses(code) - assertSameSummary(getSingleMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "", ATHROW)) - assertSameSummary(getSingleMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW)) + val cDCE = dceCompiler.compileClass(code) + assertSameSummary(getMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "", ATHROW)) + assertSameSummary(getMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW)) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala index 303600aa70..c9c98b403b 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala @@ -8,9 +8,9 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import scala.collection.JavaConverters._ -import scala.tools.partest.ASMConverters import scala.tools.partest.ASMConverters._ import scala.tools.testing.BytecodeTesting +import scala.tools.testing.BytecodeTesting._ @RunWith(classOf[JUnit4]) class UnusedLocalVariablesTest extends BytecodeTesting { @@ -48,7 +48,7 @@ class UnusedLocalVariablesTest extends BytecodeTesting { | } |} |""".stripMargin - val cls = compileClasses(code).head + val cls = compileClass(code) val m = convertMethod(cls.methods.asScala.toList.find(_.desc == "(I)V").get) assertTrue(m.localVars.length == 2) // this, a, but not y @@ -69,19 +69,14 @@ class UnusedLocalVariablesTest extends BytecodeTesting { |} """.stripMargin - val clss2 = compileClasses(code2) - val cls2 = clss2.find(_.name == "C").get - val companion2 = clss2.find(_.name == "C$").get + val List(cls2, companion2) = compileClasses(code2) - val clsConstr = convertMethod(cls2.methods.asScala.toList.find(_.name == "").get) - val companionConstr = convertMethod(companion2.methods.asScala.toList.find(_.name == "").get) - - assertTrue(clsConstr.localVars.length == 1) // this - assertTrue(companionConstr.localVars.length == 1) // this + assertTrue(getMethod(cls2, "").localVars.length == 1) // this + assertTrue(getMethod(companion2, "").localVars.length == 1) // this } def assertLocalVarCount(code: String, numVars: Int): Unit = { - assertTrue(singleMethod(code).localVars.length == numVars) + assertTrue(compileMethod(code).localVars.length == numVars) } } diff --git a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala index cc6d1d7483..b6e8d4fbf2 100644 --- a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +++ b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala @@ -38,9 +38,9 @@ class PatmatBytecodeTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) - assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) + val c = compileClass(code) + assert(getInstructions(c, "s1").count(_.opcode == TABLESWITCH) == 1, textify(c)) + assert(getInstructions(c, "s2").count(_.opcode == TABLESWITCH) == 1, textify(c)) } @Test @@ -66,9 +66,9 @@ class PatmatBytecodeTest extends BytecodeTesting { |} """.stripMargin - val List(c) = compileClasses(code) - assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) - assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) + val c = compileClass(code) + assert(getInstructions(c, "s1").count(_.opcode == TABLESWITCH) == 1, textify(c)) + assert(getInstructions(c, "s2").count(_.opcode == TABLESWITCH) == 1, textify(c)) } @Test @@ -81,9 +81,9 @@ class PatmatBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val c = optCompiler.compileClasses(code).head + val c :: _ = optCompiler.compileClasses(code) - assertSameSummary(getSingleMethod(c, "a"), List( + assertSameSummary(getMethod(c, "a"), List( NEW, DUP, ICONST_1, LDC, "", "y", ARETURN)) } @@ -98,8 +98,8 @@ class PatmatBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val c = optCompiler.compileClasses(code).head - assert(!getSingleMethod(c, "a").instructions.exists(i => i.opcode == IFNULL || i.opcode == IFNONNULL), textify(findAsmMethod(c, "a"))) + val c :: _ = optCompiler.compileClasses(code) + assert(!getInstructions(c, "a").exists(i => i.opcode == IFNULL || i.opcode == IFNONNULL), textify(getAsmMethod(c, "a"))) } @Test @@ -112,8 +112,8 @@ class PatmatBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val c = optCompiler.compileClasses(code).head - assertSameSummary(getSingleMethod(c, "a"), List( + val c :: _ = optCompiler.compileClasses(code) + assertSameSummary(getMethod(c, "a"), List( NEW, DUP, ICONST_1, "boxToInteger", LDC, "", ASTORE /*1*/, ALOAD /*1*/, "y", ASTORE /*2*/, ALOAD /*1*/, "x", INSTANCEOF, IFNE /*R*/, @@ -133,7 +133,7 @@ class PatmatBytecodeTest extends BytecodeTesting { | } |} """.stripMargin - val c = optCompiler.compileClasses(code, allowMessage = _.msg.contains("may not be exhaustive")).head + val c = optCompiler.compileClass(code, allowMessage = _.msg.contains("may not be exhaustive")) val expected = List( ALOAD /*1*/ , INSTANCEOF /*::*/ , IFEQ /*A*/ , @@ -142,8 +142,8 @@ class PatmatBytecodeTest extends BytecodeTesting { -1 /*A*/ , NEW /*MatchError*/ , DUP, ALOAD /*1*/ , "", ATHROW, -1 /*B*/ , ILOAD, IRETURN) - assertSameSummary(getSingleMethod(c, "a"), expected) - assertSameSummary(getSingleMethod(c, "b"), expected) + assertSameSummary(getMethod(c, "a"), expected) + assertSameSummary(getMethod(c, "b"), expected) } @Test @@ -166,17 +166,17 @@ class PatmatBytecodeTest extends BytecodeTesting { |} """.stripMargin val List(c, cMod) = optCompiler.compileClasses(code) - assertSameSummary(getSingleMethod(c, "t1"), List(ICONST_1, ICONST_2, IADD, IRETURN)) - assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, IRETURN)) - assertInvokedMethods(getSingleMethod(c, "t3"), List("C.tplCall", "scala/Tuple2._1", "scala/Tuple2._2$mcI$sp", "scala/MatchError.", "java/lang/String.length")) - assertInvokedMethods(getSingleMethod(c, "t4"), List("C.tplCall", "scala/Tuple2._2$mcI$sp", "scala/MatchError.")) - assertNoInvoke(getSingleMethod(c, "t5")) - assertSameSummary(getSingleMethod(c, "t6"), List(BIPUSH, IRETURN)) + assertSameSummary(getMethod(c, "t1"), List(ICONST_1, ICONST_2, IADD, IRETURN)) + assertSameSummary(getMethod(c, "t2"), List(ICONST_1, IRETURN)) + assertInvokedMethods(getMethod(c, "t3"), List("C.tplCall", "scala/Tuple2._1", "scala/Tuple2._2$mcI$sp", "scala/MatchError.", "java/lang/String.length")) + assertInvokedMethods(getMethod(c, "t4"), List("C.tplCall", "scala/Tuple2._2$mcI$sp", "scala/MatchError.")) + assertNoInvoke(getMethod(c, "t5")) + assertSameSummary(getMethod(c, "t6"), List(BIPUSH, IRETURN)) // MatchError reachable because of the type pattern `s: String` - assertInvokedMethods(getSingleMethod(c, "t7"), List("C.a", "C.b", "scala/MatchError.", "java/lang/String.length")) - assertSameSummary(getSingleMethod(c, "t8"), List(ALOAD, "b", IRETURN)) + assertInvokedMethods(getMethod(c, "t7"), List("C.a", "C.b", "scala/MatchError.", "java/lang/String.length")) + assertSameSummary(getMethod(c, "t8"), List(ALOAD, "b", IRETURN)) // C allocation not eliminated - constructor may have side-effects. - assertSameSummary(getSingleMethod(c, "t9"), List(NEW, DUP, LDC, BIPUSH, "", "a", "toString", ARETURN)) + assertSameSummary(getMethod(c, "t9"), List(NEW, DUP, LDC, BIPUSH, "", "a", "toString", ARETURN)) } } diff --git a/test/junit/scala/tools/testing/BytecodeTesting.scala b/test/junit/scala/tools/testing/BytecodeTesting.scala index d6f8dbc219..b11ad27148 100644 --- a/test/junit/scala/tools/testing/BytecodeTesting.scala +++ b/test/junit/scala/tools/testing/BytecodeTesting.scala @@ -44,14 +44,23 @@ class Compiler(val global: Global) { } } - def compile(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[(String, Array[Byte])] = { + def compileToBytes(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[(String, Array[Byte])] = { val run = newRun run.compileSources(makeSourceFile(scalaCode, "unitTestSource.scala") :: javaCode.map(p => makeSourceFile(p._1, p._2))) checkReport(allowMessage) getGeneratedClassfiles(global.settings.outputDirs.getSingleOutput.get) } - def compileTransformed(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: global.Tree => global.Tree): List[(String, Array[Byte])] = { + def compileClasses(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = { + readAsmClasses(compileToBytes(code, javaCode, allowMessage)) + } + + def compileClass(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): ClassNode = { + val List(c) = compileClasses(code, javaCode, allowMessage) + c + } + + def compileToBytesTransformed(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: global.Tree => global.Tree): List[(String, Array[Byte])] = { import global._ settings.stopBefore.value = "jvm" :: Nil val run = newRun @@ -68,22 +77,30 @@ class Compiler(val global: Global) { getGeneratedClassfiles(settings.outputDirs.getSingleOutput.get) } - def compileClasses(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = { - readAsmClasses(compile(code, javaCode, allowMessage)) + def compileClassesTransformed(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: global.Tree => global.Tree): List[ClassNode] = + readAsmClasses(compileToBytesTransformed(scalaCode, javaCode, beforeBackend)) + + def compileAsmMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[MethodNode] = { + val c = compileClass(s"class C { $code }", allowMessage = allowMessage) + getAsmMethods(c, _ != "") } - def compileMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[MethodNode] = { - compileClasses(s"class C { $code }", allowMessage = allowMessage).head.methods.asScala.toList.filterNot(_.name == "") + def compileAsmMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): MethodNode = { + val List(m) = compileAsmMethods(code, allowMessage) + m } - def singleMethodInstructions(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Instruction] = { + def compileMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Method] = + compileAsmMethods(code, allowMessage).map(convertMethod) + + def compileMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): Method = { val List(m) = compileMethods(code, allowMessage = allowMessage) - instructionsFromMethod(m) + m } - def singleMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): Method = { + def compileInstructions(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Instruction] = { val List(m) = compileMethods(code, allowMessage = allowMessage) - convertMethod(m) + m.instructions } } @@ -145,7 +162,7 @@ object BytecodeTesting { * The output directory is a physical directory, I have not figured out if / how it's possible to * add a VirtualDirectory to the classpath of a compiler. */ - def compileSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[(String, Array[Byte])] = { + def compileToBytesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[(String, Array[Byte])] = { val outDir = AbstractFile.getDirectory(TempDir.createTempDir()) val outDirPath = outDir.canonicalPath val argsWithOutDir = extraArgs + s" -d $outDirPath -cp $outDirPath" @@ -162,13 +179,11 @@ object BytecodeTesting { classfiles } - def compileClassesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()) = { - readAsmClasses(compileSeparately(codes, extraArgs, allowMessage, afterEach)) + def compileClassesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[ClassNode] = { + readAsmClasses(compileToBytesSeparately(codes, extraArgs, allowMessage, afterEach)) } - def readAsmClasses(classfiles: List[(String, Array[Byte])]) = { - classfiles.map(p => AsmUtils.readClass(p._2)).sortBy(_.name) - } + def readAsmClasses(classfiles: List[(String, Array[Byte])]) = classfiles.map(p => AsmUtils.readClass(p._2)).sortBy(_.name) def assertSameCode(method: Method, expected: List[Instruction]): Unit = assertSameCode(method.instructions.dropNonOp, expected) def assertSameCode(actual: List[Instruction], expected: List[Instruction]): Unit = { @@ -218,23 +233,51 @@ object BytecodeTesting { assert(indy.isEmpty, indy) } - def getSingleMethod(classNode: ClassNode, name: String): Method = - convertMethod(classNode.methods.asScala.toList.find(_.name == name).get) + def findClass(cs: List[ClassNode], name: String): ClassNode = { + val List(c) = cs.filter(_.name == name) + c + } + + def getAsmMethods(c: ClassNode, p: String => Boolean): List[MethodNode] = + c.methods.iterator.asScala.filter(m => p(m.name)).toList.sortBy(_.name) - def findAsmMethods(c: ClassNode, p: String => Boolean) = c.methods.iterator.asScala.filter(m => p(m.name)).toList.sortBy(_.name) - def findAsmMethod(c: ClassNode, name: String) = findAsmMethods(c, _ == name).head + def getAsmMethods(c: ClassNode, name: String): List[MethodNode] = + getAsmMethods(c, _ == name) + + def getAsmMethod(c: ClassNode, name: String): MethodNode = { + val List(m) = getAsmMethods(c, name) + m + } + + def getMethods(c: ClassNode, name: String): List[Method] = + getAsmMethods(c, name).map(convertMethod) + + def getMethod(c: ClassNode, name: String): Method = + convertMethod(getAsmMethod(c, name)) + + def getInstructions(c: ClassNode, name: String): List[Instruction] = + getMethod(c, name).instructions /** * Instructions that match `query` when textified. * If `query` starts with a `+`, the next instruction is returned. */ - def findInstr(method: MethodNode, query: String): List[AbstractInsnNode] = { + def findInstrs(method: MethodNode, query: String): List[AbstractInsnNode] = { val useNext = query(0) == '+' val instrPart = if (useNext) query.drop(1) else query val insns = method.instructions.iterator.asScala.filter(i => textify(i) contains instrPart).toList if (useNext) insns.map(_.getNext) else insns } + /** + * Instruction that matches `query` when textified. + * If `query` starts with a `+`, the next instruction is returned. + */ + def findInstr(method: MethodNode, query: String): AbstractInsnNode = { + val List(i) = findInstrs(method, query) + i + } + def assertHandlerLabelPostions(h: ExceptionHandler, instructions: List[Instruction], startIndex: Int, endIndex: Int, handlerIndex: Int): Unit = { val insVec = instructions.toVector assertTrue(h.start == insVec(startIndex) && h.end == insVec(endIndex) && h.handler == insVec(handlerIndex)) -- cgit v1.2.3