Because anonymous functions in Scala are historically Serializable, In 2.12 we are opting to use a generic deserializer that calls LambdaMetafactory.bootstrap, rather than emitting an indy instruction per lambda within $deserializeLambda$, which has been noted as a problem in javac:
Reduce size of $deserializeLambda$ method https://bugs.openjdk.java.net/browse/JDK-8008413 At JVM language summit last week I was alerted to a flaw in this approach: it inadvertently makes all private methods in the lambda host class accessible by means of a forged SerializedLambda. Thanks for the feedback, Remi and Brian! I'm working to plug this hole, and thought I'd share the technique in case it if of interest beyond scalac: SD-193 Lock down lambda deserialization https://github.com/scala/scala/pull/5321 The body of $deserializeLambda$ is now a single invokedynamic. Its bootstrap argument is an array of method handles to valid lambda target methods. The generic deserializer creates a j.u.HashMap relating these String keys of the form "$methodName $descriptor". It can then limit deserialiazion to SerializedLambda-s targeting these methods. This approach costs 2 bytes per serializable lambda in the constant pool: all the entries are already there for the LambdaMetafactory bootstrap args, we just refer to them again. A downside is that the first lambda to be deserialized will incur a one-time time + space cost proportional the total number of lambdas in the host class to construct the map. Here's the bytecode comparison between this proposal and javac: https://gist.github.com/retronym/fcf46910cc7801f32017e8699a59c831 Regards, Jason Zaugg
_______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev