RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v8]
Archie L. Cobbs
duke at openjdk.org
Wed Jan 18 23:12:34 UTC 2023
> This patch is both a minor optimization and a fix for JDK-7176515.
>
> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar".
>
> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later.
>
> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug.
>
> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table.
>
> This results in two improvements:
> * It avoids building the lookup table for switches on self
> * It fixes JDK-7176515 as stated
>
> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out).
>
> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it.
>
> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled.
Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision:
Simplify code a bit by using Map.computeIfAbsent().
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/10797/files
- new: https://git.openjdk.org/jdk/pull/10797/files/6f7f30f7..53be679b
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=07
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=06-07
Stats: 4 lines in 1 file changed: 0 ins; 3 del; 1 mod
Patch: https://git.openjdk.org/jdk/pull/10797.diff
Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797
PR: https://git.openjdk.org/jdk/pull/10797
More information about the compiler-dev
mailing list