diff options
author | Paul Phillips <paulp@improving.org> | 2011-08-22 19:49:46 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-08-22 19:49:46 +0000 |
commit | 80952759fbaaf3a99f6bc0ca528da726b5a438e7 (patch) | |
tree | 6a81273c34bc51830ce60a7b4d65aa6111a8ef51 /test/files/run | |
parent | 4b29535009d7848d870252b5b08f53844544de64 (diff) | |
download | scala-80952759fbaaf3a99f6bc0ca528da726b5a438e7.tar.gz scala-80952759fbaaf3a99f6bc0ca528da726b5a438e7.tar.bz2 scala-80952759fbaaf3a99f6bc0ca528da726b5a438e7.zip |
Created infrastructure for testing icode + sett...
Created infrastructure for testing icode + settings/partest yak shaving.
See enclosed test files/run/inline-ex-handlers.scala. To compare
optimized and unoptimized icode after a given phase, all you need in a
partest source file is this:
import scala.tools.partest.IcodeTest
object Test extends IcodeTest {
override def printIcodeAfterPhase = "inlineExceptionHandlers"
}
Other things can be done, see IcodeTest.scala. Review by ureche.
Diffstat (limited to 'test/files/run')
-rw-r--r-- | test/files/run/inline-ex-handlers.check | 314 | ||||
-rw-r--r-- | test/files/run/inline-ex-handlers.scala | 329 |
2 files changed, 643 insertions, 0 deletions
diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check new file mode 100644 index 0000000000..29daca3471 --- /dev/null +++ b/test/files/run/inline-ex-handlers.check @@ -0,0 +1,314 @@ +268c268 +< locals: value x$1, value temp1 +--- +> locals: value x$1, value temp1, variable boxed1 +270c270 +< blocks: [1,2,3,4] +--- +> blocks: [1,2,3] +283,285d282 +< 92 JUMP 4 +< +< 4: +291a289,290 +> 92 STORE_LOCAL(variable boxed1) +> 92 LOAD_LOCAL(variable boxed1) +372c371 +< blocks: [1,2,3,4,5,7,8,10] +--- +> blocks: [1,2,3,4,5,7,8,10,11] +396c395,404 +< 103 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$1) +> ? JUMP 11 +> +> 11: +> 101 LOAD_LOCAL(value ex$1) +> 101 STORE_LOCAL(value temp2) +> 101 SCOPE_ENTER value temp2 +> 101 LOAD_LOCAL(value temp2) +> 101 IS_INSTANCE REF(class MyException) +> 101 CZJUMP (BOOL)NE ? 4 : 5 +487c495 +< blocks: [1,2,3,4,6,7,8,9,10] +--- +> blocks: [1,2,3,4,6,7,8,9,10,11,12,13] +516c524,529 +< 306 THROW(MyException) +--- +> ? JUMP 11 +> +> 11: +> ? LOAD_LOCAL(variable monitor4) +> 305 MONITOR_EXIT +> ? JUMP 12 +522c535,541 +< ? THROW(Throwable) +--- +> ? JUMP 12 +> +> 12: +> ? LOAD_LOCAL(variable monitor3) +> 304 MONITOR_EXIT +> ? STORE_LOCAL(value t) +> ? JUMP 13 +528c547,560 +< ? THROW(Throwable) +--- +> ? STORE_LOCAL(value t) +> ? JUMP 13 +> +> 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) +> 310 JUMP 2 +552c584 +< catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 +--- +> catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 +555c587 +< catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3 +--- +> catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3 +587c619 +< blocks: [1,2,3,4,5,6,7,9,10] +--- +> blocks: [1,2,3,4,5,6,7,9,10,11,12] +611c643,649 +< 78 THROW(IllegalArgumentException) +--- +> ? STORE_LOCAL(value e) +> ? JUMP 11 +> +> 11: +> 81 LOAD_LOCAL(value e) +> ? STORE_LOCAL(variable exc1) +> ? JUMP 12 +640c678,692 +< 81 THROW(Exception) +--- +> ? STORE_LOCAL(variable exc1) +> ? JUMP 12 +> +> 12: +> 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) +662c714 +< catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3 +--- +> catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3 +688c740 +< blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19] +--- +> blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19,20,21,22] +712c764,773 +< 172 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$4) +> ? JUMP 20 +> +> 20: +> 170 LOAD_LOCAL(value ex$4) +> 170 STORE_LOCAL(value temp11) +> 170 SCOPE_ENTER value temp11 +> 170 LOAD_LOCAL(value temp11) +> 170 IS_INSTANCE REF(class MyException) +> 170 CZJUMP (BOOL)NE ? 12 : 13 +766c827,828 +< 177 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$5) +> ? JUMP 21 +770c832,841 +< 170 THROW(Throwable) +--- +> ? STORE_LOCAL(value ex$5) +> ? JUMP 21 +> +> 21: +> 169 LOAD_LOCAL(value ex$5) +> 169 STORE_LOCAL(value temp14) +> 169 SCOPE_ENTER value temp14 +> 169 LOAD_LOCAL(value temp14) +> 169 IS_INSTANCE REF(class MyException) +> 169 CZJUMP (BOOL)NE ? 5 : 6 +801c872,873 +< 182 THROW(MyException) +--- +> ? STORE_LOCAL(variable exc2) +> ? JUMP 22 +805c877,891 +< 169 THROW(Throwable) +--- +> ? STORE_LOCAL(variable exc2) +> ? JUMP 22 +> +> 22: +> 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) +827c913 +< catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18) starting at: 4 +--- +> catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18, 20) starting at: 4 +830c916 +< catch (<none>) in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18) starting at: 3 +--- +> catch (<none>) in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18, 20, 21) starting at: 3 +856c942 +< blocks: [1,2,3,6,7,8,10,11,13] +--- +> blocks: [1,2,3,6,7,8,10,11,13,14] +880c966,975 +< 124 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$2) +> ? JUMP 14 +> +> 14: +> 122 LOAD_LOCAL(value ex$2) +> 122 STORE_LOCAL(value temp5) +> 122 SCOPE_ENTER value temp5 +> 122 LOAD_LOCAL(value temp5) +> 122 IS_INSTANCE REF(class MyException) +> 122 CZJUMP (BOOL)NE ? 7 : 8 +928c1023 +< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13) starting at: 3 +--- +> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13, 14) starting at: 3 +954c1049 +< blocks: [1,2,3,4,5,9,10,11,13] +--- +> blocks: [1,2,3,4,5,9,10,11,13,14] +978c1073,1082 +< 148 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$3) +> ? JUMP 14 +> +> 14: +> 145 LOAD_LOCAL(value ex$3) +> 145 STORE_LOCAL(value temp8) +> 145 SCOPE_ENTER value temp8 +> 145 LOAD_LOCAL(value temp8) +> 145 IS_INSTANCE REF(class MyException) +> 145 CZJUMP (BOOL)NE ? 4 : 5 +1222c1326 +< blocks: [1,2,3,4,5,7] +--- +> blocks: [1,2,3,4,5,7,8] +1246c1350,1357 +< 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 +1295c1406 +< blocks: [1,2,3,4,5,7,8,10,11,13] +--- +> blocks: [1,2,3,4,5,7,8,10,11,13,14] +1319c1430,1431 +< 203 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$6) +> ? JUMP 14 +1339c1451,1460 +< 209 THROW(MyException) +--- +> ? STORE_LOCAL(value ex$6) +> ? JUMP 14 +> +> 14: +> 200 LOAD_LOCAL(value ex$6) +> 200 STORE_LOCAL(value temp17) +> 200 SCOPE_ENTER value temp17 +> 200 LOAD_LOCAL(value temp17) +> 200 IS_INSTANCE REF(class MyException) +> 200 CZJUMP (BOOL)NE ? 4 : 5 +1402c1523 +< blocks: [1,2,3,4,5,7] +--- +> blocks: [1,2,3,4,5,7,8] +1426c1547,1554 +< 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 +1475c1603 +< blocks: [1,2,3,4] +--- +> blocks: [1,2,3,4,5] +1495c1623,1628 +< 229 THROW(MyException) +--- +> ? JUMP 5 +> +> 5: +> ? LOAD_LOCAL(variable monitor1) +> 228 MONITOR_EXIT +> 228 THROW(Throwable) +1501c1634 +< ? THROW(Throwable) +--- +> 228 THROW(Throwable) +1529c1662 +< locals: value args, variable result, variable monitor2, variable monitorResult1 +--- +> locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 +1531c1664 +< blocks: [1,2,3,4] +--- +> blocks: [1,2,3,4,5] +1554c1687,1695 +< 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) +1560c1701 +< ? THROW(Throwable) +--- +> 244 THROW(Throwable) + diff --git a/test/files/run/inline-ex-handlers.scala b/test/files/run/inline-ex-handlers.scala new file mode 100644 index 0000000000..a96b938e13 --- /dev/null +++ b/test/files/run/inline-ex-handlers.scala @@ -0,0 +1,329 @@ +import scala.tools.partest.IcodeTest + +object Test extends IcodeTest { + override def printIcodeAfterPhase = "inlineExceptionHandlers" +} + +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!") + }*/ + } +} |