summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala17
1 files changed, 9 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
index 83615abc31..d85d85003d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
@@ -76,7 +76,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
* host a static field in the enclosing class. This allows us to add this method to interfaces
* that define lambdas in default methods.
*/
- def addLambdaDeserialize(classNode: ClassNode): Unit = {
+ def addLambdaDeserialize(classNode: ClassNode, implMethods: List[Handle]): Unit = {
val cw = classNode
// Make sure to reference the ClassBTypes of all types that are used in the code generated
@@ -87,12 +87,13 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
val nilLookupDesc = MethodBType(Nil, jliMethodHandlesLookupRef).descriptor
val serlamObjDesc = MethodBType(jliSerializedLambdaRef :: Nil, ObjectRef).descriptor
+ val addTargetMethodsObjDesc = MethodBType(ObjectRef :: Nil, UNIT).descriptor
{
val mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambda$", serlamObjDesc, null, null)
mv.visitCode()
mv.visitVarInsn(ALOAD, 0)
- mv.visitInvokeDynamicInsn("lambdaDeserialize", serlamObjDesc, lambdaDeserializeBootstrapHandle)
+ mv.visitInvokeDynamicInsn("lambdaDeserialize", serlamObjDesc, lambdaDeserializeBootstrapHandle, implMethods: _*)
mv.visitInsn(ARETURN)
mv.visitEnd()
}
@@ -104,16 +105,16 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
* a boolean indicating if the instruction list contains an instantiation of a serializable SAM
* type.
*/
- def cloneInstructions(methodNode: MethodNode, labelMap: Map[LabelNode, LabelNode], keepLineNumbers: Boolean): (InsnList, Map[AbstractInsnNode, AbstractInsnNode], Boolean) = {
+ def cloneInstructions(methodNode: MethodNode, labelMap: Map[LabelNode, LabelNode], keepLineNumbers: Boolean): (InsnList, Map[AbstractInsnNode, AbstractInsnNode], List[Handle]) = {
val javaLabelMap = labelMap.asJava
val result = new InsnList
var map = Map.empty[AbstractInsnNode, AbstractInsnNode]
- var hasSerializableClosureInstantiation = false
+ var inlinedTargetHandles = mutable.ListBuffer[Handle]()
for (ins <- methodNode.instructions.iterator.asScala) {
- if (!hasSerializableClosureInstantiation) ins match {
+ ins match {
case callGraph.LambdaMetaFactoryCall(indy, _, _, _) => indy.bsmArgs match {
- case Array(_, _, _, flags: Integer, xs@_*) if (flags.intValue & LambdaMetafactory.FLAG_SERIALIZABLE) != 0 =>
- hasSerializableClosureInstantiation = true
+ case Array(_, targetHandle: Handle, _, flags: Integer, xs@_*) if (flags.intValue & LambdaMetafactory.FLAG_SERIALIZABLE) != 0 =>
+ inlinedTargetHandles += targetHandle
case _ =>
}
case _ =>
@@ -124,7 +125,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
map += ((ins, cloned))
}
}
- (result, map, hasSerializableClosureInstantiation)
+ (result, map, inlinedTargetHandles.toList)
}
def getBoxedUnit: FieldInsnNode = new FieldInsnNode(GETSTATIC, srBoxedUnitRef.internalName, "UNIT", srBoxedUnitRef.descriptor)