Wasteful wrapping and unwrapping of arguments to blocks/procs
-------------------------------------------------------------
Key: JRUBY-2560
URL: http://jira.codehaus.org/browse/JRUBY-2560
Project: JRuby
Issue Type: Bug
Components: Core Classes/Modules
Affects Versions: JRuby 1.1.2
Reporter: Charles Oliver Nutter
Fix For: JRuby 1.1+
We are doing way too much wrapping and unwrapping of arguments to blocks. In
addition, because multiple assignment is based on a RubyArray always, we box
individual arguments even in the simple cases where they'll just be immediately
assigned to individual variables. This is probably a substantial reason why
block invocation is slower than method invocation, when in most cases it should
be faster.
Here is some sample code, from InterpretedBlockBody:
{noformat}
# main entry point for interpreted procs (including define_method methods)
public IRubyObject call(ThreadContext context, IRubyObject[] args, Binding
binding, Block.Type type) {
args = prepareArgumentsForCall(context, args, type);
return yield(context, context.getRuntime().newArrayNoCopy(args), null,
null, true, binding, type);
}
# hmm...lots of wrapping going on in here too
public IRubyObject[] prepareArgumentsForCall(ThreadContext context,
IRubyObject[] args, Block.Type type) {
switch (type) {
case NORMAL: {
assert false : "can this happen?";
if (args.length == 1 && args[0] instanceof RubyArray) {
if (argumentType == MULTIPLE_ASSIGNMENT || argumentType ==
SINGLE_RESTARG) {
args = ((RubyArray) args[0]).toJavaArray();
}
break;
}
}
case PROC: {
if (args.length == 1 && args[0] instanceof RubyArray) {
if (argumentType == MULTIPLE_ASSIGNMENT && argumentType !=
SINGLE_RESTARG) {
args = ((RubyArray) args[0]).toJavaArray();
}
}
break;
}
case LAMBDA:
if (argumentType == ARRAY && args.length != 1) {
context.getRuntime().getWarnings().warn(ID.MULTIPLE_VALUES_FOR_BLOCK, "multiple
values for a block parameter (" + args.length + " for " + arity().getValue() +
")");
if (args.length == 0) {
args = new IRubyObject[] {context.getRuntime().getNil()};
} else {
args = new IRubyObject[]
{context.getRuntime().newArrayNoCopy(args)};
}
} else {
arity().checkArity(context.getRuntime(), args);
}
break;
}
return args;
}
{noformat}
After the 1.1.2 release, we should start exploring what it would take to make
Blocks have specific-arity optimizations as well, especially since they're even
more likely than methods to have only a small number of arguments.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email