Streams factories in Stream

John Rose john.r.rose at
Thu Apr 25 17:39:44 PDT 2013

On Apr 24, 2013, at 4:37 AM, Remi Forax <forax at> wrote:

> In that case, it's better to use invokedynamic to do the whole varargs adaptation

That's a brilliant suggestion, and not just for the special case of arity zero.  Here's one way of seeing it:

When A::m calls a vararags B::v on (say) 2 arguments, the length-2 argument array is allocated by A::m and consumed by B::v.

If (as sometimes happens) A::m and B::v are compiled by separate compilation tasks, then escape analysis on the array will fail, and A::m will have to allocate one, always.

But if A::m calls some system-generated adapter B::v$2arg (via indy), which then calls B::v, then the system can (if it chooses) inline B::v into B::v$2arg (and also other arity adapters).  Then the array will go away after escape analysis, and you'll get exactly one split of B::v per dynamically occurring arity.  (Plus the explicit-array case.)

The arity-zero case falls out "for free".

Key fact: Escape analysis requires (a) a known creation point and (b) known use points.  If you separately compile A::m from B::v, then you cut off (a) from (b).  But an arity adapter lets them find each other again.

(Note that (b) requires that the varargs array is used very simply, such as iterating.  Bonus points for a switch or decision tree on its length, because then all but one switch case disappears.)

— John

More information about the lambda-dev mailing list