What we have lost ?

Paul Sandoz paul.sandoz at oracle.com
Wed Sep 7 23:10:26 UTC 2022


The Vector API is I think a proof point that ref projection can be acceptable and can work.

The Vector API implementation currently behaves approximately as if a vector instance (whose concrete class is private) is a ref to a value object. The C2 compiler performs aggressive unboxing and mapping "payloads" (analogous to value objects) vectors hold to vector registers, rather than scalarizing the element “overlay” or view over the payload described by the vector’s shape and element type (the species).

In this current model we generally don’t recommend storing vector instances in the heap (there are exceptions to that rule for constants), and instead vectors are loaded from or stored to memory containers such as arrays, byte buffers, or memory segments. After a few iterations of the API and implementation its starting to work rather well at generating efficient vectorized code on supporting hardware.


We are currently early in the process of exploring alignment of the Vector API with Valhalla where:

1. the private concrete vector classes are value classes whose .val type is private; and 
2. a vector value class has a "payload" field whose type is a value type.

The "payload" is a non-atomic "bag of bits" e.g. values types of Bits256.val, Bits128.val etc, which would not be exposed in the public Vector API. So no utterance of .val is expected in this model. The API remains the same as it does today.

We could decide the value classes of those “bag of bits” could be public classes, and developers may interact with those using the .val. Unsure yet. As we explore and learn more the approach could change. I hope the exploration will be informative.

Paul.



> On Sep 7, 2022, at 2:27 PM, forax at univ-mlv.fr wrote:
> 
> 
> 
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>, "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Sent: Wednesday, September 7, 2022 8:38:46 PM
> Subject: Re: What we have lost ?
> I would summarize this mail as "no new observations, but growing discomfort with ref-as-default."  All of these points amount to "there are classes for which most uses will prefer val to varying degrees, but users may forget to say .val / avoid saying .val because it is clunky", which may turn into performance potholes.  These are surely known, so I will take this as Remi worrying that this will be a bigger and more persistent irritant than we think.
> 
> If we take a step back, one of the main reason of introducing value types is to have a way to be closer to the actual CPU architecture which can also be described as solving Java performance potholes.
> So i think we should shy away that term.
> 
> Dan help us to categorize the different issues,
> - singleton types and vector representing SIMD registers are similar cases where using the ref projection is far worst than the val projection, to the point where author of those classes may prefer to not have a ref projection.
>   In the case of an empty value class, storing the val projection use no memory, so the difference in term of the behavior is big,
>   In the case of a SIMD register, if the VM loose track of the creation of something which is typed as the reference projection, a nullcheck will to be emitted, while usually we don't care about the cost of a nullcheck, having a supplementary nullcheck in a thigh loop is a far bigger issue to the point where having a reference projection for such types is counter productive.
> 
> - Atomic (or any class that play the role of a modifier like Stable, etc) is when the ref projection have the wrong semantics so should not exist and there is no need for a lightweight boxing given that you can always extract the value from the monad (and use its reference projection if necessary).
> 
> - the last case is a case where the way the value classes are defined in Scala/Kotlin can not be retrofitted to use the VM value classes because getClass() always returns the class of the ref projection. This is also a case where those value classes should not have a ref projection.
> 
> 
> (I think the idea of "class for which there is no ref type" is a non-starter; for all of the types you talk about (vectors, etc), you could make the same argument for `int`, but no one is saying we don't need `Integer`.  I think what you are really getting at here is coming back to some form of "I want val-default".)
> 
> There are types which should never be null for different reasons, for those types having a reference projection is an issue.
> A nullable int is something useful hence we need Integer, sadly not all the value types are like this.
> 
> 
> A control question I would ask (though let's keep the bikeshedding to a dull roar) is how much of this is about the undeniable clumsiness of the locution "Point.val".  If, for example, the val type were called "point" or "Point!", as some people have already publicly wished, does this change your concern that "users will get it wrong all the time"? 
> 
> I really believe that not all (value) types should have a reference projection.
> 
> Rémi
> 
> 
> 
> 
> On 9/6/2022 4:32 AM, Remi Forax wrote:
> Hi everybody,
> it seems to me that the current design has reached a kind of local maximum, which is nice and not nice at the same time,
> so i would like to take the time to reflect on what we have sacrificed when moving to the current design.
> 
> What is missing/not supported by the current model is value classes that should not be used by reference,
> either because it will cause performance issues or because the user will not get the semantics he think he will get.
> 
> Here is a list of such value types:
> - unit types, value types like by example Nothing (which mean that a method never returns) with no fields.
>   Because creating a ref on it creates something :)
> 
> - wrappers/monads that modify the semantics, by example a generic value class Atomic that plays the same role as an AtomicReference, AtomicInteger, etc
>   the problem here is that the default semantics is not the semantics the user want.
>   
> - SIMD vectors, if those are nullable, the VM/JIT will insert implicit null checks which are not usually a problem apart in thigh loop like users write with SIMD vectors.
> 
> - existing value classes in Scala or Kotlin, those are not nullable by default but in the current design, getClass() will happily reflect them with a nullable class making Scala/Kotlin second class citizens of the Java platform.
> 
> Those are my 4 tent poles, they are maybe others, but currently we fail to provide a good answer for those cases.
> 
> regards,
> Rémi
> 
> 
> 
> 
> 
> 



More information about the valhalla-spec-observers mailing list