Return value type fields in registers

Roland Westrelin rwestrel at
Tue Mar 28 12:25:54 UTC 2017

Instead of returning a reference to a value type (which forces the
compiler to allocate a value type instance and initialize it), with this
change, the compiler returns the value type in registers: one field per
register. Similarly to the calling convention,
SharedRuntime::java_return_convention() defines what registers are used
to return value types. That call can fail if there are not enough
registers for a particular value type (too many fields in the value
type), in which case, the compiler is forced to allocate a value type

Because the compiled code now returns multiple values, the interpreter
needs to be able to handle multiple return values. Because the
interpreter works with value type references, on method return, it has
to allocate a new value type and initialize it with the field's values
from the registers of the calling convention. Because the interpreter
now expects multiple return values from a call, returning from an
interpreted method also needs to follow the calling convention and
return a value type instance in registers. Both loading the fields into
registers from a value type instance on return and allocating a new
value type instance initialized from the field values in registers is
performed through runtime calls that read/write register values using a

On the compiler side, supporting multiple return values consists mostly
in adding as many edges as there are fields to the ReturnNode and adding
as many projections as there are fields following a call.

The change also includes 

This is not turned on by default for 2 reasons: 1) The interpreter
reallocates value types in the heap. It would make more sense for the
interpreter to do it using the new buffer scheme that's being
developed. 2) If lambda form are involved, exact types for return values
are lost and this return scheme breaks. It needs lambda form to be
specialized to each value type types.

This is mostly unrelated but I noticed that calling a method that
returns a value type through reflection is currently broken (assert
failure somewhere in the reflection code). I suppose that when
reflection is fixed, it will box the returned value type so it's not
affected by that change to the calling convention. I suppose a similar
problem exists with passing value type arguments through reflection
though I haven't tried it.


More information about the valhalla-dev mailing list