summaryrefslogtreecommitdiff
path: root/test/pending/jvm
diff options
context:
space:
mode:
authorSimon Ochsenreither <simon@ochsenreither.de>2015-09-16 17:31:02 +0200
committerSimon Ochsenreither <simon@ochsenreither.de>2015-10-27 15:43:08 +0100
commit1a8daa2d6cbf46a7cdd9180c11c641adabcf6d92 (patch)
treeb7014fdfe397864c621322bfe00ff3307df5017e /test/pending/jvm
parent4321ea458ad1258f273ee22a4c6a7606ab054501 (diff)
downloadscala-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')
-rw-r--r--test/pending/jvm/constant-optimization/Foo_1.flags1
-rw-r--r--test/pending/jvm/constant-optimization/Foo_1.scala9
-rw-r--r--test/pending/jvm/constant-optimization/Test.scala27
-rw-r--r--test/pending/jvm/patmat_opt_ignore_underscore.check1
-rw-r--r--test/pending/jvm/patmat_opt_ignore_underscore.flags1
-rw-r--r--test/pending/jvm/patmat_opt_ignore_underscore/Analyzed_1.scala29
-rw-r--r--test/pending/jvm/patmat_opt_ignore_underscore/test.scala18
-rw-r--r--test/pending/jvm/patmat_opt_no_nullcheck.check1
-rw-r--r--test/pending/jvm/patmat_opt_no_nullcheck.flags1
-rw-r--r--test/pending/jvm/patmat_opt_no_nullcheck/Analyzed_1.scala24
-rw-r--r--test/pending/jvm/patmat_opt_no_nullcheck/test.scala14
-rw-r--r--test/pending/jvm/patmat_opt_primitive_typetest.check1
-rw-r--r--test/pending/jvm/patmat_opt_primitive_typetest.flags1
-rw-r--r--test/pending/jvm/patmat_opt_primitive_typetest/Analyzed_1.scala24
-rw-r--r--test/pending/jvm/patmat_opt_primitive_typetest/test.scala8
-rw-r--r--test/pending/jvm/t7006.check29
-rw-r--r--test/pending/jvm/t7006/Foo_1.flags1
-rw-r--r--test/pending/jvm/t7006/Foo_1.scala10
-rw-r--r--test/pending/jvm/t7006/Test.scala21
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)
+ }
+}