RFR: JDK-8241798: Allow enums to have more constants

Brian Goetz brian.goetz at oracle.com
Mon Mar 30 13:45:06 UTC 2020


Remi is of course correct that there are many creative solutions using indy/condy.  I don’t want to stifle that creativity, but I also don’t want that creativity to stop Liam from making progress.

Liam observed a problem, and came up with a narrowly targeted, low risk solution that doesn’t reopen questions about translation strategy and that is obviously better than what we have.  Yes, we could discuss whether there’s a better big-picture strategy for dealing with the values() method, or for pushing the limit up higher.  But let’s also be aware that it is too easy to get mired in blue-sky ideas and then Liam’s problem is not solved.  

So, +1 from me on this patch.  It is simple and responsible.  



> On Mar 28, 2020, at 8:12 PM, Remi Forax <forax at univ-mlv.fr> wrote:
> 
> Hi Liam,
> Having values() initialized is the static block is a common issue once you have a code generator that spit enums.
> I had a similar issue and ends up not using enums but plain old classes in the generator because of that.
> 
> There is another solution,
> you can use constantdynamic and pass the names of the constants (an array) as a bootstrap argument,
> you can go up to 65 635 (the limit in term of number of fields), in fact far less because the constant pool will be full before that point.
> 
> public static MyEnum[] values()  {
>   ldc "values" [MyEnum   [BSM=java/lang/runtime/ConstantEnumMetaFactory] ["constant1", "constant2", ...]
>   invokevirtual clone()
>   areturn
> }
> 
> The major advantage of using constant dynamic is that if nobody calls the method values(), the array is never initialized.
> 
> And once the VM will suport fields declared as "lazy static final", you can get ride of the static bock because the initialization of the constant fields will be done lazily too.
> 
> Rémi
> 
> De: "Liam Miller-Cushon" <cushon at google.com>
> À: "compiler-dev" <compiler-dev at openjdk.java.net>
> Envoyé: Dimanche 29 Mars 2020 00:37:24
> Objet: RFR: JDK-8241798: Allow enums to have more constants
> Please consider this change to allow enums to have ~4100 constants (up from the current limit of ~2740), by moving the creation of the values array out of the clinit to a helper method.
> 
> It's fair to ask whether this is worth doing. Increasing the limit by this amount doesn't really change the use-cases enums are suitable for: they still can't represent arbitrarily large collections of constants, and if you have an enum with >2740 constants you're probably going to want >4100 eventually. On the other hand, I don't see any obvious drawbacks to the change (in terms of complexity in the compiler, performance impact, or complexity of generated code). And other options for increasing the limit would require significantly more difficult and longer-term changes (e.g. tackling the method and constant pool size limits).
> 
> Another question is whether this is the best code generation strategy. Currently javac saves the values array to a field and returns copies of it using clone(). The approach ecj uses skips the field, and just re-creates the array every time values() is called. For now I'm keeping the values field to minimize the performance impact of this change, but the ecj approach would avoid that field and the helper method.
> 
> bug: https://bugs.openjdk.java.net/browse/JDK-8241798 <https://bugs.openjdk.java.net/browse/JDK-8241798>
> webrev: http://cr.openjdk.java.net/~cushon/8241798/webrev.00/ <http://cr.openjdk.java.net/~cushon/8241798/webrev.00/>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20200330/ecda6cb0/attachment.htm>


More information about the compiler-dev mailing list