RFR: 8369654: javac OutOfMemoryError for complex intersection type [v3]
Vicente Romero
vromero at openjdk.org
Thu Oct 30 19:49:30 UTC 2025
On Thu, 30 Oct 2025 12:57:09 GMT, Vicente Romero <vromero at openjdk.org> wrote:
>> Javac is throwing an OOME for the code like:
>>
>> class Test {
>> interface WithMixin01<T> {}
>> // ...
>> // 20 interfaces here
>> interface WithMixin20<T> {}
>>
>> interface ClientA extends
>> WithMixin02<ClientA>,
>> WithMixin01<ClientA>,
>> WithMixin03<ClientA>,
>> WithMixin04<ClientA>,
>> WithMixin05<ClientA>,
>> WithMixin06<ClientA>,
>> WithMixin07<ClientA>,
>> WithMixin08<ClientA>,
>> WithMixin09<ClientA>,
>> WithMixin10<ClientA>,
>> WithMixin11<ClientA>,
>> WithMixin12<ClientA>,
>> WithMixin13<ClientA>,
>> WithMixin14<ClientA>,
>> WithMixin15<ClientA>,
>> WithMixin16<ClientA>,
>> WithMixin17<ClientA>,
>> WithMixin18<ClientA>,
>> WithMixin19<ClientA>,
>> WithMixin20<ClientA> {
>> }
>>
>> interface ClientB extends
>> WithMixin01<ClientB>,
>> WithMixin02<ClientB>,
>> WithMixin03<ClientB>,
>> WithMixin04<ClientB>,
>> WithMixin05<ClientB>,
>> WithMixin06<ClientB>,
>> WithMixin07<ClientB>,
>> WithMixin08<ClientB>,
>> WithMixin09<ClientB>,
>> WithMixin10<ClientB>,
>> WithMixin11<ClientB>,
>> WithMixin12<ClientB>,
>> WithMixin13<ClientB>,
>> WithMixin14<ClientB>,
>> WithMixin15<ClientB>,
>> WithMixin16<ClientB>,
>> WithMixin17<ClientB>,
>> WithMixin18<ClientB>,
>> WithMixin19<ClientB>,
>> WithMixin20<ClientB> {
>> }
>>
>> public static void main(String... args) {
>> ClientA a = null;
>> ClientB b = null;
>> String selector = "a";
>> Object o = switch (selector) {
>> case "a" -> a;
>> case "b" -> b;
>> default -> null;
>> };
>> }
>> }
>>
>> the reason is that after [JDK-8353565](https://bugs.openjdk.org/browse/JDK-8353565) we are using Types::lub when joining jump chains in Code. The result of the lub will be erased anyways so the proposal here is to cut in the result given by lub types that will be erased anyways. The reason for the slow lub invocation here is that in order to obtain the lub in this case, the lub method is invoked several times. Each invocation, minus the first one, with very complex types which makes them very ...
>
> Vicente Romero has updated the pull request incrementally with one additional commit since the last revision:
>
> Update src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>
> Co-authored-by: Andrey Turbanov <turbanoff at gmail.com>
some data points to have an idea of the number of times we are invoking lub for the test case included in the description above. Assuming that we run it with different definitions of ClientA and ClientB changing the number of super types so for `# of SuperTypes == 1` we would have:
interface ClientA extends WithMixin01<ClientA> {}
interface ClientB extends WithMixin01<ClientB> {}
for 2 supertypes we would have:
interface ClientA extends WithMixin01<ClientA>, WithMixin02<ClientA> {}
interface ClientB extends WithMixin01<ClientB>, WithMixin02<ClientB> {}
and so on. I got the table below:
| # of SuperTypes | # of Lub Invocations |
|---|---|
| 1| 1
| 2 | 5
| 3 | 16
| 4 | 65
| 5 | 326
| 6 | 1957
| 7 | 13700
| 8 | 109601
| 9 | 986410
| 10 |
which is exponential on `# of SuperTypes` and steeper that `e^x` for `# of SuperTypes` > 3
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28050#issuecomment-3469791849
More information about the compiler-dev
mailing list