> Can you mix and match both modes in the same method? > Probably, since the interpreter doesn’t care about > multi-bytecode patterns. Dunno if this causes a testing > problem, and if so how to fix it. I think it’s probably > OK, especially if we require the two-way checkcast > (Q-Foo not a subtype of L-Foo in the verifier) so that > each mode stays “in its own lane”. > > More explicitly, this is a set of use cases for using > Q-types in C_Class entries in the constant pool to switch > to Q-mode for bytecodes that refer to classes, including > withfield and aconst_init. > > > Let's talk a bit about having the L world and the Q world completely disjoint > at least from the bytecode verifier POV. > > It means that we need some checkcasts to move in both direction, from a > Q-type to a L-type and vice-versa. > But at the same time, an array of L-type is a subtype of an array of Q-type ? > The result to a very uncommon/unconventional type system, and i'm not a big > fan of surprises in that area.
I've been puzzling over this as well and echo your discomfort with it, mostly on the array side. I haven't been able to identify what the sharp edge here is though other than that it feels surprising. After playing with bytecode sequences, the part I'm not clear on is whether I can store an LFoo; into a [QFoo; directly, or do I need a checkcast QFoo; before the aastore? If I need the checkcast (and I think I do), then I'm starting to come around to the view that the array side isn't actually any different from what we'd do for any other subclass relationship. The checkcast for Q->L is still odd, but less concerning as it deals with new value semantics rather than changing the array covariance? For reference, the bytecodes sequences I've been looking at are the following: Convert with checkcast: -------------------------------- aload_1 checkcast QFoo; // or LFoo; and Convert with Q->L array store/load: --------------------------------------- anewarray //LFoo astore_2 aload_2 iconst_0 invokestatic QFoo.<new>QFoo; // or any other way to get a Q aastore aload_2 iconst_0 aaload // use as an LFoo Convert with L->Q array store/load: --------------------------------------- anewarray //QFoo astore_2 aload_2 iconst_0 invokestatic X.getFoo:()LFoo; // Is a checkcast needed here first to downcast? I think so aastore aload_2 iconst_0 aaload // use as an QFoo --Dan > > Furthermore, i believe that subtyping is a key to avoid multiple bytecode > verification of the generics code. > By example, with the TypeRestriction attribute [1], the restriction has to be > subtype of the declared type/descriptor. > > Rémi > > [1] > https://cr.openjdk.java.net/~jrose/values/parametric-vm.html#type-restricted-methods-and-fields-and-the-typerestriction-attribute > > > >