[External] : Re: Consolidating the user model

Remi Forax forax at univ-mlv.fr
Thu Nov 4 22:47:25 UTC 2021


> From: "John Rose" <john.r.rose at oracle.com>
> To: "daniel smith" <daniel.smith at oracle.com>
> Cc: "Kevin Bourrillion" <kevinb at google.com>, "Brian Goetz"
> <brian.goetz at oracle.com>, "valhalla-spec-experts"
> <valhalla-spec-experts at openjdk.java.net>
> Sent: Jeudi 4 Novembre 2021 02:34:52
> Subject: Re: [External] : Re: Consolidating the user model

> On Nov 3, 2021, at 4:05 PM, Dan Smith < [ mailto:daniel.smith at oracle.com |
> daniel.smith at oracle.com ] > wrote:

>> (It is, I suppose, part of the model that objects of a given class all have a
>> finite, matching layout when accessed by value, even if the details of that
>> layout are kept abstract. Which is why value types are monomorphic and you need
>> reference types for polymorphism.)

>> The fact that the VM often discards object headers at runtime is a pure
>> optimization.

> Let’s see what happens if we say that (a) bare values have headers and (b)
> Object::getClass allows the user to observe part of the header contents.

> It follows then that the expression aPointVal.getClass() will show the contents
> of aPointVal’s header, even if it is a compile-time constant.

> Point pv = new Point(42,42); // “class Point” is the definition of Point
> assert pv.getClass() == Point.class; // ok, that’s certainly the class
> assert pv.getClass() != Point.ref.class; // and it’s not a ref, so good

> That is all fine. There’s a little hiccup when you “box” the point and get the
> same Class mirror even though the “header” is a very real-heap resident value
> now:

> Point.ref pr = pv; // same object… now it’s on the heap, though, with a real
> live heap header
> assert pr.getClass() == Point.class; // same class, but...
> assert pr.getClass() != Point.ref.class; // we suppress any distinction the heap
> header might provide

> There’s a bigger hiccup when you compare all that with good old int:

> int iv = 42; // “class int” is NOT a thing, but “class Integer” is
> assert iv.getClass() != int.class; // because int is not a class
> assert iv.getClass() == Integer.class; // ah, there’s the class!
> assert iv.getClass() == int.ref.class; // this works differently from Point
> assert ((Object)iv).getClass() == pr.getClass(); // this should be true also,
> right?

How can you have int.class not being a class and at the same time having the notation int.ref ?? 

If you suppose that int is now a primitive class, B3 bucket, then iv.getClass() == int.class, 
because it's equivalent to new int(iv).getClass() == int.class 
so 
assert iv.getClass() != Integer.class; //because Integer is the reference projection 
assert iv.getClass() != int.ref.class; // because int.ref is equivalent to Integer 

If you suppose that Integer is B2 bucket (after all, all other value based class are B2), then iv.getClass() == Integer.class 
because it's equivalent to Integer.valueOf(iv).getClass() == Integer.class 
so 
assert iv.getClass() != int.class; //because int.class is a fake type like void.class 
assert iv.getClass() != int.ref.class; // does not compile because Integer is B2 not B3 

I think i've missed something ? 

Rémi 


More information about the valhalla-spec-observers mailing list