Selectively Shifting and Constraining Computation
Dan Heidinga
heidinga at redhat.com
Mon Nov 7 15:57:50 UTC 2022
On Thu, Oct 27, 2022 at 8:28 PM Mark Reinhold <mark.reinhold at oracle.com>
wrote:
> 2022/10/21 19:49:36 -0700, Dan Heidinga <heidinga at redhat.com>:
> > Thanks for posting this document. It provides a clear starting point for
> > us to move forward to start to address Leyden.
>
> Thanks, Dan, and thanks for your comments and questions.
>
> > A few questions based on my read through:
> >
> >> As long as a condenser preserves program meaning and does not impose
> >> constraints other than those accepted by the developer, an
> implementation has
> >> wide latitude to optimize the result.
> >
> > Does “an implementation” refer only to the JDK or are other parts of the
> > ecosystem - frameworks, libraries, etc - able to add their own condensers
> > as well?
>
> Good question!
>
> We’re concerned here primarily with any software system that’s claimed
> to be a conformant implementation of the Java Platform -- the JDK is
> merely the dominant and best-known example. The components of such a
> system -- including any condensers -- can be held to the rigors of the
> Platform Specification and the JCK, thereby ensuring that they preserve
> the meanings of Java programs.
>
> Some people will, no doubt, want to write their own condensers, and
> obviously we’d like all condensers to preserve program meaning. The
> current conformance regime (specification/RI/JCK), however, applies only
> to entire Platform implementations.
Interesting. I'm hesitating to raise this as I don't want to derail the
technical topics, but I recall that after jlink was released, it was
necessary to update the definition of the "platform" to handle the subset
runtimes created by jlink. With the kinds of changes envisioned for
condensers - including removing unused classes, fields & methods - will we
need to update the definition of the platform again? Updates of this
nature tend to take a while on the legal front so I'm raising this early
(and hoping it's already being thought about) so the project doesn't end up
with conderners that can't be shipped due to conflicts with the platform
definition.
If we want to
> enable developers of
> external condensers to make certifiable claims of safety then we’ll need
> to extend the conformance regime to test standalone condensers.
> (Whether that needs to be a priority isn’t clear to me at the moment.)
>
There will be gaps, especially early on given the incremental delivery
plan, that frameworks will be eager to fill. As long as we provide
frameworks a way to implement custom condensers, then they'll be happy even
if they can't make the conformance claims. Many of them have adopted
native image today which suffers from the same conformance risks.
>
> Enabling the foundational tooling of the JDK (jlink, or whatever) to run
> arbitrary condensers is attractive, but not without risk. People could
> ship non-conformant condensers even if we extend the conformance regime,
> since there’d be no conformance requirement. Developers could, perhaps
> unwittingly, use such condensers and wind up with broken programs. So
> maybe we’ll support external condensers in the JDK toolchain but emit a
> warning when they’re used.
>
>
I'm glad to hear there's a path forward here. Warnings are a reasonable
restriction for custom condensers.
> >> If a developer chooses condensers that shift sufficient computation
> from run
> >> time to earlier phases — which may require accepting many constraints —
> then
> >> a conforming Java implementation could even produce a fully-static
> >> platform-specific executable.
> >
> > Great to read this! Especially in light of the recent announcement
> around
> > GraalCE moving under the OpenJDK umbrella, this provides wide latitude to
> > use something like Graal’s native image as a final condenser.
>
> Exactly.
>
> > ...
> >
> >> Some of these techniques might not require any specification changes,
> e.g.,
> >> expanding dynamic-proxy call sites into ordinary bytecode prior to run
> time.
> >
> > My experiments in this area have shown that the specification doesn’t
> need
> > to change, but that there are user-visible changes when doing this (ie:
> > Class:getNestMembers and others). Is there an intention to document the
> > user visible aspects of changes from Condensers?
>
> To the extent that a condenser changes the behavior of a program within
> the bounds of the (possibly enhanced) Platform Specification then yes,
> we should document those changes.
>
Ok. So user visible changes are in bounds for condensers provided they're
well documented. Good!
>
> >> Others will definitely require specification changes, e.g., resolving
> classes
> >> prior to run time. Yet others will take the form of new platform
> features
> >> that allow developers to express temporal shifting directly in source
> code,
> >> e.g., lazy static final fields.
> >
> > Glad to hear that language changes are in the scope of this proposal.
> > Helping developers say what they mean makes it easier to reason about
> what
> > needs to change versus trying to impose new semantics on top of the soup
> > that is <clinit>.
>
> Indeed! Applying new semantics to existing code always leads to tears.
>
> >> So let’s generalize, and allow an arbitrary number of phases in which
> >> time-shifting transformations and related optimizations can be applied.
> >
> > To confirm: this is saying that a “condensed” Java application may act as
> > an input to a later phase of “condensation”?
>
> Yes, for some but likely not all definitions of “condensed.” If you’ve
> condensed all the way down to a platform-specific executable, e.g., then
> it’s likely not worth the effort for us to support further condensation.
> (I suspect it’ll be acceptable to consider condensation to such formats
> to be terminal steps, as you suggest above.)
>
A CRIU-based checkpoint is another such potential terminal format. We're
on the same page that not all condensation has to happen in one go - it's
valid to have multiple kicks at the can provided a previous attempt wasn't
terminal.
>
> >> Condensation is meaning preserving.
> >
> > Have you given thought to precisely specifying and then validating this
> > property? It’s definitely something we want but it may be challenging to
> > enforce….
>
> The meaning of a Java program is already given by the Specification, and
> the JCK already validates a Java implementation by running a large
> collection of Specification-derived tests. My initial thought here is
> to extend the JCK to test a condenser by applying the condenser to each
> JCK test and then verifying that the condensed test still passes. (To
> keep JCK run times tractable, do this in large batches.)
>
That's a great starting point. I hadn't considered using the JCKs in that
way.
The devil will be in the details as there will be conflicts between the
condenser's changes (make this module unmodifiable) and the test's
expectations (redefine class X). This approach also feels a bit weighted
toward the end - a condenser can be developed, merged, and only later be
discovered to conflict with the JCKs. I've been trying to think of ways to
bring this forward in the development process and to make it more open but
the answer may be as it is today - lots of jtregs, clearly written specs,
and the final check is done by the JCKs.
Let us know if there are ways others can help with validating the behaviour
of condensers when running the JCKs.
>
> >> To ensure that condensers run code correctly, and transform and
> constrain
> >> code only in ways that preserve meaning, we must add the concept of
> >> condensers to the Java Platform Specification.
> >
> > I’m unclear reading this if the set of Condensers will be limited to what
> > an implementation chooses to provide or if others (frameworks) can
> provide
> > their own Condensers as well?
>
> (See above.)
>
> > Currently, implementing a jlink plugin from outside the platform is a
> pain
> > (though possible with enough –add-opens and reflective hacks) but I’d
> > prefer to see Condensers have a more supported api so the ecosystem can
> > extend the concept.
>
> Agreed. We probably do want an open condenser API, though designing a
> good one will take considerable effort. (We didn’t open the jlink
> plugin API because we knew that it wasn’t ready.)
>
+1. Sounds like we're in the same ballpark on this.
>
> >> We can, however, enable other Java implementations (e.g., some future
> version
> >> of the GraalVM native-image tool) to do so.
> >
> > This is prescient given the recent announcement that Graal CE is moving
> to
> > OpenJDK =)
>
> What a coincidence!
>
> >> Eliminate apparently-unused classes and class members (i.e., stripping,
> which
> >> requires the constraint that selected classes and members cannot be
> reflected
> >> upon)
> >
> > Being slightly pedantic, it means the removed members can’t be reflected
> > on, correct?
>
> Yes, but ...
>
> > A class that’s been stripped of unused methods / fields can
> > still have its remaining members reflectively looked up is my assumption.
>
> That’s a reasonable assumption.
>
> In detail, though, we could in principle retain reflective metadata even
> for removed program elements, if there’s a need to do so. We could,
> likewise, remove reflective metadata for some retained program elements
> if we’re confident that those elements will never be reflected upon.
> More exploration required ...
>
That makes sense. If I'm following that correctly, we can mark some
classes as "reflection hostile" and others as supporting reflection of all
members (even the removed ones). What I'm really hearing is a willingness
to completely change the model so users can make different tradeoffs. Very
excited by this approach!
>
> >> jlink
> >
> > Using jlink is the natural starting point for this work. It would be
> > unfortunate if condensers were limited to only work on modules given the
> > (unfortunately) slow update of them. Is the intention to extend jlink to
> > work with classpath entities (ie: non-modular code) as well? We foresee
> > the need for condensers to be able to “condense” non-modules as well.
>
> The jlink tool doesn’t support arbitrary class path code, or automatic
> modules, in order to guarantee that the resulting image is structurally
> correct by construction. I’m reluctant to give up on that guarantee.
> Viable workarounds exist for non-modular code (jdeps, ModiTect, etc.),
> so developers who want to risk building a potentially-broken image from
> a potentially-broken class path can do so, at their option.
>
Libraries are always the challenge here. Modularizing before your
dependencies is difficult and while Leyden may help drive modularization in
the ecosystem (a plus!), I hope we can take a pragmatic approach and bring
class path code into Leyden fold. As you said above, lot's to explore here
but I ask that we add an explicit goal to bring class path code in as much
as we can.
>
> I do expect that, in Leyden, we’ll find interesting ways to leverage the
> constraints already imposed by modules. Hopefully that will motivate
> the further adoption of modules.
>
> > We’re excited to start working with you on this approach. When do you
> > think we’d be ready to create a Leyden repo and start developing the code
> > for this approach?
>
> I’m in the process of setting up a repo; more on that soon.
>
> - Mark
Thanks Mark!
--Dan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20221107/1c5c6e29/attachment.htm>
More information about the leyden-dev
mailing list