diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-06 20:12:53 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-07 14:33:54 +0200 |
commit | e9c742e1d27c41ee8646ea20dfb59efbc3d94ef3 (patch) | |
tree | 32ce64bba9d2c2efef5799c5312825e5dbeff08b /test | |
parent | 4e9be26c1d0ea4818b54c1f882a2972f439b6e39 (diff) | |
download | scala-e9c742e1d27c41ee8646ea20dfb59efbc3d94ef3.tar.gz scala-e9c742e1d27c41ee8646ea20dfb59efbc3d94ef3.tar.bz2 scala-e9c742e1d27c41ee8646ea20dfb59efbc3d94ef3.zip |
Accessibility checks for methods with an InvokeDynamic instruction
Implements the necessary tests to check if a method with an
InvokeDynamic instruction can be inlined into a destination class.
Only InvokeDynamic instructions with LambdaMetaFactory as bootstrap
methods can be inlined. The accessibility checks cannot be implemented
generically, because it depends on what the bootstrap method is doing.
In particular, the bootstrap method receives a Lookup object as
argument which can be used to access private methods of the class
where the InvokeDynamic method is located.
A comment in the inliner explains the details.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/presentation/t7678/Runner.scala | 3 | ||||
-rw-r--r-- | test/files/run/t8029.scala | 3 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala | 37 |
3 files changed, 37 insertions, 6 deletions
diff --git a/test/files/presentation/t7678/Runner.scala b/test/files/presentation/t7678/Runner.scala index e45f057ff1..14d6dc2a70 100644 --- a/test/files/presentation/t7678/Runner.scala +++ b/test/files/presentation/t7678/Runner.scala @@ -1,6 +1,3 @@ -/* - * filter: inliner warnings; re-run with - */ import scala.tools.nsc.interactive.tests._ import scala.reflect.internal.util._ diff --git a/test/files/run/t8029.scala b/test/files/run/t8029.scala index 62629d51bc..dbd5c41387 100644 --- a/test/files/run/t8029.scala +++ b/test/files/run/t8029.scala @@ -1,6 +1,3 @@ -/* - * filter: inliner warning; re-run with - */ import scala.tools.partest._ import scala.tools.nsc._ 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 0309bb97cc..617eced560 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -991,4 +991,41 @@ class InlinerTest extends ClearAfterClass { assert(2 == t.collect({case Ldc(_, "hai!") => }).size) // twice the body of f assert(1 == t.collect({case Jump(IFNONNULL, _) => }).size) // one single null check } + + @Test + def inlineIndyLambda(): Unit = { + val code = + """object M { + | @inline def m(s: String) = { + | val f = (x: String) => x.trim + | f(s) + | } + |} + |class C { + | @inline final def m(s: String) = { + | val f = (x: String) => x.trim + | f(s) + | } + | def t1 = m("foo") + | def t2 = M.m("bar") + |} + """.stripMargin + + val List(c, _, _) = compile(code) + + val t1 = getSingleMethod(c, "t1") + assert(t1.instructions exists { + case _: InvokeDynamic => true + case _ => false + }) + // the indy call is inlined into t, and the closure elimination rewrites the closure invocation to the body method + assertInvoke(t1, "C", "C$$$anonfun$2") + + val t2 = getSingleMethod(c, "t2") + assert(t2.instructions exists { + case _: InvokeDynamic => true + case _ => false + }) + assertInvoke(t2, "M$", "M$$$anonfun$1") + } } |