diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-09-17 20:18:01 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-09-17 22:05:04 +0200 |
commit | a477c40f13644dbd596126c238dbdc262639b002 (patch) | |
tree | fedf3ec8aba6abe021b62a129a8b6ed684e579a0 | |
parent | fef4b3dd5c330f1c2f18604e231ef7c45ac14d70 (diff) | |
download | scala-a477c40f13644dbd596126c238dbdc262639b002.tar.gz scala-a477c40f13644dbd596126c238dbdc262639b002.tar.bz2 scala-a477c40f13644dbd596126c238dbdc262639b002.zip |
In the call graph, rename higherOrderParams to samParamTypes
Because that's what the field holds: the parameter types that are SAM
types.
5 files changed, 42 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 7a0b41a49a..6442b81721 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -124,7 +124,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { (declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)] declarationClassBType = classBTypeFromClassNode(declarationClassNode) } yield { - val CallsiteInfo(safeToInline, safeToRewrite, annotatedInline, annotatedNoInline, higherOrderParams, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source) + val CallsiteInfo(safeToInline, safeToRewrite, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source) Callee( callee = method, calleeDeclarationClass = declarationClassBType, @@ -132,7 +132,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { safeToRewrite = safeToRewrite, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, - higherOrderParams = higherOrderParams, + samParamTypes = samParamTypes, calleeInfoWarning = warning) } @@ -173,7 +173,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { methodProdCons: => Option[ProdConsAnalyzer] = None): IntMap[ArgInfo] = { if (callee.isLeft) IntMap.empty else { - if (callee.get.higherOrderParams.nonEmpty) { + if (callee.get.samParamTypes.nonEmpty) { val prodCons = methodProdCons.getOrElse({ localOpt.minimalRemoveUnreachableCode(callsiteMethod, callsiteClass.internalName) @@ -192,7 +192,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { val numArgs = Type.getArgumentTypes(callsiteInsn.desc).length + (if (callsiteInsn.getOpcode == Opcodes.INVOKESTATIC) 0 else 1) callFrame.stackTop - numArgs + 1 } - callee.get.higherOrderParams flatMap { + callee.get.samParamTypes flatMap { case (index, paramType) => val prods = prodCons.initialProducersForValueAt(callsiteInsn, receiverOrFirstArgSlot + index) if (prods.size != 1) None @@ -211,12 +211,39 @@ class CallGraph[BT <: BTypes](val btypes: BT) { } } + def samParamTypes(methodNode: MethodNode, receiverType: ClassBType): IntMap[ClassBType] = { + val paramTypes = { + val params = Type.getMethodType(methodNode.desc).getArgumentTypes.map(t => bTypeForDescriptorOrInternalNameFromClassfile(t.getDescriptor)) + val isStatic = BytecodeUtils.isStaticMethod(methodNode) + if (isStatic) params else receiverType +: params + } + samTypes(paramTypes) + } + + def capturedSamTypes(lmf: LambdaMetaFactoryCall): IntMap[ClassBType] = { + val capturedTypes = Type.getArgumentTypes(lmf.indy.desc).map(t => bTypeForDescriptorOrInternalNameFromClassfile(t.getDescriptor)) + samTypes(capturedTypes) + } + + private def samTypes(types: Array[BType]): IntMap[ClassBType] = { + var res = IntMap.empty[ClassBType] + for (i <- types.indices) { + types(i) match { + case c: ClassBType => + if (c.info.get.inlineInfo.sam.isDefined) res = res.updated(i, c) + + case _ => + } + } + res + } + /** * Just a named tuple used as return type of `analyzeCallsite`. */ private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, - higherOrderParams: IntMap[ClassBType], + samParamTypes: IntMap[ClassBType], warning: Option[CalleeInfoWarning]) /** @@ -277,7 +304,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2) annotatedInline = methodInlineInfo.annotatedInline, annotatedNoInline = methodInlineInfo.annotatedNoInline, - higherOrderParams = inlinerHeuristics.higherOrderParams(calleeMethodNode, receiverType), + samParamTypes = samParamTypes(calleeMethodNode, receiverType), warning = warning) case None => @@ -337,14 +364,14 @@ class CallGraph[BT <: BTypes](val btypes: BT) { * that can be safely re-written to the static implementation method. * @param annotatedInline True if the callee is annotated @inline * @param annotatedNoInline True if the callee is annotated @noinline - * @param higherOrderParams A map from parameter positions to SAM parameter types + * @param samParamTypes A map from parameter positions to SAM parameter types * @param calleeInfoWarning An inliner warning if some information was not available while * gathering the information about this callee. */ final case class Callee(callee: MethodNode, calleeDeclarationClass: ClassBType, safeToInline: Boolean, safeToRewrite: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, - higherOrderParams: IntMap[ClassBType], + samParamTypes: IntMap[ClassBType], calleeInfoWarning: Option[CalleeInfoWarning]) { assert(!(safeToInline && safeToRewrite), s"A callee of ${callee.name} can be either safeToInline or safeToRewrite, but not both.") override def toString = s"Callee($calleeDeclarationClass.${callee.name})" diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index a509bed5c5..f211c00c80 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -246,7 +246,7 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { safeToRewrite = false, // the lambda body method is not a trait interface method annotatedInline = false, annotatedNoInline = false, - inlinerHeuristics.higherOrderParams(bodyMethodNode, bodyDeclClassType), + samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType), calleeInfoWarning = None) }) val bodyMethodCallsite = Callsite( diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 144a899c03..1b017bb0da 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -112,7 +112,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { */ def rewriteFinalTraitMethodInvocation(callsite: Callsite): Unit = { if (doRewriteTraitCallsite(callsite)) { - val Right(Callee(callee, calleeDeclarationClass, _, _, annotatedInline, annotatedNoInline, higherOrderParams, infoWarning)) = callsite.callee + val Right(Callee(callee, calleeDeclarationClass, _, _, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee val traitMethodArgumentTypes = asm.Type.getArgumentTypes(callee.desc) @@ -159,9 +159,9 @@ class Inliner[BT <: BTypes](val btypes: BT) { callsite.callsiteMethod.instructions.remove(callsite.callsiteInstruction) callGraph.removeCallsite(callsite.callsiteInstruction, callsite.callsiteMethod) - val staticCallHigherOrderParams = { - if (selfParamType.info.get.inlineInfo.sam.isEmpty) higherOrderParams - 0 - else higherOrderParams.updated(0, selfParamType) + val staticCallSamParamTypes = { + if (selfParamType.info.get.inlineInfo.sam.isEmpty) samParamTypes - 0 + else samParamTypes.updated(0, selfParamType) } val staticCallsite = Callsite( callsiteInstruction = newCallsiteInstruction, @@ -174,7 +174,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { safeToRewrite = false, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, - higherOrderParams = staticCallHigherOrderParams, + samParamTypes = staticCallSamParamTypes, calleeInfoWarning = infoWarning)), argInfos = callsite.argInfos, callsiteStackHeight = callsite.callsiteStackHeight, 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 7cfc797317..cd10094204 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala @@ -67,24 +67,6 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { }).filterNot(_._2.isEmpty).toMap } - def higherOrderParams(methodNode: MethodNode, receiverType: ClassBType): IntMap[ClassBType] = { - var res = IntMap.empty[ClassBType] - val paramTypes = { - val params = Type.getMethodType(methodNode.desc).getArgumentTypes.map(t => bTypeForDescriptorOrInternalNameFromClassfile(t.getDescriptor)) - val isStatic = BytecodeUtils.isStaticMethod(methodNode) - if (isStatic) params else receiverType +: params - } - for (i <- paramTypes.indices) { - paramTypes(i) match { - case c: ClassBType => - if (c.info.get.inlineInfo.sam.isDefined) res = res.updated(i, c) - - case _ => - } - } - res - } - /** * Returns the inline request for a callsite if the callsite should be inlined according to the * current heuristics (`-Yopt-inline-heuristics`). 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 a462b4ff0a..aa7184ffd8 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -96,7 +96,7 @@ class InlinerTest extends ClearAfterClass { callsiteInstruction = callsiteInstruction, 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)), + callee = Right(callGraph.Callee(callee = callee, calleeDeclarationClass = calleeDeclarationClass, safeToInline = true, safeToRewrite = false, annotatedInline = false, annotatedNoInline = false, samParamTypes = IntMap.empty, calleeInfoWarning = None)), argInfos = IntMap.empty, callsiteStackHeight = callsiteStackHeight, receiverKnownNotNull = receiverKnownNotNull, |