More on seeing the L world as a U world

John Rose john.r.rose at
Wed Nov 22 19:03:53 UTC 2017

Good comments.

On Nov 22, 2017, at 3:05 AM, Remi Forax <forax at> wrote:
> Primitive types:
> primitive types are seen by the VM as value types, int.class.isValueType() returns true.
> there is no need to see those class in the JDK, so like currently there are synthetize by the VM. So storing an int as an Object is equivalent to box/buffer the int like any value type. 

Yes, I think this will work pretty easily in the JVM.
The harder adjustment is in the language, where the
cast (Object)(int)x produces an (Integer), where the
JVM is now willing to produce a buffered (int).

> Performance:
> If we have U types everywhere, doesn't it introduce perf issues, by example, what about acmp now having to test if it operates on value types or reference types.
> There are two facts that save us here, with acmp as example,
> - first for one execution, a type is either a value type or a reference type, so it enables the kind of optimization we do with quick opcodes, i.e. the slow path is if you do not know if the type is a reference type or a value type, but once you have do the test for a type, you can install a fast path for all acmp on the same type.

acmp is so fast that even detecting values will cause noticeable
overheads.  I think the JIT will end up hoisting value detection
as much as possible.  In some systems, we might consider
hoisting the distinction into object references, all the way through
the heap and GC.

> - if the cost is too important we can have say that acmp will always do a pointer check (here we are saved by the fact that in hotspot a value type is also a machine word pointer) and introduces a new opcode, ucmp that have a bigger overhead.

That acmp is exactly what I mean by a Heisenbox comparison.
If we could get comfortable with Heisenboxes, the acmp problem
would go away.  But the cost is great:  the expression "a==a"
yields an essentially indeterminate result.  I don't know how to
make that acceptable as a JVM behavior.  So "a==a" yielding
always false for values, or (more expensively) "a==a" triggering
a fieldwise substitutability check for values, seems like the
place we have to land on.

> The semantics of acmp on value type in that case is garbage, but not less garbage that the current boxing semantics specified by the JLS. 

I wish that were true, but there's a bit more garbage with
Heisenboxes.  This contrived but legal program does not always
return true for value types:

boolean paradox(DoubleComplex x) {
 DoubleComplex y = x;
 boolean p1 = (x == y);  // might be true or false
 doSomething();  // might deopt or JIT
 boolean p2 = (x == y);  // independently might be true or false
 return p1 == p2;

As an old Lisper, I am inclined to turn a blind eye to that kind
of thing; that's what EQ does and you use EQV if you need
a value-sensitive test.  (EQV is your ucmp, EQ is acmp.)
But the JVM has a higher standard for reproducibility.

— John

More information about the valhalla-spec-observers mailing list