<div dir="ltr">Hi John,<div>Glad to see you bring up constructive classes again, a proposal I wholeheartedly love!</div><div>For those who don't know, John published two essay in his code review FTP (also home to other outstanding essays):</div><div><a href="https://cr.openjdk.org/~jrose/jvm/eager-super-init.html" target="_blank">https://cr.openjdk.org/~jrose/jvm/eager-super-init.html</a> - Safe construction, making final fields trusted, behaving like current @Stable or static/hidden/record finals (works well with leyden's (computed) constants)<br></div><div><a href="https://cr.openjdk.org/~jrose/jls/constructive-classes.html" target="_blank">https://cr.openjdk.org/~jrose/jls/constructive-classes.html</a> - Constructive classes in Java programming language, fixing long-standing discrepancy between normal final fields and inner class enclosing instance field (which is written before super constructor call in bytecode)</div><div><br></div><div>And it seems you have already considered the possibility of inlining such "rejecting initial value" fields in this slide (<a href="https://cr.openjdk.org/~jrose/values/field-initializations.pdf" target="_blank">https://cr.openjdk.org/~jrose/values/field-initializations.pdf</a>) even though I am not aware of its exact context. Would you mind sharing more behind-the-scenes details?</div><div><br></div><div>Question: what do STM and HTM stand for? Unfortunately I am not that familiar with hardware, and "doubly-periodic arrays" is also enigmatic to me (I can't find anything from online searches). I hope you can give me some references on these.</div><div><br></div><div>Also a few general remarks:</div><div>1. The Valhalla research and development has benefitted mainline JDK again. Even though the "constructive classes" was initially an innovation to prevent creating new bytecode sequences that breaks compatibility with the existing new-dup-<init>, it now allows regular Java classes to have more safety with their final fields and removed the long-standing weirdness of having inner classes initialize their outer instance before super call; the same happened back in JDK 11 when NestHost and NestMember were added, which I recall was designed for creating subclasses for generic specialization, but it removed all $accessor$0s generated by javac to access inner class private members, boosting performance and reducing class file sizes.</div><div>2. Currently our value class is quite restrictive (no field in abstract values, only null-restricted fields for zero-default value classes, etc) but they are futureproof, as these capabilities can be expanded (algebraic types with sealed, initialization-guard for final fields that reject default values) without hurting backward compatibility. Love this way of enhancement.</div><div><br></div><div>Chen</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jan 21, 2024 at 5:13 AM Remi Forax <<a href="mailto:forax@univ-mlv.fr" target="_blank">forax@univ-mlv.fr</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">----- Original Message -----<br>
> From: "John Rose" <<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a>><br>
> To: "-" <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>><br>
> Cc: "Brian Goetz" <<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>>, "David Alayachew" <<a href="mailto:davidalayachew@gmail.com" target="_blank">davidalayachew@gmail.com</a>>, "Smith Wilson"<br>
> <<a href="mailto:wilsons2401@outlook.com" target="_blank">wilsons2401@outlook.com</a>>, "valhalla-dev" <<a href="mailto:valhalla-dev@openjdk.org" target="_blank">valhalla-dev@openjdk.org</a>><br>
> Sent: Sunday, January 21, 2024 7:10:08 AM<br>
> Subject: Re: Value types design decisions<br>
<br>
> On 20 Jan 2024, at 21:20, - wrote:<br>
> <br>
>> Hi Brian, from your description of LocalDate![] comes a contingent question:<br>
>> Can (non-implicitly constructable) classes now have null-restricted<br>
>> (inlined) fields of types that are not implicitly constructable, given<br>
>> these fields will be initialized by the constructors to valid values? I<br>
>> assume any assignment of invalid values (notably, null) will simply result<br>
>> in exceptions such as NPE.<br>
>><br>
>> If yes, how will such fields be represented in heap as:<br>
>> 1. identity object's final fields?<br>
>> 2. identity object's mutable fields?<br>
>> 3. non-implicitly constructable value object's final fields?<br>
>><br>
>> Given these fields can have their proper states visible no later than their<br>
>> owner objects are visible.<br>
>><br>
>> I think this is a new aspect of inlining that hasn't yet been discussed,<br>
>> but is probably worth discussing.<br>
>><br>
> <br>
> That is well spotted.  As Brian said, “Stay tuned”.  Here is a teaser:<br>
> <br>
> <a href="https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-December/002400.html" rel="noreferrer" target="_blank">https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-December/002400.html</a><br>
> <br>
> You are right to imply that the implementation options are likely to differ for<br>
> immutable and mutable fields (and sub-fields of values).<br>
> <br>
> As a result of certain conversations last summer at JMVLS, our design for<br>
> Valhalla got simpler, because value and identity objects use more similar code<br>
> shapes for their construction.  That gave us a better logical framework for<br>
> thinking about problems and requirements of guaranteed field initialization,<br>
> the results of which will come out shortly.<br>
> <br>
> The basic insight is, if you can prove a field is initialized, you can tolerate<br>
> an abstraction-breaking initial value.  The fun problem is building out the<br>
> framework for making the necessary proofs, at the right levels in the stack.<br>
> <br>
> For mutable fields there is an additional problem, of course, of ensuring that<br>
> races (on a field of type V! or V) cannot expose values that the author of V<br>
> has deemed private to V.  (Allowing V to opt out of atomicity makes the VM’s<br>
> job easier.)  Once the initialization problem is solved, it is easier to attack<br>
> the “safe mutation” problem, with or without an atomicity requirement.  All of<br>
> this stuff will happen “under the hood”.<br>
> <br>
> As Brian says, once the semantics are nailed down, then the optimizations can<br>
> start to show up.  Once the rules are set properly, the games can begin.  (I’m<br>
> talking about the VM implementation games, the kind of games I like best.)<br>
> <br>
> I expect to see a long line of VM optimizations arise in the future after<br>
> Valhalla, to flatten more and more value types, as optimizations get more<br>
> clever and hardware gets more capable.  My concern for this year is to get the<br>
> semantic rules into the right shape (for both language and VM).  That way the<br>
> best optimizations are possible in the future.<br>
> <br>
> Examples of possible future stuff:  Research on STM and HTM might be “mined” for<br>
> potential candidates to optimize flat, mutable data.  There are clever “cache<br>
> friendly” and “lock free” algorithms that might be applicable.  I have a<br>
> handful of pet ideas…  One is doubly-periodic arrays, where each array “card”<br>
> has N payloads and N null bits (or N big fields and N little fields; N might be<br>
> 7) but they are allocated column-style (within the card) instead of row-style<br>
> (which is what we do to day in the Valhalla prototype).  The card size is tuned<br>
> to the cache line size, of course.  The indexing arithmetic is surprisingly<br>
> clean, once you work it out.<br>
<br>
<br>
Another big area we have left on the side is the flattening of sealed (implicit or explicit) hierarchy of value types.<br>
<br>
> <br>
> — John<br>
<br>
Rémi<br>
</blockquote></div>