abandon all U-types, welcome to L-world (or, what I learned in Burlington)
john.r.rose at oracle.com
Wed Nov 22 18:48:18 UTC 2017
On Nov 22, 2017, at 5:48 AM, Brian Goetz <Brian.Goetz at Oracle.COM> wrote:
> What's the L-world story for array subtyping? For any R-type, R <: Object. If everything is an L type and everything is <: Object, are arrays of Q-types/primitives also subtypes of Object?
> We didn't have a story for this in QU-world either, but at least in QU-world it was believable that QFoo <! Object. But that seems much less tenable when there's no syntactic difference between L-uses and Q-uses. (And even less so when we might migrate code from L to Q.)
We were just talking about this in the concall with IBM.
Field and array-element flattening are the two places where
the Q/R distinction provides a crucial hint that flattening
*may* (not always *must*) occur. This hint is crucial because
it is statically visible *before* all class files are loaded.
The instance layout algorithm and the verifier both need
to run before all class files are loaded (because of
circularities, also performance). In U-world, the
letter 'Q' in a static descriptor tells the instance layout
generator to load the field class and extract sub-layout.
It also tells the verifier not to assume a covariantly
compatible layout relative to the type Object.
If we don't keep a few Q's around for old times'
sake, we will need to signal these subtle difference
some other way, with an ACC_FLATTENABLE
bit on fields and a special "[@" syntax variant
(pick your letter, maybe "Q") for array descriptors.
I think of this as the "residual Q problem", of
finding offices for the few remaining occurrences
of Q that do real work in L-world.
(The user-visible distinction of flat vs. legacy
arrays was one influence that led us towards
user-visible box types. I'd like to resist that this
time around. Perhaps "[@" is a syntax that is
mutually exclusive with plain "[". And there is
a showdown when such an array is created,
so that the descriptor has a "@" if and only if
the loaded element type is in fact a Q-type.
It's a move that of class loader constraints.)
I am not opposed to allowing the existing Q-syntax
for descriptors, in a limited number of places, to
solve those residual problems. That thought leads
me to try on the idea (which Remi discourages)
that perhaps Q-narrowings of some method
descriptors are useful (requiring bridges just
like today's generics). A Q-narrowing of a
class means: No nulls here, identity is not
observable, and value-based semantics are
in force, including unmodifiability. Not a bad
set of guarantees; maybe that's a job for Q's
rather than an invisible type profile.
BTW, an Ljava/util/List; would not pass through
a Qjava/util/List; descriptor, unless List.copyOf
were applied to it first. The VM and java.base
can conspire to provide a curated set of Q-able
types with enforced value or value-based behavior.
More information about the valhalla-spec-observers