How to implement a record de-constructor ?

forax at forax at
Wed Mar 21 08:06:38 UTC 2018

Hi Dan,

----- Mail original -----
> De: "Daniel Heidinga" <Daniel_Heidinga at>
> À: "Remi Forax" <forax at>
> Cc: "Brian Goetz" <brian.goetz at>, "amber-spec-experts" <amber-spec-experts at>
> Envoyé: Mardi 20 Mars 2018 21:31:00
> Objet: Re: How to implement a record de-constructor ?

>>>> if a de-constructor is inlined by the VM the same way getter is
>>inlined by the
>>>> VM, i.e. most of the time,
>>>> and if the de-constructor has no side effect (otherwise you have
>>bigger problem
>>>> that just a performance issue) then the VM will remove unused
>>>> share common sub-expressions, etc.
> Even ignoring side-effects, the cost model for a getter method is
> vastly different than invoking a MethodHandle from a List / array
> of MethodHandles, even if that List/array is rooted in the constant
> pool.
> The getter is an invokevirtual of cp data that the VM *knows* can't
> change. The MH is fetched from a mutable object (at least as far as
> the VM can trust) and then invoked.
> There's a lot of simulation overhead there - think emulating C++
> vtables in C.

I think there is a misunderstanding here,
i was talking about the option (2), where the de-constructor is
  record Point {
    Object <deconstructor>(MethodHandle mh, Object o) {
      return mh.invokeExact(o, this.x, this.y);
in that case as you see the the VM can do a pattern matching on the bytecode to see if it's a dumb extractor or not, like it does for a dumb getter.

For option (1), where you get an array/list of method handles, as you said, things are more complicated.
You can still for most operations like serialization, cloning, etc, help the VM by creating create one methodh handle from the list by folding them together.

By example, for writing a record into an output stream,
you can start from the list of getters
  [point -> point.x, point -> point.y]
and fold them to one method handle that will write every field values on the output stream
  (outputStream, point) -> { outputStream.write(point.x); outputStream.write(point.y); }

>>> I would love to buy this, but I don't.  The expensive actions of
>>> are likely to be allocating and copying stuff; even if the results
>>> unused, there are still many reasons why the JIT might not elide
>>> allocation and copying.
>>Apart if people still write side effects in their constructor in
>>2018, it should not be an issue,
>>we are still missing frozen arrays but immutable collections
>>(List.of+List.copyOf) is a good enough replacement.
> A frozen array would help as the VM could be taught the elements
> won't change. A List, even an immutable one, looks mutable to
> the VM.

Yes, an immutable list like the result of List.of() doesn't help the VM but it avoid the user code to contains a defensive copy which helps the VM.

> --Dan


More information about the amber-spec-observers mailing list