summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/opt
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-10-20 10:31:54 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-10-20 11:55:09 +0200
commit19ee72193b6d3d4b1dc1e3bba430d3d741db97e3 (patch)
tree05ab5562fab71f9e04c926574cdfd6fcc373dd1d /test/junit/scala/tools/nsc/backend/jvm/opt
parent0a33c421767f6e4587f8adac19169f184d845548 (diff)
downloadscala-19ee72193b6d3d4b1dc1e3bba430d3d741db97e3.tar.gz
scala-19ee72193b6d3d4b1dc1e3bba430d3d741db97e3.tar.bz2
scala-19ee72193b6d3d4b1dc1e3bba430d3d741db97e3.zip
Correctly handle post-inline requests of non-existing callsites
A post-inline request is allowed to refer to a callsite that does not exist anymore because it was alredy inlined while handling some other inline request, or because it was DCE'd.
Diffstat (limited to 'test/junit/scala/tools/nsc/backend/jvm/opt')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala40
1 files changed, 36 insertions, 4 deletions
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 cdba4073f2..37cd9431dc 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -1007,21 +1007,53 @@ class InlinerTest extends ClearAfterClass {
| final def f = 10
| final def g = f + 19
| final def h = g + 29
+ | final def i = h + 39
|}
""".stripMargin
val List(c) = compile(code)
val hMeth = findAsmMethod(c, "h")
val gMeth = findAsmMethod(c, "g")
- val gCall = getCallsite(hMeth, "g")
+ val iMeth = findAsmMethod(c, "i")
val fCall = getCallsite(gMeth, "f")
+ val gCall = getCallsite(hMeth, "g")
+ val hCall = getCallsite(iMeth, "h")
val warning = inliner.canInlineBody(gCall)
assert(warning.isEmpty, warning)
- inliner.inline(InlineRequest(gCall, List(InlineRequest(fCall, Nil))))
- assertNoInvoke(getSingleMethod(c, "h")) // no invoke in h: first g is inlined, then the inlined call to f is also inlined
- assertInvoke(getSingleMethod(c, "g"), "C", "f") // g itself still has the call to f
+ inliner.inline(InlineRequest(hCall,
+ post = List(InlineRequest(gCall,
+ post = List(InlineRequest(fCall, Nil))))))
+ assertNoInvoke(convertMethod(iMeth)) // no invoke in i: first h is inlined, then the inlined call to g is also inlined, etc for f
+ assertInvoke(convertMethod(gMeth), "C", "f") // g itself still has the call to f
+ }
+
+ @Test
+ def postRequestSkipAlreadyInlined(): Unit = {
+ val code =
+ """class C {
+ | final def a = 10
+ | final def b = a + 20
+ | final def c = b + 30
+ | final def d = c + 40
+ |}
+ """.stripMargin
+
+ val List(cl) = compile(code)
+ val List(b, c, d) = List("b", "c", "d").map(findAsmMethod(cl, _))
+ val aCall = getCallsite(b, "a")
+ val bCall = getCallsite(c, "b")
+ val cCall = getCallsite(d, "c")
+
+ inliner.inline(InlineRequest(bCall, Nil))
+
+ val req = InlineRequest(cCall,
+ List(InlineRequest(bCall,
+ List(InlineRequest(aCall, Nil)))))
+ inliner.inline(req)
+
+ assertNoInvoke(convertMethod(d))
}
/**