From heidinga at redhat.com Mon Nov 7 15:57:50 2022 From: heidinga at redhat.com (Dan Heidinga) Date: Mon, 7 Nov 2022 10:57:50 -0500 Subject: Selectively Shifting and Constraining Computation In-Reply-To: <20221027172839.945357016@eggemoggin.niobe.net> References: <20221013105630.787752083@eggemoggin.niobe.net> <20221027172839.945357016@eggemoggin.niobe.net> Message-ID: On Thu, Oct 27, 2022 at 8:28 PM Mark Reinhold wrote: > 2022/10/21 19:49:36 -0700, Dan Heidinga : > > 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 . > > 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: From heidinga at redhat.com Mon Nov 14 14:58:35 2022 From: heidinga at redhat.com (Dan Heidinga) Date: Mon, 14 Nov 2022 09:58:35 -0500 Subject: Lazy statics (was: Re: Selectively Shifting and Constraining Computation) In-Reply-To: <9A1EF932-96AE-455B-B50B-BB7ED7C6CCD8@oracle.com> References: <20221013105630.787752083@eggemoggin.niobe.net> <1690520167.25120630.1665686609004.JavaMail.zimbra@u-pem.fr> <20221013120424.298245311@eggemoggin.niobe.net> <78C8DA0A-FB04-46F2-9512-255F31B775EB@oracle.com> <15CF9BD7-D9F3-44C8-9BA8-E1B07AD5217F@oracle.com> <381835350.31599386.1666418214406.JavaMail.zimbra@u-pem.fr> <9A1EF932-96AE-455B-B50B-BB7ED7C6CCD8@oracle.com> Message-ID: John, nice write up on the Lazy static finals JEP. Reading the JEP I was curious about one of the restrictions - the need for the static field to be "final". There's a clear transformation from the IODH pattern to a static final field that's appealing and finals allow for better optimization so it's an obvious first target. The semantics in the JEP though seem like they would work equally well for non-final static fields as well. Users can already implement this themselves today due to the mutability of the field, but I can see a benefit to allowing users to specify a lazy initializer for mutable fields as well. Is extending it to all static fields (both final and non-final) a potential follow on to this work? --Dan On Mon, Oct 24, 2022 at 8:39 PM John Rose wrote: > On 21 Oct 2022, at 22:56, forax at univ-mlv.fr wrote: > > > I'm a great fan of the lazy statics, but you do not only get reordering > of the side effects, you may also get double executions of the > initialization code, double executions of the side effects. > > So the constraint on the side effects when initializing a lazy static is > quite radical, do not do them . > > I think you are referring to the draft semantics of lazies which > piggy-back on top of CONSTANT_Dynamic, which indeed allows initialization > races and therefore double side effects. I?m getting rid of this in the > newest draft of the JEP, so that refactoring to lazy will be easier to say > ?yes? to. > > A lazy static should never double its initializer, regardless of > init-races. My current plan is to insist that the same class locking be > done for each lazy init as for itself (which is the big lazy init > of the overall class). And on the same CL object mentioned in JVMS 5.5. > > Also, errors in lazy inits will be recorded as > ExceptionInInitializerError, not BootstrapMethodError. Both effects > require some subtle tweaking of the bootstrapping of lazies, which I?m > working on? > > I just updated the JEP to reflect this: > https://bugs.openjdk.org/browse/JDK-8209964 > > There?s a new section on translation strategy. It hints at adjustments to > the BSM protocol, which I?m currently investigating. The basic idea there > is that a BSM can ask that the JVM pass it exactly one argument, which > reifies the entire state of the relevant condy entry, and allows the BSM to > update that state appropriately as it arbitrates error and race conditions. > > See also a slide deck mentioned in the comments. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: