<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"Brian Goetz" <brian.goetz@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr>, "valhalla-spec-experts" <valhalla-spec-experts@openjdk.java.net><br><b>Cc: </b>"daniel smith" <daniel.smith@oracle.com>, "valhalla-spec-experts" <valhalla-spec-experts@openjdk.java.net><br><b>Sent: </b>Tuesday, June 14, 2022 3:16:41 PM<br><b>Subject: </b>Re: User model stacking: current status<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
<blockquote cite="mid:187309785.7141993.1655190785532.JavaMail.zimbra@u-pem.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size:
12pt; color: #000000">
<div>
</div></div></blockquote></blockquote><div><br data-mce-bogus="1"></div><div>[...]<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
<br>
<blockquote cite="mid:187309785.7141993.1655190785532.JavaMail.zimbra@u-pem.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size:
12pt; color: #000000">
<div>
<div><br>
</div>
<blockquote style="border-left:2px solid
#1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><font size="4"><font face="monospace"><br>
Summary:<br><br>
class B1 { }<br></font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace"> value class B2 {
private class val { } }<br></font></font> value class B3a { }<br></font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace"> non-atomic value
class B3n { }<br></font></font><br>
Value class here is clearly the star of the show; all
value classes are treated uniformly (ref-default, have a
val); some value classes encapsulate the val type; some
value classes further relax the integrity requirements
of instances on the heap, to get better flattening and
performance, when their semantics don't require it.<br><br>
It's an orthogonal choice whether the default is "val is
private" and "val is public". </font></font></blockquote>
<div><br>
</div>
<div>It makes B2.val a reality, but B3 has no sane default
value otherwise it's a B3, so B2.val should not exist.<br>
</div>
<div><br>
</div>
</div>
</div>
</blockquote>
<br>
Let me try explaining again. <br>
<br>
All value types have .ref and .val types. They have the properties
we've been discussing for a long time: ref types are references, and
are therefore nullable and atomic; val types are direct values, are
not nullable, and are _not necessarily_ atomic. <br>
<br>
We've been describing B2 classes as those with "no good default",
but that doesn't mean that they can't have a .val type. It means we
*can't trust arbitrary code to properly initialize a B2.val type.*
Once initialized, B2.val is fine, and have the benefit of greater
flatness. We explored language and VM features to ensure B2.val
types are properly initialized, but that ran into the rocks. <br>
<br>
But we can allow the B2 class itself to mediate access to the .val
type. This has two benefits:<br>
<br>
- We can get back some of the benefit of flattening B2.val types<br>
- Uniformity<br>
<br>
Here are two examples of where a B2 class could safely and
beneficially use B2.val:<br>
<br>
<font face="monospace"> value class Rational { <br>
Rational[] harmonicSeq(int n) { <br>
Rational.val[] rs = new Rational.val[n];<br>
for (int i=0; i<n; i++)<br>
rs[i] = new Rational(1, n);<br>
return rs;<br>
}<br>
}<br><br>
Here, we've made a _flat_ array of Rational.val, properly
initialized it, and returned it to the user. THe user gets the
benefit of flatness, but can't screw it up, because of the array
store check. If Rational.val were illegal, then no array of
rationals could be flat. </font></blockquote><div><br></div><div>but you are leaking Rational.val as the class of the array, so one can write<br data-mce-bogus="1"></div><div> var array = Rational.<span style="font-family: monospace;">harmonicSeq(3);</span><span style="font-family: monospace;"></span></div><div><span style="font-family: monospace;"> var array2 = Arrays.copyOf(array, array.length + 1);<br data-mce-bogus="1"></span></div><div><span style="font-family: monospace;"> var defaultValue = array2[array2.length - 1];<br data-mce-bogus="1"></span></div><div><br data-mce-bogus="1"></div><div>Currently we live in a world where apart of using jdk.unsupported, there is no way to get an uninitialized object even by reflection,</div><div>you propose to shatter that idea and to allow to bypass the constructor and have access to the default value directly in the language.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>I think it may be reasonable to allow access to Rational.val through a specific reflection API but it means disallowing some methods like Arrays.copyOf() and add more like createAValueArrayFromAnExistingRefArray(), but accessing directly to B2.val is just a big security hole.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><font face="monospace"><br>
Similarly, a nestmate could take advantage of packing:<br><br>
value class Complex { <br>
value class C3 { <br>
Complex.val x, y, z;<br><br>
...<br>
}<br><br>
C3 c3(Complex x, Complex y, Complex z) { return new C3(x,
y, z); }<br></font><br>
}<br>
<br>
C3 gets the benefit of full flattening, which it can do because its
in the nest; it can share the flattened instances safely with code
outside the nest. <br>
<br>
(Access control is powerful thing.)</blockquote><div><br></div><div>and it's hard to get it right.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>regards,<br data-mce-bogus="1"></div><div>RĂ©mi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div></div></div></body></html>