Target of opportunity: remove method <vnew> and aconst_init / withfield opcodes

Remi Forax forax at univ-mlv.fr
Sat Aug 12 20:39:42 UTC 2023


John and I and several others had several interresting discussions yesterday about Valhalla,
one of them about the removal of <vnew> and aconst_init/withfield, something i've called in the past, solving the last mile issue.

Currently, refactoring from/to a value class/identity class is not a backward compatible move because of the way value classes are initialized using the <vnew> factory method. The reason is that during the initialization, a class instance is mutable but the VM considers that all value class instances are non-mutable.

But at the same time, in order to implement Serialization of value classes (exactly de-serialization), there is a need for a mechanism to tag value class instances as "not yet finished to be initialized", something John refers has the object being in larval state because the de-serialization first create the instance and then populate its fields. In the lw prototypes, this is currently implemented using Unsafe.

I think we have the opportunity now to use the same larval protocol for all values classes, making them binary backward compatible with identity classes. With both of them using the initialization protocol, the same new/dup/invokespecial dance.

In term of specification, the idea is that "new" on a value class creates a larval instance and the end of the constructor mark the instance as non-larval/true-value-instance.

I think that using the same initialization protocol at callsite is a good idea. We are re-aligning the bytecode with the Java code, One thing wichh is currently hard to understand for our users is that currently the Java code is the same for a value class and an identity class but the generated bytecode is not binary compatible. This also go well with the recent move to remove the Q-descriptor, we are moving toward the goal of being fully binary backward compatible.

We may want to modify the verifier to verify that "this" does not escape the constructor in case of a value class, but I do not thing it's a requirement, so it's maybe better to not do that :)

The end of constructor is already a point where all VMs/JITs are able to emit codes (for store/store barrier or finalizer registration), so we are piggy backing on an existing concept. The only main drawback I see is that the header of a buffered value type has to have one bit to indicate the larval state and those header bits are really precious.

regards,
Rémi


More information about the valhalla-spec-observers mailing list