summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
index 009742501e..79e74f3eb7 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
@@ -7,14 +7,14 @@ package scala.tools.nsc
package backend.jvm
package opt
-import scala.tools.asm.tree.MethodNode
-import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.collection.JavaConverters._
+import scala.tools.asm.Opcodes
+import scala.tools.asm.tree.{MethodInsnNode, MethodNode}
+import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.tools.nsc.backend.jvm.BackendReporting.OptimizerWarning
class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
import bTypes._
- import inliner._
import callGraph._
case class InlineRequest(callsite: Callsite, post: List[InlineRequest], reason: String) {
@@ -93,7 +93,27 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
val callee = callsite.callee.get
def requestIfCanInline(callsite: Callsite, reason: String): Either[OptimizerWarning, InlineRequest] = inliner.earlyCanInlineCheck(callsite) match {
case Some(w) => Left(w)
- case None => Right(InlineRequest(callsite, Nil, reason))
+ case None =>
+ val callee = callsite.callee.get
+ val postInlineRequest: List[InlineRequest] = callee.calleeDeclarationClass.isInterface match {
+ case Right(true) =>
+ // Treat the pair of trait interface method and static method as one for the purposes of inlining:
+ // if we inline invokeinterface, invoke the invokestatic, too.
+ val calls = callee.callee.instructions.iterator().asScala.filter(BytecodeUtils.isCall).take(2).toList
+ calls match {
+ case List(x: MethodInsnNode) if x.getOpcode == Opcodes.INVOKESTATIC && x.name == (callee.callee.name + "$") =>
+ callGraph.addIfMissing(callee.callee, callee.calleeDeclarationClass)
+ val maybeNodeToCallsite1 = callGraph.findCallSite(callee.callee, x)
+ maybeNodeToCallsite1.toList.flatMap(x => requestIfCanInline(x, reason).right.toOption)
+ case _ =>
+ Nil
+
+ }
+ case _ => Nil
+ }
+
+ Right(InlineRequest(callsite, postInlineRequest, reason))
+
}
compilerSettings.YoptInlineHeuristics.value match {