RFR: 8336492: Regression in lambda serialization [v3]

Maurizio Cimadamore mcimadamore at openjdk.org
Tue Jul 30 17:58:33 UTC 2024


On Tue, 30 Jul 2024 17:19:06 GMT, Liam Miller-Cushon <cushon at openjdk.org> wrote:

> I investigated, it looks like the order of a captured local and parameter is now reversed in the signature:

I see - since the serialized form of a lambda also includes a signature string, we fail to deserialize if the signature string cannot be parsed to a `MethodType` that is consistent with the type of the generated lambda method. Also, since the order of captures is different, the serialized lambda name is also different.

The order of captures has changed because `CaptureScanner`. Now, if I compile this program using Java 22:


class Test {
   void m(String s, int i) {
       new Object() {
           void g() { System.out.println(s + i); }
       };
   }

   Runnable r(String s, int i) {
       return () -> System.out.println(s + i);
   }
}

I see that the order of capture is the same in both the anon class constructor and the lambda:


  private static void lambda$r$0(java.lang.String, int);
...
  Test$1(Test, java.lang.String, int);


But with this patch they are not:


  private static void lambda$r$0(int, java.lang.String);
...
  Test$1(Test, java.lang.String, int);


The peculiarity (which I missed) is that `Lower` gets the set of freevars, and then always _prepend_ their definition to the class/constructor. `LambdaToMethod`, OTOH, _appends_ them. This is what's causing the mismatched order. I'll fix this, as I think the old order looked better than the new one (as each captured variable appear in "order of capture").

-------------

PR Comment: https://git.openjdk.org/jdk/pull/20349#issuecomment-2258900256


More information about the compiler-dev mailing list