VM model and aconst_init
Dan Heidinga
heidinga at redhat.com
Tue Jan 25 14:40:16 UTC 2022
> 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
>
>
>
>
More information about the valhalla-spec-experts
mailing list