condy and enums

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Oct 11 23:35:37 UTC 2023


On 12/10/2023 00:03, Liam Miller-Cushon wrote:
> Hi Maurizio, thanks for the comments!
>
> I am still kind of on the fence about this one, as you say.
>
> I collected some data from Google's codebase, and a majority of enum 
> constants would be able to use condy:
> * 71% of enum declarations have no explicit constructors that take 
> parameters.
> * 80% percent of expressions used as arguments to enum constructors 
> are constants.
> * The most common non-constant expressions used as arguments to enum 
> constructors include static factory methods (e.g. `List.of(...)`, 
> `Map.of(...)`, Optional.of(...)`). I also saw a number of static field 
> accesses (e.g. `BigDecimal.ZERO`). None of those individual examples 
> account for more than 1% of the total, and there was a long tail.
>
> What are your thoughts on how often we'd want to be able to use this 
> path, before it was worth supporting?

Hi Liam
Thanks for the great data (as always).

I think these numbers make the evidence for your case a little stronger, 
as it does seem that the footprint will be reduced in the majority of cases.

On balance, I believe it's something that might be worth pursuing.

As pointed out in other emails, we'd need to keep an eye on the startup 
impact (because of condy), as well as possible bootstrap issues when 
using such a feature in a module like java.base. For instance, the 
indified string concat support has an option so that it's turned off 
when compiling java.base.

Cheers
Maurizio



>
> On Tue, Oct 10, 2023 at 3:34 AM Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com> wrote:
>
>     Hi Liam,
>     the overall idea seem fine. I'm a bit on the fence (as I think you
>     already are) when I try to assess whether adding the extra
>     complexity is
>     worth it here. On the one hand, the code we have today is not very
>     compact, but the javac translation strategy is quite uniform, and can
>     deal with both enum construction and custom enums (e.g. enums which
>     define their own bodies). The approach proposed here, while it's more
>     compact for the case where an enum has no parameters (or where the
>     parameters are not constant), it has to contain some fallback
>     logic for
>     the more general case, so the resulting lowering code becomes a
>     little
>     bit more cryptic to understand, and maintain (going forward).
>
>     Do you have some data re. how many enum construction can be optimized
>     with this approach? Trying to think about code I've seen in the past,
>     the assumption that enum construction parameters are constant doesn't
>     strike me as too unrealistic, so I would expect that a lot of
>     enums out
>     there could be optimized by this path (in which case I'd be more
>     willing
>     to consider it).
>
>     Thanks for the great work!
>     Maurizio
>
>
>     On 09/10/2023 22:45, Liam Miller-Cushon wrote:
>     > Hello,
>     >
>     > I'd like to discuss the idea of using constant dynamic in the
>     > generated code for enums.
>     >
>     > The possibility of using condy came up in the review thread for
>     > JDK-8241798, which implemented a small change to the code
>     generation
>     > strategy for enums to raise the limit on the number of enum
>     constants.
>     > To recap, there are limits on the number of constants in an enum
>     > imposed by the class file format. The constants are represented as
>     > static final fields, which have to be initialized in the clinit,
>     which
>     > eventually runs into the 64k method size limit:
>     >
>     >
>     https://mail.openjdk.org/pipermail/compiler-dev/2020-March/014413.html
>     > https://bugs.openjdk.org/browse/JDK-8241798
>     >
>     > I did some recent experimentation into using condy to initialize
>     enum
>     > constants and create the values array. There's a very rough draft
>     > here: https://github.com/openjdk/jdk/pull/16108
>     <https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/16108__;!!ACWV5N9M2RV99hQ!LfR6LWykI9T8OOPyuCoGQDZPUBAgWFkAT22M6yh7r8c4Nyscjyx9K8iQBKFut-J6SSLbCkwfDV_zdClD7xULwQ$>
>     >
>     > With that change the clinit just contains a ldc/putstatus for each
>     > constant, which is 6 bytes per constant, raising the limit on the
>     > number of constants from ~4k today to about 10k.
>     >
>     > I am interested in high level feedback about the idea. Does this
>     seem
>     > like a good use of condy, or a bad use of condy? Are there reasons
>     > (performance, maintenance, other things I'm not considering) why
>     using
>     > condy in this way wouldn't be advisable?
>     >
>     > One caveat is that it may not be very valuable to raise the limit
>     > further. Four thousand is already a lot of enum constants. I
>     suspect
>     > for many domains where it's necessary to represent >4k values,
>     it will
>     > eventually need to represent >10k values, and that enums are not
>     the
>     > best way to model those domains. So I wouldn't argue for doing
>     this if
>     > there end up being a lot of trade-offs, but if the condy
>     approach was
>     > appealing in general perhaps raising the limit at the same time
>     could
>     > be win-win.
>     >
>     > Working through the prototype raised some questions about what a
>     > production quality implementation would look like:
>     >
>     > Enums with user-defined constructors are currently only handled
>     if the
>     > arguments are static constants. What would the right solution be?
>     > Perhaps a factory method could be synthetized for constants with
>     > non-constant arguments, so condy could still be used to load them.
>     >
>     > The class initializer for MethodHandle transitively loads enums, so
>     > having enum class initializers use condy creates a cyclic
>     dependency.
>     > The prototype skips the new strategy for java.base. I could imagine
>     > having a way to opt specific enums out of the new strategy, but
>     having
>     > to maintain multiple code generation strategies for enums does not
>     > seem very appealing. Perhaps there's a way to refactor to break
>     those
>     > cycles, or that the lazy static final field proposal in JDK-8209964
>     > could help here, or something else.
>     >
>     > I'm curious what you think,
>     > Liam
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20231012/038b98ef/attachment-0001.htm>


More information about the compiler-dev mailing list