Hello folks! Now that we're a few months into JRuby 9000 I've started
to hack on the indy bindings again. Things are looking good so far.
I'm working on getting closures to inline where they're invoked by
chaining together a number of GWT just like a polymorphic call site.

Anyway, my discovery today was that it's too expensive to collect a
bunch of arguments at the end of an argument list right now.

For one place in closure dispatch, we need to box a single incoming
argument in an array. In InvokeBinder code, that looks like this:

Binder.from(IRubyObject[].class, IRubyObject.class).collect(0,

Since there's only a single argument and we're boxing to the end of
the list, this turns into a handle.asCollector followed by an

Unfortunately, it's MUCH faster to just bind to a hand-written method
that constructs the array directly.

Binder.from(IRubyObject[].class, IRubyObject.class)
CompiledIRBlockBody.class, "wrapValue");

private static IRubyObject[] wrapValue(IRubyObject value) {
    return new IRubyObject[] {value};

I was running a benchmark that calls a method with a closure 10M
times, and the method yields back to the closure 25 times, so a total
of 250M closure dispatches passing through the above adapter (among
others). Everything seems to fit together nicely, though I haven't
checked inlining yet.

With asCollector: 16-17s per iteration

With hand-written array construction: 7-8s per iteration

A sampling profile only shows my Ruby code as the top items, and an
allocation trace shows Object[] as the number one object being
created...not IRubyObject[]. Could that be the reason it's slower?
Some type trickery messing with optimization?

This is very unfortunate because there's no other general-purpose way
to collect arguments in a handle chain.

- Charlie
mlvm-dev mailing list

Reply via email to