summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-07-07 14:34:11 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-07-07 14:39:33 +0200
commit6e273f7cb6a0f6ff12d899676d30aff5d83b3bb1 (patch)
treea205774f06159d0f7430d3a5b215039c5e0ae74c /src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
parente9c742e1d27c41ee8646ea20dfb59efbc3d94ef3 (diff)
downloadscala-6e273f7cb6a0f6ff12d899676d30aff5d83b3bb1.tar.gz
scala-6e273f7cb6a0f6ff12d899676d30aff5d83b3bb1.tar.bz2
scala-6e273f7cb6a0f6ff12d899676d30aff5d83b3bb1.zip
Small refactoring to the closure optimizer
Introduces an extractor `LMFInvokeDynamic` that matches InvokeDynamic instructions that are LambdaMetaFactory calls. The case class `LambdaMetaFactoryCall` holds such an InvokeDynamic instruction. It also holds the bootstrap arguments (samMethodType, implMethod, instantiatedMethodType) so that they can be accessed without casting the indy.bsmArgs. The `closureInstantiations` map in the call graph now stores ClosureInstantiation objects instead of a tuple. This simplifies some code and gets rid of a few casts.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala31
1 files changed, 15 insertions, 16 deletions
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 4a022b7bc4..3794ee9950 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -456,9 +456,9 @@ class Inliner[BT <: BTypes](val btypes: BT) {
case indy: InvokeDynamicInsnNode =>
callGraph.closureInstantiations.get(indy) match {
- case Some((methodNode, ownerClass)) =>
+ case Some(closureInit) =>
val newIndy = instructionMap(indy).asInstanceOf[InvokeDynamicInsnNode]
- callGraph.closureInstantiations(newIndy) = (callsiteMethod, callsiteClass)
+ callGraph.closureInstantiations(newIndy) = ClosureInstantiation(closureInit.lambdaMetaFactoryCall.copy(indy = newIndy), callsiteMethod, callsiteClass)
case None =>
}
@@ -688,7 +688,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
}
}
- case indy: InvokeDynamicInsnNode =>
+ case LMFInvokeDynamic(lmf) =>
// an indy instr points to a "call site specifier" (CSP) [1]
// - a reference to a bootstrap method [2]
// - bootstrap method name
@@ -734,21 +734,20 @@ class Inliner[BT <: BTypes](val btypes: BT) {
// the implMethod is public, lambdaMetaFactory doesn't use the Lookup object's extended
// capability, and we can safely inline the instruction into a different class.
- if (destinationClass == calleeDeclarationClass) {
+ val methodRefClass = classBTypeFromParsedClassfile(lmf.implMethod.getOwner)
+ for {
+ (methodNode, methodDeclClassNode) <- byteCodeRepository.methodNode(methodRefClass.internalName, lmf.implMethod.getName, lmf.implMethod.getDesc): Either[OptimizerWarning, (MethodNode, InternalName)]
+ methodDeclClass = classBTypeFromParsedClassfile(methodDeclClassNode)
+ res <- memberIsAccessible(methodNode.access, methodDeclClass, methodRefClass, destinationClass)
+ } yield {
+ res
+ }
+
+ case indy: InvokeDynamicInsnNode =>
+ if (destinationClass == calleeDeclarationClass)
Right(true) // within the same class, any indy instruction can be inlined
- } else if (closureOptimizer.isClosureInstantiation(indy)) {
- val implMethod = indy.bsmArgs(1).asInstanceOf[Handle] // safe, checked in isClosureInstantiation
- val methodRefClass = classBTypeFromParsedClassfile(implMethod.getOwner)
- for {
- (methodNode, methodDeclClassNode) <- byteCodeRepository.methodNode(methodRefClass.internalName, implMethod.getName, implMethod.getDesc): Either[OptimizerWarning, (MethodNode, InternalName)]
- methodDeclClass = classBTypeFromParsedClassfile(methodDeclClassNode)
- res <- memberIsAccessible(methodNode.access, methodDeclClass, methodRefClass, destinationClass)
- } yield {
- res
- }
- } else {
+ else
Left(UnknownInvokeDynamicInstruction)
- }
case ci: LdcInsnNode => ci.cst match {
case t: asm.Type => classIsAccessible(bTypeForDescriptorOrInternalNameFromClassfile(t.getInternalName), destinationClass)