abandon all U-types, welcome to L-world (or, what I learned in Burlington)

John Rose 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.

— John

More information about the valhalla-spec-observers mailing list