Doubling down on the erasure vs constant pool specialization

Remi Forax forax at
Wed Dec 6 14:47:41 UTC 2017

Hi John, hi all,
i've read the doc you send us during our last meeting on the classfile specialization,
while it's powerful i do not think we need to do constant pool specialization at least to implements generics over primitives and value types.

One of the results of the MVT prototype is that we need Q types only for the layout, you do not need Q types to represent value types on the stack, so we should not need to specialize the signature of a method if the class is generified, we can use Object as carrier type, an Object can represent reference type by subtyping and primitive and value type by buffering. If we do not need method descriptor specialization, we do not need vtable specialization, etc.

We have 3 places where we can specialize the Java code, at bytecode level, at constant pool level, at JIT level, i believe we should investigate trying to do the specialization at JIT level only, mostly because it doesn't have the complexity of doing the specialization at constant pool level and it is the same level of bet as saying that we can use Object as a carrier type for all Q types.

So here is my counter proposal: doubling down on the erasure, let method descriptor to use Object, introduce class species and method species, make the few bytecodes that deals with the layout species aware.

for a field, like for Q-type field, the field need to be annotated with the type variable of the species, so when the layout is created, the VM can decide or not to specialize the layout
for array, again, array are species so the component type is reified (again, the VM can decide to not specialize the array) and tested when storing an element. 

in term of bytecode, we have two kind of bytecodes that need to have there semantics changed,
- new/anewarray, and all invoke* need to be able to send (out of band) argument types to create a species-class or a species-method,
  this can be done by using a typevar bytecode as prefix, the typevar being able to specify either a type argument, or a type variable from the current species-class or species-method
- getfield/aaload doesn't need to be changed, they will both put an Object on stack
- for putfield, a supplementary check to type argument of the species is needed before storing the value. 
- for aastore, the component check already exist.


More information about the valhalla-spec-observers mailing list