Draft JEP Announcement: "Computed Constants"

Dan Heidinga heidinga at redhat.com
Fri Jul 28 15:53:31 UTC 2023

First off, congrats Per and Maurizio for such a clear well written draft
JEP and for finding a library solution to this problem.  It's great work!

I've spent a lot of time looking into "unscrambling the <clinit> egg"
through the use of the IDOH pattern, GraalVM's Substitution mechanism,
qbicc's per-field <rtinit> method(s) and I'm pretty happy with the approach
you've taken here as it provides an essential building block for decoupling
state in <clinit> for new classes.  One of the challenges in this space has
been trying to discern / reverse-engineer the developer's intent after the
fact from the very conjoined <clinit> method.  This approach provides
developers a way to easily separate out each field's initialization code
and lifecycle from the other static fields in a class.

With my "optimizing startup hat on", I share some of the concerns others
have expressed about the use of lambdas to initialize ComputedConstant as
it exposes the lambda cost model to end users - users now need to
understand if the cost of the lambda generation (inflation?  Not sure what
the right term is for converting a lambda expression to a functional
interface instance) will be more or less than the cost of the computation
they want to store in a ComputedConstant if they want to realize a startup
benefit from this change.

While Per and Maurizio have already suggested partial solutions for this -
use an anonymous class, a predefined Supplier instance, or
ComputedConstant.ofList - I'm slightly concerned this can become a
tragedy of the commons like problem where multiple classes in an
application - or even multiple libraries - each use ComputedConstant.of()
and see an improvement for their use class, but a degradation when all are
put together in a single application.  Maurizio indicates they saw exactly
this problem with jextract and were able to use the
ComputedConstant.ofList() to address it, but that's when all uses are from
a single source and can be updated together.  Do you have any thoughts on
how to avoid this unstable state where using more ComputedConstants might
regress startup?

As suggested in the "Dependencies" section of the JEP, this may enable
pre-evaluating computed constants.  Given that goal, should language like
the following sentence from the java.util.concurrent.constant package
summary javadoc be avoid?
> In other words, a provider can only run once and in the first-calling
thread and so, there is no race across threads which guarantees the
at-most-once evaluation
This defines when the provider is called which may need to be adapted if
time-shifting a ComputedConstant becomes possible.  Is it better to avoid
the "first-calling thread" claim from the start?

>From the java.util.concurrent.constant.ComputedConstant javadoc:
> If a thread calls this method while being bound by another thread, the
current thread will be suspended until the binding completes (successfully
or not). Otherwise, this method is guaranteed to be lock-free.
Which lock is being used to serialize the computation?  Is it the same lock
used for serializing access to <clinit> or is some other lock for just the
constants or....?  Using the same lock as <clinit> may lead to similar
surprising deadlocks as when the appserver folk were first experimenting
with more complex classloading designs (ie: osgi, others) which took many
years to resolve so I'd suggest picking something unrelated if possible.

Again, I think this is a great building block and I'm excited to see it
being proposed.


On Thu, Jul 27, 2023 at 11:53 AM Per-Ake Minborg <per-ake.minborg at oracle.com>

> Hi all,
>   Maurizio and I have drafted a JEP for computed constants, which are
>   immutable value holders that are initialized at most once.  They offer
>   the performance and safety benefits of final fields while offering
>   greater flexibility as to the timing of initialization.  In the
>   context of Leyden, they could be one basis for shifting computation
>   both forward and backward in time.
>   The draft is here: https://openjdk.org/jeps/8312611
>   Now that the Leyden repo is open, I’ll publish the prototype code to a
>   new branch there shortly.
>   Comments are welcome!
>   Best, Per
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20230728/6474d39f/attachment.htm>

More information about the leyden-dev mailing list