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


Reply via email to