diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-10-20 10:31:54 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-10-20 11:55:09 +0200 |
commit | 19ee72193b6d3d4b1dc1e3bba430d3d741db97e3 (patch) | |
tree | 05ab5562fab71f9e04c926574cdfd6fcc373dd1d /test/junit/scala/tools/nsc/backend/jvm/opt | |
parent | 0a33c421767f6e4587f8adac19169f184d845548 (diff) | |
download | scala-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.scala | 40 |
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)) } /** |