RFR: 8336492: Regression in lambda serialization [v3]
Liam Miller-Cushon
cushon at openjdk.org
Tue Jul 30 16:20:33 UTC 2024
On Sat, 27 Jul 2024 18:42:13 GMT, Liam Miller-Cushon <cushon at openjdk.org> wrote:
>> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision:
>>
>> Add more docs to CaptureScanner, and make fields private/final
>
> Some initial testing shows a regression in type annotation handling with this change.
>
> Given an example like the following, the type annotation in the lambda is now being incorrectly propagated to the constructor. A `RuntimeInvisibleTypeAnnotations` attribute for the annotation is emitted on both the synthetic lambda method and the constructor. I noticed this because the `length` for the `RuntimeInvisibleTypeAnnotations` is longer than the constructor, and both ASM and javap report an error for the class file.
>
>
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Target;
> import java.util.ArrayList;
> import java.util.List;
>
> class T {
> @Target(ElementType.TYPE_USE)
> @interface A {}
>
> Runnable r =
> () -> {
> List<@A Object> xs = new ArrayList<>();
> xs.add(1);
> xs.add(2);
> xs.add(3);
> xs.add(5);
> xs.add(6);
> xs.add(7);
> xs.add(8);
> };
>
> T() {}
> }
>
>
> javap reports an error because the type annotation's length is longer than the constructor:
>
>
> $ javap -c T
> Compiled from "T.java"
> class T {
> java.lang.Runnable r;
>
> T();
> Code:
> Error: error at or after byte 0
> Error: Fatal error: Bytecode offset out of range; bci=89, codeLength=14
>
>
> Using the JDK 11 javap shows
>
>
> T();
> descriptor: ()V
> flags: (0x0000)
> Code:
> stack=2, locals=1, args_size=1
> 0: aload_0
> 1: invokespecial #1 // Method java/lang/Object."<init>":()V
> 4: aload_0
> 5: invokedynamic #7, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable;
> 10: putfield #11 // Field r:Ljava/lang/Runnable;
> 13: return
> LineNumberTable:
> line 22: 0
> line 10: 4
> line 22: 13
> RuntimeInvisibleTypeAnnotations:
> 0: #35(): LOCAL_VARIABLE, {start_pc=8, length=81, index=0}, location=[TYPE_ARGUMENT(0)]
> T$A
> @cushon things look stable on our end, maybe you want to give this PR another try?
I will verify with the latest changes, but I have preliminary results from testing before https://github.com/openjdk/jdk/pull/20349/commits/6a5501fa83aef2ee455e7c965a1ebc74d36b97ec. There were no unexpected regressions, and some minor expected compatibility impact:
* A number of tests are asserting on names of synthetic lambda methods that have changed (e.g. `assertThat(Throwables.getStackTraceAsString(...)).contains("foo$0");`)
* I found a single test that was reading in persisted serialized data which no longer deserialized, and had to be updated to match the new output
I also removed the workarounds I'd added for JDK-8336492 and confirmed that they are unnecessary after these changes.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20349#issuecomment-2258727944
More information about the compiler-dev
mailing list