value type hygiene
brian.goetz at oracle.com
Thu May 10 15:52:32 UTC 2018
Thanks for this great writeup. I find much to agree with here, and a few things to be concerned about (I’ll express the latter in a separate mail; Dan touched on some of them.)
Now that we see it, elevating from ACC_FLATTENABLE to the ValueTypes attribute makes obvious sense. The key thing to reify is whether V was a value type at the time C was compiled. This flows into many decisions within C, and at the boundary of C and other V-users, so capturing it in one place makes sense.
I’ll add that this reminds me very much of loader constraints. When class C calls method D.m(P)R, we first textually match the call with m(P)R in D via descriptor match, and then we additionally make sure that C and D agree on any loader constraints, throwing an error if they do not. In L-world, whether C and D think V is a value or object class is another kind of constraint. At linkage time, if these constraints agree, they can use an optimized protocol; if they disagree, rather than failing, the VM can introduce hidden adaptation to iron out the disagreement. This is a big win over the use of bridges in Q-world, since the adaptors are only generated at runtime when they are strictly needed, and as the ecosystem gets recompiled over time to a more uniform view of V’s value-ness, will steadily go away. We saw shades of this in Albert’s first prototype of heisenboxes, where the JIT compiled multiple versions of each method (if needed) according to different views of value-ness, and then fit them together, lego-style.
A note on the responses:
- I think the Map.get() discussion is a red herring. This is a signature that simply makes no sense when V is a value. We’ve looked at several alternatives — optional-bearing, a pattern match (case withMapping(var v)), a get-with-default, etc. In Q-world, we observed that sometimes a method doesn’t make it to the any-fied version; it becomes a restricted method that only makes sense on reference types. In L-world, we don’t necessarily have “ref V” to fall back on (though we might), but there will need to be some way to give Map.get() a gold watch and thank it for its service (and lament that the best name has been retired from the namespace.)
I’ll start a separate thread on my concerns.
More information about the valhalla-spec-observers