diff options
author | Simon Ochsenreither <simon@ochsenreither.de> | 2015-09-16 17:31:02 +0200 |
---|---|---|
committer | Simon Ochsenreither <simon@ochsenreither.de> | 2015-10-27 15:43:08 +0100 |
commit | 1a8daa2d6cbf46a7cdd9180c11c641adabcf6d92 (patch) | |
tree | b7014fdfe397864c621322bfe00ff3307df5017e /test/pending/jvm | |
parent | 4321ea458ad1258f273ee22a4c6a7606ab054501 (diff) | |
download | scala-1a8daa2d6cbf46a7cdd9180c11c641adabcf6d92.tar.gz scala-1a8daa2d6cbf46a7cdd9180c11c641adabcf6d92.tar.bz2 scala-1a8daa2d6cbf46a7cdd9180c11c641adabcf6d92.zip |
Remove GenASM, merge remaining common code snippets
With GenBCode being the default and only supported backend for Java 8,
we can get rid of GenASM.
This commit also fixes/migrates/moves to pending/deletes tests which
depended on GenASM before.
Diffstat (limited to 'test/pending/jvm')
19 files changed, 221 insertions, 0 deletions
diff --git a/test/pending/jvm/constant-optimization/Foo_1.flags b/test/pending/jvm/constant-optimization/Foo_1.flags new file mode 100644 index 0000000000..9691c0985d --- /dev/null +++ b/test/pending/jvm/constant-optimization/Foo_1.flags @@ -0,0 +1 @@ +// constant otimization not there yet, -Yopt:nullness-tracking not enough. diff --git a/test/pending/jvm/constant-optimization/Foo_1.scala b/test/pending/jvm/constant-optimization/Foo_1.scala new file mode 100644 index 0000000000..6f408044d7 --- /dev/null +++ b/test/pending/jvm/constant-optimization/Foo_1.scala @@ -0,0 +1,9 @@ +class Foo_1 { + def foo() { + // constant optimization should eliminate all branches + val i = 1 + val x = if (i != 1) null else "good" + val y = if (x == null) "good" else x + "" + println(y) + } +}
\ No newline at end of file diff --git a/test/pending/jvm/constant-optimization/Test.scala b/test/pending/jvm/constant-optimization/Test.scala new file mode 100644 index 0000000000..dc0f8f6103 --- /dev/null +++ b/test/pending/jvm/constant-optimization/Test.scala @@ -0,0 +1,27 @@ + +import scala.tools.partest.BytecodeTest +import scala.tools.asm +import asm.tree.InsnList +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + val comparisons = Set(asm.Opcodes.IF_ACMPEQ, asm.Opcodes.IF_ACMPNE, asm.Opcodes.IF_ICMPEQ, asm.Opcodes.IF_ICMPGE, asm.Opcodes.IF_ICMPGT, asm.Opcodes.IF_ICMPLE, + asm.Opcodes.IF_ICMPLT, asm.Opcodes.IF_ICMPNE, asm.Opcodes.IFEQ, asm.Opcodes.IFGE, asm.Opcodes.IFGT, asm.Opcodes.IFLE, asm.Opcodes.IFLT, + asm.Opcodes.IFNE, asm.Opcodes.IFNONNULL, asm.Opcodes.IFNULL) + + def show: Unit = { + val classNode = loadClassNode("Foo_1") + val methodNode = getMethod(classNode, "foo") + // after optimization there should be no comparisons left + val expected = 0 + + val got = countComparisons(methodNode.instructions) + assert(got == expected, s"expected $expected but got $got comparisons") + } + + def countComparisons(insnList: InsnList): Int = { + def isComparison(node: asm.tree.AbstractInsnNode): Boolean = + (comparisons contains node.getOpcode) + insnList.iterator.asScala count isComparison + } +}
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_ignore_underscore.check b/test/pending/jvm/patmat_opt_ignore_underscore.check new file mode 100644 index 0000000000..43f53aba12 --- /dev/null +++ b/test/pending/jvm/patmat_opt_ignore_underscore.check @@ -0,0 +1 @@ +bytecode identical diff --git a/test/pending/jvm/patmat_opt_ignore_underscore.flags b/test/pending/jvm/patmat_opt_ignore_underscore.flags new file mode 100644 index 0000000000..453b6b7895 --- /dev/null +++ b/test/pending/jvm/patmat_opt_ignore_underscore.flags @@ -0,0 +1 @@ +-Yopt:l:project
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_ignore_underscore/Analyzed_1.scala b/test/pending/jvm/patmat_opt_ignore_underscore/Analyzed_1.scala new file mode 100644 index 0000000000..b0506018f6 --- /dev/null +++ b/test/pending/jvm/patmat_opt_ignore_underscore/Analyzed_1.scala @@ -0,0 +1,29 @@ +// this class's bytecode, compiled under -optimize is analyzed by the test +// method a's bytecode should be identical to method b's bytecode +// this is not the best test for shielding against regressing on this particular issue, +// but it sets the stage for checking the bytecode emitted by the pattern matcher and +// comparing it to manually tuned code using if/then/else etc. +class SameBytecode { + case class Foo(x: Any, y: String) + + def a = + Foo(1, "a") match { + case Foo(_: String, y) => y + } + + // this method's body holds the tree that should be generated by the pattern matcher for method a (-Xprint:patmat) + // the test checks that bytecode for a and b is identical (modulo line numbers) + // we can't diff trees as they are quite different (patmat uses jumps to labels that cannot be expressed in source, for example) + // note that the actual tree is quite bad: we do an unnecessary null check, isInstanceOf and local val (x3) + // some of these will be fixed soon (the initial null check is for the scrutinee, which is harder to fix in patmat) + def b: String = { + val x1 = Foo(1, "a") + if (x1.ne(null)) { + if (x1.x.isInstanceOf[String]) { + return x1.y + } + } + + throw new MatchError(x1) + } +}
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_ignore_underscore/test.scala b/test/pending/jvm/patmat_opt_ignore_underscore/test.scala new file mode 100644 index 0000000000..d6630e80a0 --- /dev/null +++ b/test/pending/jvm/patmat_opt_ignore_underscore/test.scala @@ -0,0 +1,18 @@ +/* + * filter: inliner warning; re-run with + */ +import scala.tools.partest.BytecodeTest + +import scala.tools.nsc.util.JavaClassPath +import java.io.InputStream +import scala.tools.asm +import asm.ClassReader +import asm.tree.{ClassNode, InsnList} +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("SameBytecode") + sameBytecode(getMethod(classNode, "a"), getMethod(classNode, "b")) + } +} diff --git a/test/pending/jvm/patmat_opt_no_nullcheck.check b/test/pending/jvm/patmat_opt_no_nullcheck.check new file mode 100644 index 0000000000..43f53aba12 --- /dev/null +++ b/test/pending/jvm/patmat_opt_no_nullcheck.check @@ -0,0 +1 @@ +bytecode identical diff --git a/test/pending/jvm/patmat_opt_no_nullcheck.flags b/test/pending/jvm/patmat_opt_no_nullcheck.flags new file mode 100644 index 0000000000..453b6b7895 --- /dev/null +++ b/test/pending/jvm/patmat_opt_no_nullcheck.flags @@ -0,0 +1 @@ +-Yopt:l:project
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_no_nullcheck/Analyzed_1.scala b/test/pending/jvm/patmat_opt_no_nullcheck/Analyzed_1.scala new file mode 100644 index 0000000000..1e4d564cdf --- /dev/null +++ b/test/pending/jvm/patmat_opt_no_nullcheck/Analyzed_1.scala @@ -0,0 +1,24 @@ +// this class's bytecode, compiled under -optimize is analyzed by the test +// method a's bytecode should be identical to method b's bytecode +case class Foo(x: Any) + +class SameBytecode { + def a = + (Foo(1): Any) match { + case Foo(_: String) => + } + + // there's no null check + def b: Unit = { + val x1: Any = Foo(1) + if (x1.isInstanceOf[Foo]) { + val x3 = x1.asInstanceOf[Foo] + if (x3.x.isInstanceOf[String]) { + val x = () + return + } + } + + throw new MatchError(x1) + } +}
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_no_nullcheck/test.scala b/test/pending/jvm/patmat_opt_no_nullcheck/test.scala new file mode 100644 index 0000000000..5a4a398b67 --- /dev/null +++ b/test/pending/jvm/patmat_opt_no_nullcheck/test.scala @@ -0,0 +1,14 @@ +/* + * filter: inliner warning; re-run with + */ +import scala.tools.partest.{ BytecodeTest, ASMConverters } + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("SameBytecode") + // ASM and GenBCode assign variable slots slightly differently + val instrsA = ASMConverters.instructionsFromMethod(getMethod(classNode, "a")) + val instrsB = ASMConverters.instructionsFromMethod(getMethod(classNode, "b")) + assert(ASMConverters.equivalentBytecode(instrsA, instrsB), diffInstructions(instrsA, instrsB)) // doesn't work + } +} diff --git a/test/pending/jvm/patmat_opt_primitive_typetest.check b/test/pending/jvm/patmat_opt_primitive_typetest.check new file mode 100644 index 0000000000..43f53aba12 --- /dev/null +++ b/test/pending/jvm/patmat_opt_primitive_typetest.check @@ -0,0 +1 @@ +bytecode identical diff --git a/test/pending/jvm/patmat_opt_primitive_typetest.flags b/test/pending/jvm/patmat_opt_primitive_typetest.flags new file mode 100644 index 0000000000..19c578e4ad --- /dev/null +++ b/test/pending/jvm/patmat_opt_primitive_typetest.flags @@ -0,0 +1 @@ +-Yopt:l:project diff --git a/test/pending/jvm/patmat_opt_primitive_typetest/Analyzed_1.scala b/test/pending/jvm/patmat_opt_primitive_typetest/Analyzed_1.scala new file mode 100644 index 0000000000..c961082fa7 --- /dev/null +++ b/test/pending/jvm/patmat_opt_primitive_typetest/Analyzed_1.scala @@ -0,0 +1,24 @@ +// this class's bytecode, compiled under -optimize is analyzed by the test +// method a's bytecode should be identical to method b's bytecode +class SameBytecode { + case class Foo(x: Int, y: String) + + def a = + Foo(1, "a") match { + case Foo(_: Int, y) => y + } + + // this method's body holds the tree that should be generated by the pattern matcher for method a (-Xprint:patmat) + // the test checks that bytecode for a and b is identical (modulo line numbers) + // we can't diff trees as they are quite different (patmat uses jumps to labels that cannot be expressed in source, for example) + // note that the actual tree is quite bad: we do an unnecessary null check, and local val (x3) + // some of these will be fixed soon (the initial null check is for the scrutinee, which is harder to fix in patmat) + def b: String = { + val x1 = Foo(1, "a") + if (x1.ne(null)) { + return x1.y + } + + throw new MatchError(x1) + } +}
\ No newline at end of file diff --git a/test/pending/jvm/patmat_opt_primitive_typetest/test.scala b/test/pending/jvm/patmat_opt_primitive_typetest/test.scala new file mode 100644 index 0000000000..2927e763d5 --- /dev/null +++ b/test/pending/jvm/patmat_opt_primitive_typetest/test.scala @@ -0,0 +1,8 @@ +import scala.tools.partest.BytecodeTest + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("SameBytecode") + sameBytecode(getMethod(classNode, "a"), getMethod(classNode, "b")) + } +} diff --git a/test/pending/jvm/t7006.check b/test/pending/jvm/t7006.check new file mode 100644 index 0000000000..6294b14d62 --- /dev/null +++ b/test/pending/jvm/t7006.check @@ -0,0 +1,29 @@ +[running phase parser on Foo_1.scala] +[running phase namer on Foo_1.scala] +[running phase packageobjects on Foo_1.scala] +[running phase typer on Foo_1.scala] +[running phase patmat on Foo_1.scala] +[running phase superaccessors on Foo_1.scala] +[running phase extmethods on Foo_1.scala] +[running phase pickler on Foo_1.scala] +[running phase refchecks on Foo_1.scala] +[running phase uncurry on Foo_1.scala] +[running phase tailcalls on Foo_1.scala] +[running phase specialize on Foo_1.scala] +[running phase explicitouter on Foo_1.scala] +[running phase erasure on Foo_1.scala] +[running phase posterasure on Foo_1.scala] +[running phase lazyvals on Foo_1.scala] +[running phase lambdalift on Foo_1.scala] +[running phase constructors on Foo_1.scala] +[running phase flatten on Foo_1.scala] +[running phase mixin on Foo_1.scala] +[running phase cleanup on Foo_1.scala] +[running phase delambdafy on Foo_1.scala] +[running phase icode on Foo_1.scala] +[running phase inliner on Foo_1.scala] +[running phase inlinehandlers on Foo_1.scala] +[running phase closelim on Foo_1.scala] +[running phase constopt on Foo_1.scala] +[running phase dce on Foo_1.scala] +[running phase jvm on icode] diff --git a/test/pending/jvm/t7006/Foo_1.flags b/test/pending/jvm/t7006/Foo_1.flags new file mode 100644 index 0000000000..5d1b6b2644 --- /dev/null +++ b/test/pending/jvm/t7006/Foo_1.flags @@ -0,0 +1 @@ +-Yopt:l:project -Ydebug -Xfatal-warnings diff --git a/test/pending/jvm/t7006/Foo_1.scala b/test/pending/jvm/t7006/Foo_1.scala new file mode 100644 index 0000000000..3985557d9f --- /dev/null +++ b/test/pending/jvm/t7006/Foo_1.scala @@ -0,0 +1,10 @@ +class Foo_1 { + def foo { + try { + val x = 3 // this will be optimized away, leaving a useless jump only block + } finally { + print("hello") + } + while(true){} // ensure infinite loop doesn't break the algorithm + } +} diff --git a/test/pending/jvm/t7006/Test.scala b/test/pending/jvm/t7006/Test.scala new file mode 100644 index 0000000000..7b4a8c45fb --- /dev/null +++ b/test/pending/jvm/t7006/Test.scala @@ -0,0 +1,21 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.asm +import asm.tree.InsnList +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("Foo_1") + val methodNode = getMethod(classNode, "foo") + val nopCount = count(methodNode.instructions, asm.Opcodes.NOP) + val gotoCount = count(methodNode.instructions, asm.Opcodes.GOTO) + assert(nopCount == 0, s"NOPs expected: 0, actual: $nopCount") + assert(gotoCount == 1, s"GOTOs expected: 1, actual: $gotoCount") + } + + def count(insnList: InsnList, opcode: Int): Int = { + def isNop(node: asm.tree.AbstractInsnNode): Boolean = + (node.getOpcode == opcode) + insnList.iterator.asScala.count(isNop) + } +} |