Reference pointers in compact value objects (primitive classes)

Remi Forax forax at univ-mlv.fr
Tue Apr 25 14:46:24 UTC 2023


----- Original Message -----
> From: "-" <liangchenblue at gmail.com>
> To: valhalla-dev at openjdk.org
> Sent: Tuesday, April 25, 2023 3:38:20 PM
> Subject: Reference pointers in compact value objects (primitive classes)

> Hello,
> I just wonder if nullable reference pointers can be part of compact
> value objects.

It depends if it's on the stack or on the heap.
On stack, a nullable reference to a value class if fully scalarized.
On heap, a nullable reference is not flattened, non null reference of value class with a default instance are flattened.

On stack, declaring a class as a value class is enough
  value record Point (int x, int y) {}

On heap, the value class also need a default constructor
   value record Point (int x, int y) {
     default Point();   // the default value is not null but Point(0,0)
   } 

  and when used, a field has to declare that the field is not nullable using '!'
   record Rectangle(Point! topLeft, Point! bottonRight) { }


> 
> For instance, in the Classfile API, there is StackMapGenerator.Type, a
> record with (int type, ClassDesc reference, int bci). The default
> state (0, null, 0) is valid and a desirable default (0 type means
> top-type). If the ClassDesc field can be part of the compact
> representation, then the whole structure can be optimized, which looks
> promising to me.

Most values of the ClassFile API are values on stack so they should be scalarized.
Note that, this is not yet true, currently a switch on a sealed interface forces the rematerialization.

> 
> Meanwhile, I have another question about nullable object
> representation in value classes: Suppose we have
> Optional<Optional<Optional<String>>>, what will the representation be?
> How will we distinguish Optional.empty() with
> Optional.of(Optional.empty())?

Let suppose that Optional is declared with a default instance like this
  value class Optional<T> {
    private final T value;

    default Optional();
    ...
  }

Then you need a '!' to ask for flattening, so Optional<Optional!<String>>

Now to answer to your question, the VM tracks the class (here Optional is specialized class), so even if the memory layout is the same between Optional<String> and Optional<Optional!<String>>, the specialized classes (sometimes also called the species) at runtime are not the same.

> 
> Thanks,
> Chen Liang

regards,
Rémi



More information about the valhalla-dev mailing list