Eager enum class initialization with enum switch
Remi Forax
forax at univ-mlv.fr
Wed Feb 20 11:48:36 UTC 2019
yes !
we can also fix the fact that shuffling the enum constants is currently a non compatible change.
Tagir,
you can have one bootstrap method for all enums (somewhere in the JDK) given that it will be called with a Lookup that reference the enum class and you can not use a condy directly because the ldc instruction has to be in the same classfile (not the same compilation unit) as the constant pool that defines the condy.
Rémi
----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "Tagir Valeev" <amaembo at gmail.com>, "Alex Buckley" <alex.buckley at oracle.com>
> Cc: "compiler-dev" <compiler-dev at openjdk.java.net>
> Envoyé: Mercredi 20 Février 2019 12:23:57
> Objet: Re: Eager enum class initialization with enum switch
> Hi Tagir,
> as you might know, we have plans to overhaul switch translation strategy:
>
> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000522.html
>
> Which, I think, should take care of fixing this particular issue. I
> think aiming for that plan is better than coming up with a point fix for
> this specific corner case.
>
> Cheers
> Maurizio
>
>
> On 20/02/2019 05:24, Tagir Valeev wrote:
>> Hello, Alex!
>>
>> Thanks for reply. I filed an issue:
>> https://bugs.openjdk.java.net/browse/JDK-8219412
>>
>> It would be great were the lookup table created using condy bootstrap.
>> This would not only fix the reported problem,
>> but also reduce the amount of produced code. In particular, no
>> additional class file would be necessary:
>> bootstrap methods could be generated in the same class (one bootstrap
>> and one constant per enum; the same constant
>> could be reused for several switches over the same enum).
>>
>> With best regards,
>> Tagir Valeev
>>
>> On Wed, Feb 20, 2019 at 5:09 AM Alex Buckley <alex.buckley at oracle.com> wrote:
>>> On 2/16/2019 12:59 AM, Tagir Valeev wrote:
>>>> Consider the following program (Test.java):
>>>>
>>>> class Test {
>>>> enum A{
>>>> X;
>>>> static { System.out.println("A is initialized!"); }
>>>> }
>>>> enum B{
>>>> Y;
>>>> static { System.out.println("B is initialized!"); }
>>>> }
>>>>
>>>> static void testA(A a) { switch(a) {} }
>>>>
>>>> static void testB(B b) { switch(b) {} }
>>>>
>>>> public static void main(String[] args) {
>>>> testA(A.X);
>>>> }
>>>> }
>>>>
>>>> When I compile it via javac and run it I see:
>>>> A is initialized!
>>>> B is initialized!
>>>>
>>>> Despite the fact that testB is never called, and no references to the
>>>> B enum actually used during the program execution. According to JLS
>>>> 12.4.1 B should not be initialized. Am I missing something?
>>> Using JDK 11, I agree that compiling and running Test produces the
>>> results you say.
>>>
>>> It's not valid to initialize the enum type B when no reference to B's
>>> constants or methods is made at run time. I vaguely recall prior
>>> discussions of this unfortunate aspect of javac's translation.
>>>
>>> I notice that the presence of the `testB(B)` method is what triggers
>>> javac's overly eager initialization of B. Without that method
>>> declaration, only "A is initialized!" is printed.
>>>
> >> Alex
More information about the compiler-dev
mailing list