diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2016-01-24 13:03:22 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-01-24 13:03:22 +0100 |
commit | b0831e774e290148ce28cb7957794542dffe0366 (patch) | |
tree | 1380b224b4fe31598b07b3ddee9a46ff2e3eaf10 /test/pending/run | |
parent | 1a9e649e34cda4306537d74ab425c33d5f6a77db (diff) | |
parent | 1081e718f8f8e174dbf615e42b157e187d3d3886 (diff) | |
download | scala-b0831e774e290148ce28cb7957794542dffe0366.tar.gz scala-b0831e774e290148ce28cb7957794542dffe0366.tar.bz2 scala-b0831e774e290148ce28cb7957794542dffe0366.zip |
Merge remote-tracking branch 'upstream/2.12.x' into opt/elimBoxes
Diffstat (limited to 'test/pending/run')
-rw-r--r-- | test/pending/run/inline-ex-handlers.check | 491 | ||||
-rw-r--r-- | test/pending/run/inline-ex-handlers.scala | 329 | ||||
-rw-r--r-- | test/pending/run/t5313.check | 12 | ||||
-rw-r--r-- | test/pending/run/t5313.scala | 54 | ||||
-rw-r--r-- | test/pending/run/t6955.scala | 33 | ||||
-rw-r--r-- | test/pending/run/t6956.scala | 31 | ||||
-rw-r--r-- | test/pending/run/test-cpp.check | 81 | ||||
-rw-r--r-- | test/pending/run/test-cpp.scala | 104 |
8 files changed, 1135 insertions, 0 deletions
diff --git a/test/pending/run/inline-ex-handlers.check b/test/pending/run/inline-ex-handlers.check new file mode 100644 index 0000000000..fce32771b4 --- /dev/null +++ b/test/pending/run/inline-ex-handlers.check @@ -0,0 +1,491 @@ +--- a ++++ b +@@ -171,5 +171,5 @@ + def productElement(x$1: Int (INT)): Object { +- locals: value x$1, value x1 ++ locals: value x$1, value x1, variable boxed1 + startBlock: 1 +- blocks: [1,2,3,4] ++ blocks: [1,3,4] + +@@ -186,2 +186,4 @@ + 92 LOAD_LOCAL(value x$1) ++ 92 STORE_LOCAL(variable boxed1) ++ 92 LOAD_LOCAL(variable boxed1) + 92 BOX INT +@@ -194,5 +196,2 @@ + 92 CALL_METHOD MyException.message (dynamic) +- 92 JUMP 2 +- +- 2: + 92 RETURN(REF(class Object)) +@@ -246,3 +245,3 @@ + startBlock: 1 +- blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18] ++ blocks: [1,2,3,4,5,6,8,11,12,13,14,15,16,17,18] + +@@ -257,5 +256,2 @@ + 92 SCOPE_ENTER value x1 +- 92 JUMP 7 +- +- 7: + 92 LOAD_LOCAL(value x1) +@@ -408,5 +404,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, value ex6, value x4, value x5, value message, value x ++ locals: value args, variable result, value ex6, value x4, value x5, value x + startBlock: 1 +- blocks: [1,2,3,4,5,8,10,11,13] ++ blocks: [1,2,3,5,8,10,11,13,14] + +@@ -434,4 +430,13 @@ + 103 CALL_METHOD MyException.<init> (static-instance) +- 103 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 14 + ++ 14: ++ 101 LOAD_LOCAL(value ex6) ++ 101 STORE_LOCAL(value x4) ++ 101 SCOPE_ENTER value x4 ++ 106 LOAD_LOCAL(value x4) ++ 106 IS_INSTANCE REF(class MyException) ++ 106 CZJUMP (BOOL)NE ? 5 : 8 ++ + 13: +@@ -447,5 +452,2 @@ + 101 SCOPE_ENTER value x4 +- 101 JUMP 4 +- +- 4: + 106 LOAD_LOCAL(value x4) +@@ -459,8 +461,5 @@ + 106 SCOPE_ENTER value x5 +- 106 LOAD_LOCAL(value x5) +- 106 CALL_METHOD MyException.message (dynamic) +- 106 STORE_LOCAL(value message) +- 106 SCOPE_ENTER value message + 106 LOAD_MODULE object Predef +- 106 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 106 CALL_METHOD MyException.message (dynamic) + 106 CALL_METHOD scala.Predef.println (dynamic) +@@ -536,3 +535,3 @@ + startBlock: 1 +- blocks: [1,2,3,4,6,7,9,10] ++ blocks: [1,3,4,6,7,9,10,11,12,13] + +@@ -565,4 +564,9 @@ + 306 CALL_METHOD MyException.<init> (static-instance) +- 306 THROW(MyException) ++ ? JUMP 11 + ++ 11: ++ ? LOAD_LOCAL(variable monitor4) ++ 305 MONITOR_EXIT ++ ? JUMP 12 ++ + 9: +@@ -571,3 +575,3 @@ + 305 MONITOR_EXIT +- ? THROW(Throwable) ++ ? JUMP 12 + +@@ -577,4 +581,11 @@ + 304 MONITOR_EXIT +- ? THROW(Throwable) ++ ? STORE_LOCAL(value t) ++ ? JUMP 13 + ++ 12: ++ ? LOAD_LOCAL(variable monitor3) ++ 304 MONITOR_EXIT ++ ? STORE_LOCAL(value t) ++ ? JUMP 13 ++ + 3: +@@ -591,5 +602,14 @@ + 310 CALL_METHOD scala.Predef.println (dynamic) +- 310 JUMP 2 ++ 300 RETURN(UNIT) + +- 2: ++ 13: ++ 310 LOAD_MODULE object Predef ++ 310 CALL_PRIMITIVE(StartConcat) ++ 310 CONSTANT("Caught crash: ") ++ 310 CALL_PRIMITIVE(StringConcat(REF(class String))) ++ 310 LOAD_LOCAL(value t) ++ 310 CALL_METHOD java.lang.Throwable.toString (dynamic) ++ 310 CALL_PRIMITIVE(StringConcat(REF(class String))) ++ 310 CALL_PRIMITIVE(EndConcat) ++ 310 CALL_METHOD scala.Predef.println (dynamic) + 300 RETURN(UNIT) +@@ -601,6 +621,6 @@ + with finalizer: null +- catch (Throwable) in Vector(7, 9, 10) starting at: 6 ++ catch (Throwable) in Vector(7, 9, 10, 11) starting at: 6 + consisting of blocks: List(6) + with finalizer: null +- catch (Throwable) in Vector(4, 6, 7, 9, 10) starting at: 3 ++ catch (Throwable) in Vector(4, 6, 7, 9, 10, 11, 12) starting at: 3 + consisting of blocks: List(3) +@@ -636,3 +656,3 @@ + startBlock: 1 +- blocks: [1,3,4,5,6,8,9] ++ blocks: [1,3,4,5,6,8,9,10,11] + +@@ -660,4 +680,10 @@ + 78 CALL_METHOD java.lang.IllegalArgumentException.<init> (static-instance) +- 78 THROW(IllegalArgumentException) ++ ? STORE_LOCAL(value e) ++ ? JUMP 10 + ++ 10: ++ 81 LOAD_LOCAL(value e) ++ ? STORE_LOCAL(variable exc1) ++ ? JUMP 11 ++ + 8: +@@ -686,3 +712,4 @@ + 81 LOAD_LOCAL(value e) +- 81 THROW(Exception) ++ ? STORE_LOCAL(variable exc1) ++ ? JUMP 11 + +@@ -703,2 +730,15 @@ + ++ 11: ++ 83 LOAD_MODULE object Predef ++ 83 CONSTANT("finally") ++ 83 CALL_METHOD scala.Predef.println (dynamic) ++ 84 LOAD_LOCAL(variable result) ++ 84 CONSTANT(1) ++ 84 CALL_PRIMITIVE(Arithmetic(SUB,INT)) ++ 84 CONSTANT(2) ++ 84 CALL_PRIMITIVE(Arithmetic(DIV,INT)) ++ 84 STORE_LOCAL(variable result) ++ 84 LOAD_LOCAL(variable exc1) ++ 84 THROW(Throwable) ++ + } +@@ -708,3 +748,3 @@ + with finalizer: null +- catch (<none>) in Vector(4, 5, 6, 8) starting at: 3 ++ catch (<none>) in Vector(4, 5, 6, 8, 10) starting at: 3 + consisting of blocks: List(3) +@@ -732,5 +772,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value message, value x, value ex6, value x4, value x5, value message, value x ++ locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value x, value ex6, value x4, value x5, value x + startBlock: 1 +- blocks: [1,3,4,5,6,9,13,14,15,18,20,21,23,24] ++ blocks: [1,3,4,5,6,9,13,14,15,18,20,21,23,24,25,26,27] + +@@ -758,4 +798,11 @@ + 172 CALL_METHOD MyException.<init> (static-instance) +- 172 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 25 + ++ 25: ++ 170 LOAD_LOCAL(value ex6) ++ 170 STORE_LOCAL(value x4) ++ 170 SCOPE_ENTER value x4 ++ 170 JUMP 14 ++ + 23: +@@ -798,8 +845,5 @@ + 175 SCOPE_ENTER value x5 +- 175 LOAD_LOCAL(value x5) +- 175 CALL_METHOD MyException.message (dynamic) +- 175 STORE_LOCAL(value message) +- 175 SCOPE_ENTER value message + 176 LOAD_MODULE object Predef +- 176 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 176 CALL_METHOD MyException.message (dynamic) + 176 CALL_METHOD scala.Predef.println (dynamic) +@@ -807,5 +851,7 @@ + 177 DUP(REF(class MyException)) +- 177 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 177 CALL_METHOD MyException.message (dynamic) + 177 CALL_METHOD MyException.<init> (static-instance) +- 177 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 26 + +@@ -813,3 +859,4 @@ + 170 LOAD_LOCAL(value ex6) +- 170 THROW(Throwable) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 26 + +@@ -823,2 +870,8 @@ + ++ 26: ++ 169 LOAD_LOCAL(value ex6) ++ 169 STORE_LOCAL(value x4) ++ 169 SCOPE_ENTER value x4 ++ 169 JUMP 5 ++ + 5: +@@ -833,8 +886,5 @@ + 180 SCOPE_ENTER value x5 +- 180 LOAD_LOCAL(value x5) +- 180 CALL_METHOD MyException.message (dynamic) +- 180 STORE_LOCAL(value message) +- 180 SCOPE_ENTER value message + 181 LOAD_MODULE object Predef +- 181 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 181 CALL_METHOD MyException.message (dynamic) + 181 CALL_METHOD scala.Predef.println (dynamic) +@@ -842,5 +892,7 @@ + 182 DUP(REF(class MyException)) +- 182 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 182 CALL_METHOD MyException.message (dynamic) + 182 CALL_METHOD MyException.<init> (static-instance) +- 182 THROW(MyException) ++ ? STORE_LOCAL(variable exc2) ++ ? JUMP 27 + +@@ -848,3 +900,4 @@ + 169 LOAD_LOCAL(value ex6) +- 169 THROW(Throwable) ++ ? STORE_LOCAL(variable exc2) ++ ? JUMP 27 + +@@ -865,2 +918,15 @@ + ++ 27: ++ 184 LOAD_MODULE object Predef ++ 184 CONSTANT("finally") ++ 184 CALL_METHOD scala.Predef.println (dynamic) ++ 185 LOAD_LOCAL(variable result) ++ 185 CONSTANT(1) ++ 185 CALL_PRIMITIVE(Arithmetic(SUB,INT)) ++ 185 CONSTANT(2) ++ 185 CALL_PRIMITIVE(Arithmetic(DIV,INT)) ++ 185 STORE_LOCAL(variable result) ++ 185 LOAD_LOCAL(variable exc2) ++ 185 THROW(Throwable) ++ + } +@@ -870,6 +936,6 @@ + with finalizer: null +- catch (Throwable) in Vector(13, 14, 15, 18, 20, 21, 23) starting at: 4 ++ catch (Throwable) in Vector(13, 14, 15, 18, 20, 21, 23, 25) starting at: 4 + consisting of blocks: List(9, 8, 6, 5, 4) + with finalizer: null +- catch (<none>) in Vector(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23) starting at: 3 ++ catch (<none>) in Vector(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23, 25, 26) starting at: 3 + consisting of blocks: List(3) +@@ -897,5 +963,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, value e, value ex6, value x4, value x5, value message, value x ++ locals: value args, variable result, value e, value ex6, value x4, value x5, value x + startBlock: 1 +- blocks: [1,2,3,6,7,8,11,13,14,16] ++ blocks: [1,2,3,6,7,8,11,13,14,16,17] + +@@ -923,4 +989,11 @@ + 124 CALL_METHOD MyException.<init> (static-instance) +- 124 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 17 + ++ 17: ++ 122 LOAD_LOCAL(value ex6) ++ 122 STORE_LOCAL(value x4) ++ 122 SCOPE_ENTER value x4 ++ 122 JUMP 7 ++ + 16: +@@ -948,8 +1021,5 @@ + 127 SCOPE_ENTER value x5 +- 127 LOAD_LOCAL(value x5) +- 127 CALL_METHOD MyException.message (dynamic) +- 127 STORE_LOCAL(value message) +- 127 SCOPE_ENTER value message + 127 LOAD_MODULE object Predef +- 127 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 127 CALL_METHOD MyException.message (dynamic) + 127 CALL_METHOD scala.Predef.println (dynamic) +@@ -982,3 +1052,3 @@ + with finalizer: null +- catch (IllegalArgumentException) in Vector(6, 7, 8, 11, 13, 14, 16) starting at: 3 ++ catch (IllegalArgumentException) in Vector(6, 7, 8, 11, 13, 14, 16, 17) starting at: 3 + consisting of blocks: List(3) +@@ -1006,5 +1076,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, value ex6, value x4, value x5, value message, value x, value e ++ locals: value args, variable result, value ex6, value x4, value x5, value x, value e + startBlock: 1 +- blocks: [1,2,3,4,5,8,12,13,14,16] ++ blocks: [1,2,3,5,8,12,13,14,16,17] + +@@ -1032,4 +1102,13 @@ + 148 CALL_METHOD MyException.<init> (static-instance) +- 148 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 17 + ++ 17: ++ 145 LOAD_LOCAL(value ex6) ++ 145 STORE_LOCAL(value x4) ++ 145 SCOPE_ENTER value x4 ++ 154 LOAD_LOCAL(value x4) ++ 154 IS_INSTANCE REF(class MyException) ++ 154 CZJUMP (BOOL)NE ? 5 : 8 ++ + 16: +@@ -1053,5 +1132,2 @@ + 145 SCOPE_ENTER value x4 +- 145 JUMP 4 +- +- 4: + 154 LOAD_LOCAL(value x4) +@@ -1065,8 +1141,5 @@ + 154 SCOPE_ENTER value x5 +- 154 LOAD_LOCAL(value x5) +- 154 CALL_METHOD MyException.message (dynamic) +- 154 STORE_LOCAL(value message) +- 154 SCOPE_ENTER value message + 154 LOAD_MODULE object Predef +- 154 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 154 CALL_METHOD MyException.message (dynamic) + 154 CALL_METHOD scala.Predef.println (dynamic) +@@ -1287,3 +1360,3 @@ + startBlock: 1 +- blocks: [1,2,3,4,5,7] ++ blocks: [1,2,3,4,5,7,8] + +@@ -1311,4 +1384,11 @@ + 38 CALL_METHOD java.lang.IllegalArgumentException.<init> (static-instance) +- 38 THROW(IllegalArgumentException) ++ ? STORE_LOCAL(value e) ++ ? JUMP 8 + ++ 8: ++ 42 LOAD_MODULE object Predef ++ 42 CONSTANT("IllegalArgumentException") ++ 42 CALL_METHOD scala.Predef.println (dynamic) ++ 42 JUMP 2 ++ + 7: +@@ -1358,5 +1438,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, value ex6, value x4, value x5, value message, value x ++ locals: value args, variable result, value ex6, value x4, value x5, value x + startBlock: 1 +- blocks: [1,2,3,4,5,8,10,11,13,14,16] ++ blocks: [1,2,3,5,8,10,11,13,14,16,17] + +@@ -1384,3 +1464,4 @@ + 203 CALL_METHOD MyException.<init> (static-instance) +- 203 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 17 + +@@ -1404,4 +1485,13 @@ + 209 CALL_METHOD MyException.<init> (static-instance) +- 209 THROW(MyException) ++ ? STORE_LOCAL(value ex6) ++ ? JUMP 17 + ++ 17: ++ 200 LOAD_LOCAL(value ex6) ++ 200 STORE_LOCAL(value x4) ++ 200 SCOPE_ENTER value x4 ++ 212 LOAD_LOCAL(value x4) ++ 212 IS_INSTANCE REF(class MyException) ++ 212 CZJUMP (BOOL)NE ? 5 : 8 ++ + 16: +@@ -1417,5 +1507,2 @@ + 200 SCOPE_ENTER value x4 +- 200 JUMP 4 +- +- 4: + 212 LOAD_LOCAL(value x4) +@@ -1429,8 +1516,5 @@ + 212 SCOPE_ENTER value x5 +- 212 LOAD_LOCAL(value x5) +- 212 CALL_METHOD MyException.message (dynamic) +- 212 STORE_LOCAL(value message) +- 212 SCOPE_ENTER value message + 213 LOAD_MODULE object Predef +- 213 LOAD_LOCAL(value message) ++ ? LOAD_LOCAL(value x5) ++ 213 CALL_METHOD MyException.message (dynamic) + 213 CALL_METHOD scala.Predef.println (dynamic) +@@ -1478,3 +1562,3 @@ + startBlock: 1 +- blocks: [1,2,3,4,5,7] ++ blocks: [1,2,3,4,5,7,8] + +@@ -1502,4 +1586,11 @@ + 58 CALL_METHOD java.lang.IllegalArgumentException.<init> (static-instance) +- 58 THROW(IllegalArgumentException) ++ ? STORE_LOCAL(value e) ++ ? JUMP 8 + ++ 8: ++ 62 LOAD_MODULE object Predef ++ 62 CONSTANT("RuntimeException") ++ 62 CALL_METHOD scala.Predef.println (dynamic) ++ 62 JUMP 2 ++ + 7: +@@ -1551,3 +1642,3 @@ + startBlock: 1 +- blocks: [1,3,4] ++ blocks: [1,3,4,5] + +@@ -1571,4 +1662,9 @@ + 229 CALL_METHOD MyException.<init> (static-instance) +- 229 THROW(MyException) ++ ? JUMP 5 + ++ 5: ++ ? LOAD_LOCAL(variable monitor1) ++ 228 MONITOR_EXIT ++ 228 THROW(Throwable) ++ + 3: +@@ -1577,3 +1673,3 @@ + 228 MONITOR_EXIT +- ? THROW(Throwable) ++ 228 THROW(Throwable) + +@@ -1605,5 +1701,5 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, variable result, variable monitor2, variable monitorResult1 ++ locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 + startBlock: 1 +- blocks: [1,3,4] ++ blocks: [1,3,4,5] + +@@ -1630,4 +1726,12 @@ + 245 CALL_METHOD MyException.<init> (static-instance) +- 245 THROW(MyException) ++ ? STORE_LOCAL(value exception$1) ++ ? DROP ConcatClass ++ ? LOAD_LOCAL(value exception$1) ++ ? JUMP 5 + ++ 5: ++ ? LOAD_LOCAL(variable monitor2) ++ 244 MONITOR_EXIT ++ 244 THROW(Throwable) ++ + 3: +@@ -1636,3 +1740,3 @@ + 244 MONITOR_EXIT +- ? THROW(Throwable) ++ 244 THROW(Throwable) diff --git a/test/pending/run/inline-ex-handlers.scala b/test/pending/run/inline-ex-handlers.scala new file mode 100644 index 0000000000..964594d258 --- /dev/null +++ b/test/pending/run/inline-ex-handlers.scala @@ -0,0 +1,329 @@ +import scala.tools.partest.IcodeComparison + +object Test extends IcodeComparison { + override def printIcodeAfterPhase = "inlinehandlers" +} + +import scala.util.Random._ + +/** There should be no inlining taking place in this class */ +object TestInlineHandlersNoInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersNoInline") + var result = -1 + + try { + if (nextInt % 2 == 0) + throw new IllegalArgumentException("something") + result = 1 + } catch { + case e: StackOverflowError => + println("Stack overflow") + } + + result + } +} + +/** Just a simple inlining should take place in this class */ +object TestInlineHandlersSimpleInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSimpleInline") + var result = -1 + + try { + if (nextInt % 2 == 0) + throw new IllegalArgumentException("something") + result = 1 + } catch { + case e: IllegalArgumentException => + println("IllegalArgumentException") + } + + result + } +} + +/** Inlining should take place because the handler is taking a superclass of the exception thrown */ +object TestInlineHandlersSubclassInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSubclassInline") + var result = -1 + + try { + if (nextInt % 2 == 0) + throw new IllegalArgumentException("something") + result = 1 + } catch { + case e: RuntimeException => + println("RuntimeException") + } + + result + } +} + +/** For this class, the finally handler should be inlined */ +object TestInlineHandlersFinallyInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersFinallyInline") + var result = -1 + + try { + if (nextInt % 2 == 0) + throw new IllegalArgumentException("something") + result = 1 + } catch { + case e: Exception => throw e + } finally { + println("finally") + result = (result - 1) / 2 + } + + result + } +} + + +case class MyException(message: String) extends RuntimeException(message) + +/** For this class, we test inlining for a case class error */ +object TestInlineHandlersCaseClassExceptionInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersCaseClassExceptionInline") + var result = -1 + + try { + if (nextInt % 2 == 0) + throw new MyException("something") + result = 1 + } catch { + case MyException(message) => println(message) + } + + result + } +} + + +/** For this class, inline should take place in the inner handler */ +object TestInlineHandlersNestedHandlerInnerInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersNestedHandlersInnerInline") + var result = -1 + + try { + try { + if (nextInt % 2 == 0) + throw new MyException("something") + result = 1 + } catch { + case MyException(message) => println(message) + } + } catch { + case e: IllegalArgumentException => println("IllegalArgumentException") + } + + result + } +} + + +/** For this class, inline should take place in the outer handler */ +object TestInlineHandlersNestedHandlerOuterInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersNestedHandlersOuterInline") + var result = -1 + + try { + try { + if (nextInt % 2 == 0) + throw new MyException("something") + result = 1 + } catch { + case e: IllegalArgumentException => println("IllegalArgumentException") + } + } catch { + case MyException(message) => println(message) + } + + result + } +} + + +/** For this class, inline should take place in the all handlers (inner, outer and finally) */ +object TestInlineHandlersNestedHandlerAllInline { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersNestedHandlersOuterInline") + var result = -1 + + try { + try { + if (nextInt % 2 == 0) + throw new MyException("something") + result = 1 + } catch { + case MyException(message) => + println(message) + throw MyException(message) + } + } catch { + case MyException(message) => + println(message) + throw MyException(message) + } finally { + println("finally") + result = (result - 1) / 2 + } + + result + } +} + + +/** This class is meant to test whether the inline handler is copied only once for multiple inlines */ +object TestInlineHandlersSingleCopy { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSingleCopy") + var result = -1 + + try { + + if (nextInt % 2 == 0) + throw new MyException("something") + + println("A side effect in the middle") + result = 3 // another one + + if (nextInt % 3 == 2) + throw new MyException("something else") + result = 1 + } catch { + case MyException(message) => + println(message) + } + + result + } +} + +/** This should test the special exception handler for synchronized blocks */ +object TestInlineHandlersSynchronized { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSynchronized") + var result = "hello" + + // any exception thrown here will be caught by a default handler that does MONTIOR_EXIT on result :) + result.synchronized { + throw MyException(result) + } + + result.length + } +} + +/** This should test the special exception handler for synchronized blocks with stack */ +object TestInlineHandlersSynchronizedWithStack { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSynchronizedWithStack") + var result = "hello" + + // any exception thrown here will be caught by a default handler that does MONTIOR_EXIT on result :) + result = "abc" + result.synchronized { + throw MyException(result) + } + + result.length + } +} + +/** This test should trigger a bug in the dead code elimination phase - it actually crashes ICodeCheckers +object TestInlineHandlersSynchronizedWithStackDoubleThrow { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersSynchronizedWithStackDoubleThrow") + var result = "a" + + // any exception thrown here will be caught by a default handler that does MONTIOR_EXIT on result :) + result += result.synchronized { throw MyException(result) } + result += result.synchronized { throw MyException(result) } + + result.length + } +} +*/ + +/** This test should check the preciseness of the inliner: it should not do any inlining here +* as it is not able to discern between the different exceptions +*/ +object TestInlineHandlersPreciseness { + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersCorrectHandler") + + try { + val exception: Throwable = + if (scala.util.Random.nextInt % 2 == 0) + new IllegalArgumentException("even") + else + new StackOverflowError("odd") + throw exception + } catch { + case e: IllegalArgumentException => + println("Correct, IllegalArgumentException") + case e: StackOverflowError => + println("Correct, StackOverflowException") + case t: Throwable => + println("WROOOONG, not Throwable!") + } + } +} + +/** This check should verify that the double no-local exception handler is duplicated correctly */ +object TestInlineHandlersDoubleNoLocal { + + val a1: String = "a" + val a2: String = "b" + + def main(args: Array[String]): Unit = { + println("TestInlineHandlersDoubleNoLocal") + + try { + a1.synchronized { + a2. synchronized { + throw new MyException("crash") + } + } + } catch { + case t: Throwable => println("Caught crash: " + t.toString) + } + + /* try { + val exception: Throwable = + if (scala.util.Random.nextInt % 2 == 0) + new IllegalArgumentException("even") + else + new StackOverflowError("odd") + throw exception + } catch { + case e: IllegalArgumentException => + println("Correct, IllegalArgumentException") + case e: StackOverflowError => + println("Correct, StackOverflowException") + case t: Throwable => + println("WROOOONG, not Throwable!") + }*/ + } +} diff --git a/test/pending/run/t5313.check b/test/pending/run/t5313.check new file mode 100644 index 0000000000..7a48b2b711 --- /dev/null +++ b/test/pending/run/t5313.check @@ -0,0 +1,12 @@ +STORE_LOCAL(variable kept1) +STORE_LOCAL(value result) +STORE_LOCAL(variable kept1) +STORE_LOCAL(variable kept2) +STORE_LOCAL(value kept3) +STORE_LOCAL(variable kept2) +STORE_LOCAL(variable kept4) +STORE_LOCAL(variable kept4) +STORE_LOCAL(variable kept5) +STORE_LOCAL(variable kept5) +STORE_LOCAL(variable kept6) +STORE_LOCAL(variable kept6) diff --git a/test/pending/run/t5313.scala b/test/pending/run/t5313.scala new file mode 100644 index 0000000000..4a5b076e6e --- /dev/null +++ b/test/pending/run/t5313.scala @@ -0,0 +1,54 @@ +import scala.tools.partest.IcodeComparison + +object Test extends IcodeComparison { + override def printIcodeAfterPhase = "dce" + + override def extraSettings: String = super.extraSettings + " -Yopt:l:classpath" + + override def code = + """class Foo { + def randomBoolean = scala.util.Random.nextInt % 2 == 0 + def bar = { + var kept1 = new Object + val result = new java.lang.ref.WeakReference(kept1) + kept1 = null // we can't eliminate this assignment because result can observe + // when the object has no more references. See SI-5313 + kept1 = new Object // but we can eliminate this one because kept1 has already been clobbered + var erased2 = null // we can eliminate this store because it's never used + val erased3 = erased2 // and this + var erased4 = erased2 // and this + val erased5 = erased4 // and this + var kept2: Object = new Object // ultimately can't be eliminated + while(randomBoolean) { + val kept3 = kept2 + kept2 = null // this can't, because it clobbers kept2, which is used + erased4 = null // safe to eliminate + println(kept3) + } + var kept4 = new Object // have to keep, it's used + try + println(kept4) + catch { + case _ : Throwable => kept4 = null // have to keep, it clobbers kept4 which is used + } + var kept5 = new Object + print(kept5) + kept5 = null // can't eliminate it's a clobber and it's used + print(kept5) + kept5 = null // can eliminate because we don't care about clobbers of nulls + while(randomBoolean) { + var kept6: AnyRef = null // not used, but have to keep because it clobbers the next used store + // on the back edge of the loop + kept6 = new Object // used + println(kept6) + } + result + } + }""".stripMargin + + override def show() { + val storeLocal = "STORE_LOCAL" + val lines1 = collectIcode() filter (_ contains storeLocal) map (x => x.drop(x.indexOf(storeLocal))) + println(lines1 mkString "\n") + } +} diff --git a/test/pending/run/t6955.scala b/test/pending/run/t6955.scala new file mode 100644 index 0000000000..787617eff1 --- /dev/null +++ b/test/pending/run/t6955.scala @@ -0,0 +1,33 @@ +import scala.tools.partest.IcodeComparison + +// this class should compile to code that uses switches (twice) +class Switches { + type Tag = Byte + + def switchBad(i: Tag): Int = i match { // notice type of i is Tag = Byte + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } + + // this worked before, should keep working + def switchOkay(i: Byte): Int = i match { + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } +} + +object Test extends IcodeComparison { + // ensure we get two switches out of this -- ignore the rest of the output for robustness + // exclude the constant we emit for the "SWITCH ..." string below (we get the icode for all the code you see in this file) + override def show() = { + val expected = 2 + val actual = (collectIcode() filter { + x => x.indexOf("SWITCH ...") >= 0 && x.indexOf("CONSTANT(") == -1 + }).size + assert(actual == expected, s"switches expected: $expected, actual: $actual") + } +} diff --git a/test/pending/run/t6956.scala b/test/pending/run/t6956.scala new file mode 100644 index 0000000000..57d721807d --- /dev/null +++ b/test/pending/run/t6956.scala @@ -0,0 +1,31 @@ +import scala.tools.partest.IcodeComparison + +class Switches { + private[this] final val ONE = 1 + + def switchBad(i: Byte): Int = i match { + case ONE => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } + + def switchOkay(i: Byte): Int = i match { + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } +} + +object Test extends IcodeComparison { + // ensure we get two switches out of this -- ignore the rest of the output for robustness + // exclude the constant we emit for the "SWITCH ..." string below (we get the icode for all the code you see in this file) + override def show() = { + val expected = 2 + val actual = (collectIcode() filter { + x => x.indexOf("SWITCH ...") >= 0 && x.indexOf("CONSTANT(") == -1 + }).size + assert(actual == expected, s"switches expected: $expected, actual: $actual") + } +} diff --git a/test/pending/run/test-cpp.check b/test/pending/run/test-cpp.check new file mode 100644 index 0000000000..ff4c9bf2bf --- /dev/null +++ b/test/pending/run/test-cpp.check @@ -0,0 +1,81 @@ +--- a ++++ b +@@ -54,3 +54,3 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, value x, value y ++ locals: value args + startBlock: 1 +@@ -59,10 +59,6 @@ + 1: +- 52 CONSTANT(2) +- 52 STORE_LOCAL(value x) + 52 SCOPE_ENTER value x +- 53 LOAD_LOCAL(value x) +- 53 STORE_LOCAL(value y) + 53 SCOPE_ENTER value y + 54 LOAD_MODULE object Predef +- 54 LOAD_LOCAL(value y) ++ 54 CONSTANT(2) + 54 BOX INT +@@ -109,3 +105,3 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, value x, value y ++ locals: value args, value x + startBlock: 1 +@@ -118,7 +114,5 @@ + 81 SCOPE_ENTER value x +- 82 LOAD_LOCAL(value x) +- 82 STORE_LOCAL(value y) + 82 SCOPE_ENTER value y + 83 LOAD_MODULE object Predef +- 83 LOAD_LOCAL(value y) ++ 83 LOAD_LOCAL(value x) + 83 BOX INT +@@ -152,3 +146,3 @@ + def main(args: Array[String] (ARRAY[REF(class String)])): Unit { +- locals: value args, value x, value y ++ locals: value args + startBlock: 1 +@@ -157,10 +151,6 @@ + 1: +- 66 THIS(TestAliasChainDerefThis) +- 66 STORE_LOCAL(value x) + 66 SCOPE_ENTER value x +- 67 LOAD_LOCAL(value x) +- 67 STORE_LOCAL(value y) + 67 SCOPE_ENTER value y + 68 LOAD_MODULE object Predef +- 68 LOAD_LOCAL(value y) ++ 68 THIS(Object) + 68 CALL_METHOD scala.Predef.println (dynamic) +@@ -193,3 +183,3 @@ + def test(x: Int (INT)): Unit { +- locals: value x, value y ++ locals: value x + startBlock: 1 +@@ -198,7 +188,5 @@ + 1: +- 29 LOAD_LOCAL(value x) +- 29 STORE_LOCAL(value y) + 29 SCOPE_ENTER value y + 30 LOAD_MODULE object Predef +- 30 LOAD_LOCAL(value y) ++ 30 LOAD_LOCAL(value x) + 30 BOX INT +@@ -240,7 +228,5 @@ + 96 SCOPE_ENTER variable x +- 97 LOAD_LOCAL(variable x) +- 97 STORE_LOCAL(variable y) + 97 SCOPE_ENTER variable y + 98 LOAD_MODULE object Predef +- 98 LOAD_LOCAL(variable y) ++ 98 LOAD_LOCAL(variable x) + 98 BOX INT +@@ -250,6 +236,4 @@ + 100 STORE_LOCAL(variable y) +- 101 LOAD_LOCAL(variable y) +- 101 STORE_LOCAL(variable x) + 102 LOAD_MODULE object Predef +- 102 LOAD_LOCAL(variable x) ++ 102 LOAD_LOCAL(variable y) + 102 BOX INT diff --git a/test/pending/run/test-cpp.scala b/test/pending/run/test-cpp.scala new file mode 100644 index 0000000000..4fca67d51e --- /dev/null +++ b/test/pending/run/test-cpp.scala @@ -0,0 +1,104 @@ +/** + * The only change is in the decision to replace a LOAD_LOCAL(l) + * in the copy-propagation performed before ClosureElimination. + * + * In the general case, the local variable 'l' is connected through + * an alias chain with other local variables and at the end of the + * alias chain there may be a Value, call it 'v'. + * + * If 'v' is cheaper to access (it is a Deref(This) or Const(_)), then + * replace the instruction to load it from the cheaper place. + * Otherwise, we use the local variable at the end of the alias chain + * instead of 'l'. + */ + +import scala.tools.partest.IcodeComparison + +object Test extends IcodeComparison { + override def printIcodeAfterPhase = "dce" +} + +import scala.util.Random._ + +/** + * The example in the bug report (Issue-5321): an alias chain which store + * an Unknown. Should remove local variable 'y'. + */ +object TestBugReport { + def test(x: Int) = { + val y = x + println(y) + } +} + +/** + * The code taken from scala.tools.nsc.settings.Settings: + * After inlining of the setter is performed, there is an opportunity for + * copy-propagation to eliminate some local variables. + */ +object TestSetterInline { + private var _postSetHook: this.type => Unit = (x: this.type) => () + def withPostSetHook(f: this.type => Unit): this.type = { _postSetHook = f ; this } +} + + +/** + * The access of the local variable 'y' should be replaced by the + * constant. + */ +object TestAliasChainConstant { + + def main(args: Array[String]): Unit = { + val x = 2 + val y = x + println(y) + } +} + +/** + * At the end of the alias chain we have a reference to 'this'. + * The local variables should be all discarded and replace by a + * direct reference to this + */ +class TestAliasChainDerefThis { + + def main(args: Array[String]): Unit = { + val x = this + val y = x + println(y) + } +} + +/** + * At the end of the alias chain, there is the value of a field. + * The use of variable 'y' should be replaced by 'x', not by an access + * to the field 'f' since it is more costly. + */ +object TestAliasChainDerefField { + def f = nextInt + + def main(args: Array[String]): Unit = { + val x = f + val y = x + println(y) + } +} + + +/** + * The first time 'println' is called, 'x' is replaced by 'y' + * and the second time, 'y' is replaced by 'x'. But none of them + * can be removed. + */ +object TestDifferentBindings { + + def main(args: Array[String]): Unit = { + var x = nextInt + var y = x + println(y) + + y = nextInt + x = y + println(x) + } +} |