condy and enums

Liam Miller-Cushon cushon at google.com
Wed Oct 11 23:03:08 UTC 2023


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?

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
> >
> > 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/20231011/dd63adaa/attachment-0001.htm>


More information about the compiler-dev mailing list