[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