Getting back into indy...need a better argument collector!
Charles Oliver Nutter
headius at headius.com
Mon Jan 11 03:16:43 UTC 2016
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,
IRubyObject[].class).identity();
```
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
identity.
Unfortunately, it's MUCH faster to just bind to a hand-written method
that constructs the array directly.
```
Binder.from(IRubyObject[].class, IRubyObject.class)
.invokeStaticQuiet(MethodHandles.lookup(),
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
More information about the mlvm-dev
mailing list