<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial, Helvetica, sans-serif;font-size:9pt" ><div dir="ltr" style="font-family:Arial, Helvetica, sans-serif;font-size:9pt" ><div dir="ltr" ><div dir="ltr" ><div dir="ltr" ><div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >Thanks for writing this up Brian.  It clearly lists a number of the problematic areas that were identified as potentially needing re-validation.</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >The key questions are around the mental model of what we're trying to accomplish and how to make it easy (easier?) for users to migrate to use value types or handle when their pre-value code is passed a valuetype.  There's a cost for some group of users regardless of how we address each of these issues.  Who pays these costs?  Those migrating to use the new value types functionality?  Those needing to address the performance costs of migrating to a values capable runtime (JDK-N?).</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >One concern writ large across our response is performance.  I know we're looking at user model here but performance is part of that model.  Java has a well understood performance model for array access, == (acmp), and it would be unfortunate if we damaged that model significantly when introducing value types.</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >Is this a fair statement of the projects goals: to improve memory locality in Java by introducing flattenable data?  The rest of where we've gotten to has been working all the threads of that key desire through the rest of the java platform.  The L/Q world design has come about from starting from a VM perspective based on what's implementable in ways that allows the JVM to optimize the layout.</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >One of the other driving factors has been the desire to have valuetypes work with existing collections classes.  And a further goal of enabling generic specialization to allow those collections to get the benefits of the flattened data representations (ie: backed by flattened data arrays).</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >You made an important point when talking the ValObject / RefObject split - "This is probably what we'd have done if values had always been part of the Java platform".  I think we need to ask that same question about some of the other proposals and really look at if they're the choices we'd be making if values had always been part of the platform.</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >The other goal we discussed in Burlington was that pre-value code should be minimally penalized when values are introduced, especially for code that isn't using them.  Otherwise, it will be a hard sell for users to take a new JDK release that regresses their existing code.</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >Does that accurate sum up the goals we've been aiming for?</div>
<div dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<blockquote data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" > 
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >I’ve been processing the discussions at the Burlington meeting.  While I think we made a lot of progress, I think we fell into a few wishful-thinking traps with regard to the object model that we are exposing to users.  What follows is what I think is the natural conclusion of the L-World design — which is a model I think users can love, but requires us to go a little farther in what the VM does to support it.<br><br><snip><br><br>A sensible rationalization of the object model for L-World would be to<br>have special subclasses of `Object` for references and values:<br><br>```<br>class Object { ... }<br>class RefObject extends Object { ... }<br>class ValObject extends Object { ... }<br>```</font><br> </div></blockquote>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" ><font face="Default Monospace,Courier New,Courier,monospace" size="2" ><font face="Arial, Helvetica, sans-serif" ><span style="font-size: 9pt;" >Would the intention here be to retcon existing Object subclasses to instead subclass RefObject?  While this is arguable the type hierarchy </span></font><font face="Arial, Helvetica, sans-serif" ><span style="font-size: 9pt;" >we'd have if creating Java today, it will require additional speculation from the JIT on all Object references in the bytecode to bias the code one way or the other.  Some extra checks plus a potential performance cliff if the speculation is wrong and a single valuetype hits a previous RefObject only callsite.</span></font></font></div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" ><font face="Default Monospace,Courier New,Courier,monospace" size="2" ><font face="Arial, Helvetica, sans-serif" ><span style="font-size: 9pt;" >How magic would these classes be in the VM?  Would things like jvmti's classfile load hook be sent for them?  Adding fields to Object or ValObject would grow all the ValueTypes loaded which would be expensive for the sweet spot of small values.</span></font></font></div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >We can pull the same move with nullability, by declaring an interface<br>`Nullable`:<br><br>```<br>interface Nullable { }<br>```<br><br>which is implemented by `RefObject`, and, if we support value classes<br>being declared as nullable, would be implemented by those value<br>classes as well.  Again, this allows us to use `Nullable` as a<br>parameter type or field type, or as a type bound (`<T extends<br>Nullable>`).  </font></div></blockquote>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >I'm still unclear on the nullability story.  None of the options previously discussed (memcmp to ensure its all 0, some pivot field, a special bit pattern, did I miss any?) are particularly attractive and all come with different levels of costs. Even the vulls? (convert "null value" to null reference on the stack) story has additional costs and complexity that leak throughout the system - ie: the gc will need to know about the null check to know whether to mark / update / copy the reference fields of the value type - and have knock-on affects to the equality discussion below.</div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >Which model of nullability would map to this interface?</div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" >Do nullable values help meet the primary (flattenable data) or secondary goals (interop with collections)?  While they may help the second goal, I think they fail the first one.  Gaining collections at the cost of flattenability suggests we've missed our design center here.</div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >## Totality<br><br>The biggest pain point in the LW1 model is that we're saying that<br>everything is an `Object`, but we've had to distort the rules of<br>`Object` operations in ways that users might find confusing.  LW1 says<br>that equality comparison, identity hash code, locking, and<br>`Object::wait` are effectively partial, but existing code that deals<br>in `Object` may be surprised to find this out.  Additionally, arrays<br>of reference objects are covariant with `Object`, but arrays of value<br>objects are currently not.  <br><br>#### Equality<br><br>The biggest and most important challenge is assigning sensible total<br>semantics to equality on `Object`; the LW1 equality semantics are<br>sound, but not intuitive.  There's no way we can explain why for<br>values, you don't get `v == v` in a way that people will say "oh, that<br>makes sense."  If everything is an object, `==` should be a reasonable<br>equality relation on objects.  This leads us to a somewhat painful<br>shift in the semantics of equality, but once we accept that pain, I<br>think things look a lot better.<br><br>Users will expect (100% reasonably) the following to work:<br><br>```<br>Point p1, p2;<br><br>p1 == p1  // true<br><br>p2 = p1<br>p1 == p2  // true<br><br>Object o1 = p1, o2 = p2;<br><br>o1 == o1  // true<br>o1 == o2  // true<br>```</font></div></blockquote>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" ><font face="Default Monospace,Courier New,Courier,monospace" size="2" >We ran into this problem with PackedObjects which allowed creating multiple "detached" object headers that could refer to the same data.  While early users found this painful, it was usually a sign they had deeper problems in their code & understanding.  One of the difficulties was that depending on how the PackedObjects code was written, == might be true in some cases.  We found a consistent answer was better - and helped to define the user model.</font></div>
<div style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt;" > </div>
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" ><font face="Arial, Helvetica, sans-serif" ><span style="font-size: 9pt;" >In terms of values, is this really the model we want?  Users are already used to needing to call .equals() on equivalent objects.  By choosing the answer carefully here, we help to guide the right user mental model for some of the other proposals - locking being a key one.</span></font><font face="Arial, Helvetica, sans-serif" ><span style="font-size: 9pt;" > </span></font></font></div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >In LW1, if we map `==` to `ACMP`, they do not, and this will violate<br>both user intuition and the spirit of "everything is an object".  (If<br>everything is an object, then when we assign `o1 = p1`, this is just a<br>widening conversion, not a boxing conversion -- it's the same<br>underlying object, just with a new static type, so it should behave<br>the same.)<br><br>The crux of the matter is that interfaces, and `Object` (which for<br>purposes of this document should be considered an honorary interface)<br>can hold either a reference or a value, but we've not yet upgraded our<br>notion of interfaces to reflect this kind-polymorphism.  This is what<br>we have to put on a sounder footing in order to not have users fall<br>into the chasm of anomalies.  To start with:<br><br>  - A class is either a ref class or a value class.<br>  - `C implements I` means that instances of `C` are instances of `I`.<br>  - Interfaces are polymorphic over value and ref classes.<br><br>Now we need to define equality.  The terminology is messy, as so many<br>of the terms we might want to use (object, value, instance) already<br>have associations. For now, we'll describe a _substitutability_<br>predicate on two instances:<br><br>  - Two refs are substitutable if they refer to the same object<br>    identity.<br>  - Two primitives are substitutable if they are `==` (modulo special<br>    pleading for `NaN` -- see `Float::equals` and `Double::equals`).  <br>  - Two values `a` and `b` are substitutable if they are of the same<br>    type, and for each of the fields `f` of that type, `a.f` and `b.f`<br>    are substitutable.  <br><br>We then say that for any two objects, `a == b` iff a and b are<br>substitutable.  <br><br>This is an "everything is an object" story that users can love!<br>Everything is an object, equality is total and intuitive on objects,<br>interfaces play nicely -— and there are no pesky boxes (except for<br>primitives, but see below.)  The new concept here is that interfaces<br>abstract over refs and values, and therefore operations that we want<br>to be total on interfaces -- like equality -- have to take this seam<br>into account.<br><br>The costs come in two lumps.  The first is that if we're comparing two<br>objects, we first have to determine whether they are refs or values,<br>and do something different for each.  We already paid this cost in<br>LW1,  but here comes the bigger cost: if a value class has fields<br>whose static types are interfaces, the comparison may have to recur on<br>substitutability. This is horrifying for a VM engineer, but for users,<br>this is just a day at the office -- `equals` comparisons routinely<br>recur.  (For values known to (recursively) have no interface fields<br>and no floating point fields, the VM can optimize comparison to a flat<br>bitwise comparison.)</font></div>
<div> </div></blockquote>
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >While the conceptual model may be clean, it's also, as you point out, horrifying.  Trees and linked structures of values become very very expensive to acmp in ways users wouldn't expect.</font></div>
<div> </div>
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >If we do this, users will build the mental model that values are interned and that they are merely fetching the same instances from some pool of values.  This kind of model will lead them down rabbit holes - and seems to give values an identity.  We've all seen abuses of String.intern() - do we want values to be subject to that kind of code?</font></div>
<div> </div>
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >The costs here are likely quite large - all objects that might be values need to be checked, all interfaces that have ever had a value implement them, and of course, all value type fields plus whatever the Nullability model ends up being.</font></div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >#### Identity hash code<br><br>Because values have no identity, in LW1 `System::identityHashCode`<br>throws `UnsupportedOperationException`.  However, this is<br>unnecessarily harsh; for values, `identityHashCode` could simply<br>return `hashCode`.  This would enable classes like `IdentityHashMap`<br>(used by serialization frameworks) to accept values without<br>modification, with reasonable semantics -- two objects would be deemed<br>the same if they are `==`.  (For serialization, this means that equal<br>values would be interned in the stream, which is probably what is<br>wanted.)</font></div></blockquote>
<div> </div>
<div>By return `hashCode`, do you mean call a user defined hashCode function?  Would the VM enforce that all values must implement `hashCode()`?  Is the intention they are stored (growing the size of the flattened values) or would calling the hashcode() method each time be sufficient?</div>
<div> </div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >#### Locking<br><br>Locking is a difficult one.  On the one hand, it's bad form to lock on<br>an object that hasn't explicitly invited you to participate in its<br>locking protocol.  On the other hand, there is likely code out there<br>that does things like lock on client objects, which might expect at<br>least exclusion with other code that locks the same object, and a<br>_happens-before_ edge between the release and the acquire.  Having<br>locking all of a sudden throw `IllegalMonitorStateException` would<br>break such code; while we may secretly root for such code to be<br>broken, the reality is that such code is likely at the heart of large<br>legacy systems that are difficult to modify.  So we may well be forced<br>into totalizing locking in some way.  (Totalizing locking also means<br>totalizing the `Object` methods related to locking, `wait`, `notify`,<br>and `notifyAll`.)<br><br>There are a spectrum of interpretations for totalizing locking, each<br>with different tradeoffs:<br><br> - Treat locking on a value as an entirely local operation, providing<br>   no exclusion and no happens-before edge.  Existing code will<br>   continue to run when provided with values, but may produce<br>   unexpected results.  <br> - Alternately, treat locking on a value as providing no exclusion,<br>   but with acquire and release semantics.)  Wait and notify would<br>   still throw.  <br> - Treat locking on a value as acquiring a fat lock (say, a global<br>   value lock, a per-type value lock, etc.)  This gives us exclusion<br>   and visibility, with a small risk of deadlock in situations where<br>   multiple such locks are held, and a sensible semantics for wait<br>   and notify (single notify would have to be promoted to `notifyAll`).<br> - Treat locking on a value as acquiring a proxy lock which is<br>   inflated by the runtime, which assigns a unique lock to each<br>   distinguishable value.<br> - Put lock-related methods on `ValObject`, whose defaults do one of<br>   the above, and allow implementations to override them.  </font></div></blockquote>
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >Note, lock methods on ValObject doesn't cover monitor{enter,exit}.</font></div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >While nearly all of these options are horrifying, the goal here is<br>not to do something _good_, but merely to do something _good enough_<br>to avoid crushing legacy code.  </font><br> </div></blockquote>
<div>The only consistent answer here is to throw on lock operations for values.  Anything else hides incorrect code, makes it harder for users to debug issues, and leaves a mess for the VM.  As values are immutable, the lock isn't protecting anything.  Code locking on unknown objects is fundamentally broken - any semantics we give it comes at a cost and doesn't actually serve users.</div>
<div> </div>
<div>By saying no to ==, we can avoid this problem as well as it becomes clear that you won't have the identical value in hand to lock on.</div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >#### Array covariance<br><br>Currently, for any class `C`, `C[] <: Object[]`.  This makes<br>`Object[]` the "top array type".  If everything is an object, then an<br>array of anything should also be an array of `Object`.  <br><br>There are two paths to delivering on this vision: extend traditional<br>array covariance to value arrays (potentially making `aaload` sites<br>megamorphic), or moving in the direction of "Arrays 2.0" and  define a<br>specializable generic type `Array<T>` where the legacy arrays<br>implement  `Array<T>`, and require clients to migrate from `T[]` to<br>`Array<T>` before specializing their generic classes.</font></div></blockquote>
<div>I've raised the performance concerns around this previously.  There's also some knock on effects here:</div>
<div>- additional code cache usage</div>
<div>- longer compiles due to extra work to constrain objects / interfaces to prove whether they are values or not</div>
<div>- performance cliffs when speculation is wrong</div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div> </div>
<div><br><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >## Poxing</font><br> </div></blockquote>
<div>Note, checkcast doesn't return anything so conversions can't be done in checkcast.</div>
<div> </div>
<blockquote class="history-quote-1547658468826" data-history-content-modified="1" data-history-expanded="1" dir="ltr" style="font-family: Arial, Helvetica, sans-serif; font-size: 9pt; border-left-width: 2px; border-left-style: solid; border-left-color: rgb(170, 170, 170); margin-left: 5px; padding-left: 5px; direction: ltr; margin-right: 0px;" ><div><br><font face="Default Monospace,Courier New,Courier,monospace" size="2" >## Migration<br><br>In both Q-world and L-world, we took care to ensure that for a value<br>class `C`, the descriptor `LC;` describes a subtype of `Object`.  This<br>is a key part of the story for migrating reference types to values,<br>since clients of `C` will describe it with `LC;` and we don't want to<br>require a flag day on migration.  In Q-world, `LC;` is the (nullable)<br>box for `C`; in L-world, it is a nullable `C`.  <br><br>This is enough that we can migrate a value-based class to a value and<br>_existing binary clients_ will not break, even if they stuff a null<br>into an `LC;`.  However, there are other migration compatibility<br>concerns which we need to take up (which I'll do in a separate<br>document.)</font><br> </div></blockquote>
<div> </div>
<div>Asking the same question from ValObject/RefObject - are these choices the model we'd pick if designing Java from scratch today?  Does this model provide the flattened data performance the project is targeting?  And are the costs to non-value code reasonable?</div>
<div> </div>
<div>--Dan</div>
<div> </div></div></div></div></div></div><BR>