Reference favoring primitive class heap allocations

Stig Rohde Døssing stigdoessing at gmail.com
Wed Sep 1 22:23:29 UTC 2021


Thanks Rémi, I think it mostly does. I'll admit that the bit about
optimizing local T.ref goes a bit over my head.

What about method return values? If I declare a method as

T.val someMethod()
vs
T.ref someMethod()

and do

T.val someLocal = someMethod()

would the two methods have different behavior for how the value is returned
from the call (Return the value in registers/put it on the caller's stack
vs.put the object on heap and return a pointer to that), or is this
determined by whether "someLocal" is a val or a ref and doesn't have
anything to do with the return type of "someMethod"?

Den ons. 1. sep. 2021 kl. 23.06 skrev Remi Forax <forax at univ-mlv.fr>:

> ----- Original Message -----
> > From: "Stig Rohde Døssing" <stigdoessing at gmail.com>
> > To: "valhalla-dev" <valhalla-dev at openjdk.java.net>
> > Sent: Mercredi 1 Septembre 2021 12:43:46
> > Subject: Reference favoring primitive class heap allocations
>
> > Hi,
> >
>
> Hi,
>
> > JEP 401 describes that current value-based classes will be made reference
> > favoring to avoid breaking existing code. Optional is one of these. I'm
> > trying to understand the impact this will have on existing APIs with
> > respect to heap allocation.
> >
> > Please assume for the following code snippets that ordinary scalar
> > replacement does not apply.
> >
> > As I understand it, code like
> >
> > Optional.val of(T item) { new Optional.val(item) }
> > Optional.val<String> s = of("Hello")
> >
> > would tell the JVM that the Optional does not necessarily have to go on
> the
> > heap, but could maybe go on the stack or in registers instead.
> >
> > When "of" is instead defined with the reference type, as in
> >
> > Optional of(T item) { new Optional(item) }
> > Optional.val<String> s = of("Hello")
> >
> > will the Optional always go on the heap?
> >
> > Also is the plan to be able to avoid the heap for return values, or will
> > the return value of
> >
> > Optional.val of(T item)
> >
> > always go on the heap unless "of" happens to be inlined?
> >
> > Thanks for reading.
>
> Nope, there is only one way to create an object which is a primitive class.
>
> Let's use an analogy, an ArrayList<String> at runtime can be typed as
> List<?> or as List<String>, but it's the same ArrayList at runtime.
>
> With primitive classes, it works the same way, a primitive class is always
> a primitive class at runtime,
> there is no two different ways to create a primitive class, there is only
> one way (to call the factory method named <new> of Optional).
> What is different, is that a primitive class can be typed in two different
> ways, as an Optional.val or as an Optional.ref,
> those two types mean different things in term of storage for a field, an
> array element or a local variable.
>
> T.val:
>   For fields and array elements, all the fields (if there are not too
> many) of T.val are stored in the container of the T.val (the class or the
> array containing the T.val)
>   For a local variable, T.val means that the VM will use registers (or
> spill the values on stack due to the register allocator) independently of
> the inlining algorithm.
>
> T.ref:
>   For fields and array elements, a T.ref is stored as a reference (on
> heap).
>   For a local variable, T.ref means that inside the inlining horizon, the
> VM can optimize the code using escape inlining with late rematerialization,
> so better than a classical reference because a primitive class has no
> identity (in practice it's a little more complicated because you don't want
> to inflate/deflate the same object inside the inlining horizon).
>
> I hope it answers to your questions.
>
> regards,
> Rémi
>


More information about the valhalla-dev mailing list