diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-08-26 17:15:18 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-09-17 20:16:14 +0200 |
commit | 89c0a7f0a320e898f360c7c94b1ad0bbce681b3a (patch) | |
tree | 6b3e9196b6562be22d236214a6bebb5a4d99e174 /test | |
parent | da8f263208f8934650d3900793a4115ff1751310 (diff) | |
download | scala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.tar.gz scala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.tar.bz2 scala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.zip |
Store information about function literals in call graph
Remember in the call graph if a function literal is passed as an
argument to a higher-order function.
Diffstat (limited to 'test')
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala | 66 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala | 2 |
2 files changed, 59 insertions, 9 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala index 715db3f8c2..b518cbdc50 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala @@ -6,6 +6,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.junit.Test import scala.collection.generic.Clearable +import scala.collection.immutable.IntMap import scala.tools.asm.Opcodes._ import org.junit.Assert._ @@ -21,18 +22,31 @@ import AsmUtils._ import BackendReporting._ import scala.collection.convert.decorateAsScala._ +import scala.tools.testing.ClearAfterClass -@RunWith(classOf[JUnit4]) -class CallGraphTest { - val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:inline-global -Yopt-warnings") - import compiler.genBCode.bTypes._ +object CallGraphTest extends ClearAfterClass.Clearable { + var compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:inline-global -Yopt-warnings") + def clear(): Unit = { compiler = null } // allows inspecting the caches after a compilation run - val notPerRun: List[Clearable] = List(classBTypeFromInternalName, byteCodeRepository.compilingClasses, byteCodeRepository.parsedClasses, callGraph.callsites) + val notPerRun: List[Clearable] = List( + compiler.genBCode.bTypes.classBTypeFromInternalName, + compiler.genBCode.bTypes.byteCodeRepository.compilingClasses, + compiler.genBCode.bTypes.byteCodeRepository.parsedClasses, + compiler.genBCode.bTypes.callGraph.callsites) notPerRun foreach compiler.perRunCaches.unrecordCache +} + +@RunWith(classOf[JUnit4]) +class CallGraphTest extends ClearAfterClass { + ClearAfterClass.stateToClear = CallGraphTest - def compile(code: String, allowMessage: StoreReporter#Info => Boolean): List[ClassNode] = { - notPerRun.foreach(_.clear()) + val compiler = CallGraphTest.compiler + import compiler.genBCode.bTypes._ + import callGraph._ + + def compile(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = { + CallGraphTest.notPerRun.foreach(_.clear()) compileClasses(compiler)(code, allowMessage = allowMessage) } @@ -107,7 +121,7 @@ class CallGraphTest { assert(callee.annotatedInline == atInline) assert(callee.annotatedNoInline == atNoInline) - assert(callsite.argInfos == List()) // not defined yet + assert(callsite.argInfos == IntMap.empty) // no higher-order methods } catch { case e: Throwable => println(callsite); throw e } @@ -135,4 +149,40 @@ class CallGraphTest { checkCallsite(df7Call, t2, cf7, cClassBType, false, true, true) checkCallsite(dg1Call, t2, g1, cMClassBType, true, false, false) } + + /** + * NOTE: if this test fails for you when running within the IDE, it's probably because you're + * using 2.12.0-M2 for compilining within the IDE, which doesn't add SAM information to the + * InlineInfo attribute. So the InlineInfo in the classfile for Function1 doesn't say that + * it's a SAM type. The test passes when running with ant (which does a full bootstrap). + */ + @Test + def checkArgInfos(): Unit = { + val code = + """abstract class C { + | def h(f: Int => Int): Int = f(1) + | def t1 = h(x => x + 1) + | def t2(i: Int, f: Int => Int, z: Int) = h(f) + i - z + | def t3(f: Int => Int) = h(x => f(x + 1)) + |} + |abstract class D { + | def iAmASam(x: Int): Int + | def selfSamCall = iAmASam(10) + |} + |""".stripMargin + val List(c, d) = compile(code) + + def callIn(m: String) = callGraph.callsites.find(_._1.name == m).get._2.values.head + val t1h = callIn("t1") + assertEquals(t1h.argInfos.toList, List((1, FunctionLiteral))) + + val t2h = callIn("t2") + assertEquals(t2h.argInfos.toList, List((1, ForwardedParam(2)))) + + val t3h = callIn("t3") + assertEquals(t3h.argInfos.toList, List((1, FunctionLiteral))) + + val selfSamCall = callIn("selfSamCall") + assertEquals(selfSamCall.argInfos.toList, List((0,ForwardedParam(0)))) + } } 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 135ebe9a78..6dfdf20587 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -97,7 +97,7 @@ class InlinerTest extends ClearAfterClass { callsiteMethod = callsiteMethod, callsiteClass = callsiteClass, callee = Right(callGraph.Callee(callee = callee, calleeDeclarationClass = calleeDeclarationClass, safeToInline = true, safeToRewrite = false, annotatedInline = false, annotatedNoInline = false, higherOrderParams = IntMap.empty, calleeInfoWarning = None)), - argInfos = Nil, + argInfos = IntMap.empty, callsiteStackHeight = callsiteStackHeight, receiverKnownNotNull = receiverKnownNotNull, callsitePosition = NoPosition), |