Skip to content

Commit f9dbade

Browse files
committed
Move addLambdaDeserialize into the BTypes assembly
This allows accessing the method from the inliner, which doesn't have access to the Global instance.
1 parent 7088682 commit f9dbade

File tree

4 files changed

+65
-62
lines changed

4 files changed

+65
-62
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -683,60 +683,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
683683
new java.lang.Long(id)
684684
).visitEnd()
685685
}
686-
687-
/**
688-
* Add:
689-
* private static java.util.Map $deserializeLambdaCache$ = null
690-
* private static Object $deserializeLambda$(SerializedLambda l) {
691-
* var cache = $deserializeLambdaCache$
692-
* if (cache eq null) {
693-
* cache = new java.util.HashMap()
694-
* $deserializeLambdaCache$ = cache
695-
* }
696-
* return scala.runtime.LambdaDeserializer.deserializeLambda(MethodHandles.lookup(), cache, l);
697-
* }
698-
*/
699-
def addLambdaDeserialize(clazz: Symbol, jclass: asm.ClassVisitor): Unit = {
700-
val cw = jclass
701-
import scala.tools.asm.Opcodes._
702-
703-
// Need to force creation of BTypes for these as `getCommonSuperClass` is called on
704-
// automatically computing the max stack size (`visitMaxs`) during method writing.
705-
javaUtilHashMapReference
706-
javaUtilMapReference
707-
708-
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC + ACC_FINAL + ACC_STATIC)
709-
710-
{
711-
val fv = cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambdaCache$", "Ljava/util/Map;", null, null)
712-
fv.visitEnd()
713-
}
714-
715-
{
716-
val mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambda$", "(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", null, null)
717-
mv.visitCode()
718-
// javaBinaryName returns the internal name of a class. Also used in BTypesFromsymbols.classBTypeFromSymbol.
719-
mv.visitFieldInsn(GETSTATIC, clazz.javaBinaryName.toString, "$deserializeLambdaCache$", "Ljava/util/Map;")
720-
mv.visitVarInsn(ASTORE, 1)
721-
mv.visitVarInsn(ALOAD, 1)
722-
val l0 = new asm.Label()
723-
mv.visitJumpInsn(IFNONNULL, l0)
724-
mv.visitTypeInsn(NEW, "java/util/HashMap")
725-
mv.visitInsn(DUP)
726-
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false)
727-
mv.visitVarInsn(ASTORE, 1)
728-
mv.visitVarInsn(ALOAD, 1)
729-
mv.visitFieldInsn(PUTSTATIC, clazz.javaBinaryName.toString, "$deserializeLambdaCache$", "Ljava/util/Map;")
730-
mv.visitLabel(l0)
731-
mv.visitFieldInsn(GETSTATIC, "scala/runtime/LambdaDeserializer$", "MODULE$", "Lscala/runtime/LambdaDeserializer$;")
732-
mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false)
733-
mv.visitVarInsn(ALOAD, 1)
734-
mv.visitVarInsn(ALOAD, 0)
735-
mv.visitMethodInsn(INVOKEVIRTUAL, "scala/runtime/LambdaDeserializer$", "deserializeLambda", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/util/Map;Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", false)
736-
mv.visitInsn(ARETURN)
737-
mv.visitEnd()
738-
}
739-
}
740686
} // end of trait BCClassGen
741687

742688
/* functionality for building plain and mirror classes */

src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
130130
&& indyLambdaHosts.contains(claszSymbol))
131131

132132
if (shouldAddLambdaDeserialize)
133-
addLambdaDeserialize(claszSymbol, cnode)
133+
backendUtils.addLambdaDeserialize(cnode)
134134

135135
addInnerClassesASM(cnode, innerClassBufferASM.toList)
136136

src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,14 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
206206

207207
def boxedClasses: Set[ClassBType]
208208

209-
def RT_NOTHING : ClassBType
210-
def RT_NULL : ClassBType
211-
212-
def ObjectReference : ClassBType
213-
def jlCloneableReference : ClassBType
214-
def jioSerializableReference : ClassBType
209+
def RT_NOTHING: ClassBType
210+
def RT_NULL : ClassBType
211+
212+
def ObjectReference : ClassBType
213+
def jlCloneableReference : ClassBType
214+
def jioSerializableReference: ClassBType
215+
def javaUtilHashMapReference: ClassBType
216+
def javaUtilMapReference : ClassBType
215217
}
216218

217219
/**

src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package scala.tools.nsc
22
package backend.jvm
33
package analysis
44

5-
import scala.tools.asm.tree.{AbstractInsnNode, MethodNode}
5+
import scala.tools.asm.Label
6+
import scala.tools.asm.tree.{ClassNode, AbstractInsnNode, MethodNode}
67
import scala.tools.asm.tree.analysis.{Frame, BasicInterpreter, Analyzer, Value}
78
import scala.tools.nsc.backend.jvm.BTypes._
89
import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
@@ -47,4 +48,58 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
4748
}
4849

4950
class ProdConsAnalyzer(val methodNode: MethodNode, classInternalName: InternalName) extends AsmAnalyzer(methodNode, classInternalName, new Analyzer(new InitialProducerSourceInterpreter)) with ProdConsAnalyzerImpl
51+
52+
/**
53+
* Add:
54+
* private static java.util.Map $deserializeLambdaCache$ = null
55+
* private static Object $deserializeLambda$(SerializedLambda l) {
56+
* var cache = $deserializeLambdaCache$
57+
* if (cache eq null) {
58+
* cache = new java.util.HashMap()
59+
* $deserializeLambdaCache$ = cache
60+
* }
61+
* return scala.runtime.LambdaDeserializer.deserializeLambda(MethodHandles.lookup(), cache, l);
62+
* }
63+
*/
64+
def addLambdaDeserialize(classNode: ClassNode): Unit = {
65+
val cw = classNode
66+
import scala.tools.asm.Opcodes._
67+
68+
// Need to force creation of BTypes for these as `getCommonSuperClass` is called on
69+
// automatically computing the max stack size (`visitMaxs`) during method writing.
70+
btypes.coreBTypes.javaUtilHashMapReference
71+
btypes.coreBTypes.javaUtilMapReference
72+
73+
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC + ACC_FINAL + ACC_STATIC)
74+
75+
{
76+
val fv = cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambdaCache$", "Ljava/util/Map;", null, null)
77+
fv.visitEnd()
78+
}
79+
80+
{
81+
val mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$deserializeLambda$", "(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", null, null)
82+
mv.visitCode()
83+
// javaBinaryName returns the internal name of a class. Also used in BTypesFromsymbols.classBTypeFromSymbol.
84+
mv.visitFieldInsn(GETSTATIC, classNode.name, "$deserializeLambdaCache$", "Ljava/util/Map;")
85+
mv.visitVarInsn(ASTORE, 1)
86+
mv.visitVarInsn(ALOAD, 1)
87+
val l0 = new Label()
88+
mv.visitJumpInsn(IFNONNULL, l0)
89+
mv.visitTypeInsn(NEW, "java/util/HashMap")
90+
mv.visitInsn(DUP)
91+
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false)
92+
mv.visitVarInsn(ASTORE, 1)
93+
mv.visitVarInsn(ALOAD, 1)
94+
mv.visitFieldInsn(PUTSTATIC, classNode.name, "$deserializeLambdaCache$", "Ljava/util/Map;")
95+
mv.visitLabel(l0)
96+
mv.visitFieldInsn(GETSTATIC, "scala/runtime/LambdaDeserializer$", "MODULE$", "Lscala/runtime/LambdaDeserializer$;")
97+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false)
98+
mv.visitVarInsn(ALOAD, 1)
99+
mv.visitVarInsn(ALOAD, 0)
100+
mv.visitMethodInsn(INVOKEVIRTUAL, "scala/runtime/LambdaDeserializer$", "deserializeLambda", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/util/Map;Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", false)
101+
mv.visitInsn(ARETURN)
102+
mv.visitEnd()
103+
}
104+
}
50105
}

0 commit comments

Comments
 (0)