[External] : Re: Enhancing java.lang.constant for Valhalla
Dan Heidinga
heidinga at redhat.com
Fri Dec 17 18:29:56 UTC 2021
> Let's do an ASM thought experiment.
>
> The descriptors live in (a) {method,field}_info metadata, and (b) C_{Field,Method}Ref constants referred to by invoke/field access instructions.
>
> The stars, though, live somewhere completely different: the Preload attribute, which is not on the instruction, or the code attribute, or the method/field, but on the class.
>
> I would expect ClassVisitor to be enhanced with something like
>
> visitPreload(String clazz)
>
> So, when reading a classfile, you get a bunch of preload "events", and then eventually, when you get to method/field metadata, or instructions, you get a bunch of events that have L descriptors in them, with no stars.
>
> ASM commits to delivering certain events before others, so when adapting, you might accumulate the visitPreload events into a List, and then if you are inserting new instructions that are supposed to use L*, if they're not in the list, you'd emit extra visitPreload calls. (Presumably also ASM would want to filter the Preload values to eliminate duplicates.)
>
> Similarly, when writing a classfile, if you want to do a getstatic of a field known to be an L* field, you might do something like:
>
> b.visitPreload(internalName(C))
> b.visitFieldInsn(GETSTATIC, receiverClass, "foo", eLdescriptor(C))
>
> Which is to say, one of the costs of this scheme is that the stars go far away from the descriptors they are attached to (not even in 1:1 correspondence), and classfile manglers will have to keep this mapping somewhere.
This makes sense to me as well for an ASM-style use case. No arguments here.
> My first instinct is that putting the stars in the ClassDesc is putting the bookkeeping in the wrong place.
>
>
> Let's look at other uses of ClassDesc; one was the constant folding example. We want to be able to intrinsify LDC operations, including condy, and indy calls. Do any of them need preloading to work properly? (The *s are about preloading constraints.)
>
> LDC'ing a C_Class will already force loading of the class (and besides, C_Class has no use for a *.)
>
> Invoking an indy which returns an L*Foo might want Foo preloaded. I don't know enough about the timing of indy linkage to know whether all the classes in the type descriptor are loaded by the time the calling convention is set up, but I suspect it may already be?
>
This is (mostly?) true if the bootstrap method (BSM) is defined on
another class. If the BSM is defined in the same class as the
indy/condy, and it takes a static argument of a type that should have
been preloaded, then the calling convention for the BSM method will be
set up prior to the indy / condy forcing the class to be loaded.
How bad this is depends on the blast radius of missing the preload at
calling convention time. If it only poisons the calling convention of
the BSM, then no big deal as the BSM is a resolution cost. If the
effect is more global and applies to all methods with an argument of
that type, it may be more problematic as it will be a surprising sharp
edge in the performance model.
The answer to how bad it is likely depends on implementation details -
OpenJ9's later binding of calling conventions means this likely isn't
so bad but might be worse on Hotspot as calling conventions are set at
class load (based on earlier discussions)?
--Dan
More information about the valhalla-spec-experts
mailing list