Feature #15010 » Reduce-allocation-for-rest-parameters-v1.patch
| array.c | ||
|---|---|---|
| 
         rb_ary_modify_check(ary); 
   | 
||
| 
         result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST); 
   | 
||
| 
         n = RARRAY_LEN(result); 
   | 
||
| 
         rb_ary_behead(ary,n); 
   | 
||
| 
         return result; 
   | 
||
| 
     } 
   | 
||
| 
     MJIT_FUNC_EXPORTED VALUE 
   | 
||
| 
     rb_ary_behead(VALUE ary, long n) 
   | 
||
| 
     { 
   | 
||
| 
         if(n<=0) return ary; 
   | 
||
| 
         rb_ary_modify_check(ary); 
   | 
||
| 
         if (ARY_SHARED_P(ary)) { 
   | 
||
| 
     	if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) { 
   | 
||
| 
     	  setup_occupied_shared: 
   | 
||
| ... | ... | |
| 
         } 
   | 
||
| 
         ARY_INCREASE_LEN(ary, -n); 
   | 
||
| 
         return result; 
   | 
||
| 
         return ary; 
   | 
||
| 
     } 
   | 
||
| 
     static VALUE 
   | 
||
| internal.h | ||
|---|---|---|
| 
     VALUE rb_to_array_type(VALUE obj); 
   | 
||
| 
     VALUE rb_check_to_array(VALUE ary); 
   | 
||
| 
     VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *); 
   | 
||
| 
     VALUE rb_ary_behead(VALUE, long); 
   | 
||
| 
     #if defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO) 
   | 
||
| 
     #define rb_ary_new_from_args(n, ...) \ 
   | 
||
| 
         __extension__ ({ \ 
   | 
||
| vm_args.c | ||
|---|---|---|
| 
         /* additional args info */ 
   | 
||
| 
         int rest_index; 
   | 
||
| 
         int rest_dupped; 
   | 
||
| 
         const struct rb_call_info_kw_arg *kw_arg; 
   | 
||
| 
         VALUE *kw_argv; 
   | 
||
| 
         VALUE rest; 
   | 
||
| ... | ... | |
| 
         arg_setup_block 
   | 
||
| 
     }; 
   | 
||
| 
     static inline void 
   | 
||
| 
     arg_rest_dup(struct args_info *args) 
   | 
||
| 
     { 
   | 
||
| 
         if(!args->rest_dupped) { 
   | 
||
| 
             args->rest = rb_ary_dup(args->rest); 
   | 
||
| 
             args->rest_dupped = TRUE; 
   | 
||
| 
         } 
   | 
||
| 
     } 
   | 
||
| 
     static inline int 
   | 
||
| 
     args_argc(struct args_info *args) 
   | 
||
| 
     { 
   | 
||
| ... | ... | |
| 
         int i; 
   | 
||
| 
         if (args->rest) { 
   | 
||
| 
     	args->rest = rb_ary_dup(args->rest); 
   | 
||
| 
             arg_rest_dup(args); 
   | 
||
| 
     	VM_ASSERT(args->rest_index == 0); 
   | 
||
| 
     	for (i=args->argc + RARRAY_LENINT(args->rest); i<min_argc; i++) { 
   | 
||
| 
     	    rb_ary_push(args->rest, Qnil); 
   | 
||
| ... | ... | |
| 
     	const long len = RARRAY_LEN(args->rest); 
   | 
||
| 
     	if (len > over_argc) { 
   | 
||
| 
     	    args->rest = rb_ary_dup(args->rest); 
   | 
||
| 
     	    arg_rest_dup(args); 
   | 
||
| 
     	    rb_ary_resize(args->rest, len - over_argc); 
   | 
||
| 
     	    return; 
   | 
||
| 
     	} 
   | 
||
| ... | ... | |
| 
         if (args->rest != Qfalse) { 
   | 
||
| 
     	int argc = args->argc; 
   | 
||
| 
     	args->argc = 0; 
   | 
||
| 
     	args->rest = rb_ary_dup(args->rest); /* make dup */ 
   | 
||
| 
             arg_rest_dup(args); 
   | 
||
| 
     	/* 
   | 
||
| 
     	 * argv: [m0, m1, m2, m3] 
   | 
||
| ... | ... | |
| 
         else if (args->argc > 0) { 
   | 
||
| 
     	args->rest = rb_ary_new_from_values(args->argc, args->argv); 
   | 
||
| 
     	args->rest_index = 0; 
   | 
||
| 
             args->rest_dupped = TRUE; 
   | 
||
| 
     	args->argc = 0; 
   | 
||
| 
         } 
   | 
||
| 
     } 
   | 
||
| ... | ... | |
| 
         VALUE ary; 
   | 
||
| 
         if (args->rest) { 
   | 
||
| 
     	ary = rb_ary_subseq(args->rest, args->rest_index, RARRAY_LEN(args->rest) - args->rest_index); 
   | 
||
| 
             ary = rb_ary_behead(args->rest, args->rest_index); 
   | 
||
| 
             args->rest_index = 0; 
   | 
||
| 
     	args->rest = 0; 
   | 
||
| 
         } 
   | 
||
| 
         else { 
   | 
||
| ... | ... | |
| 
     		    RARRAY_ASET(args->rest, len - 1, rest_hash); 
   | 
||
| 
     		} 
   | 
||
| 
     		else { 
   | 
||
| 
     		    args->rest = rb_ary_dup(args->rest); 
   | 
||
| 
     		    arg_rest_dup(args); 
   | 
||
| 
     		    rb_ary_pop(args->rest); 
   | 
||
| 
     		    return TRUE; 
   | 
||
| 
     		} 
   | 
||
| ... | ... | |
| 
         args->kw_argv = NULL; 
   | 
||
| 
         if (args->rest) { 
   | 
||
| 
     	args->rest = rb_ary_dup(args->rest); 
   | 
||
| 
     	arg_rest_dup(args); 
   | 
||
| 
     	rb_ary_push(args->rest, h); 
   | 
||
| 
         } 
   | 
||
| 
         else { 
   | 
||
| ... | ... | |
| 
     args_setup_post_parameters(struct args_info *args, int argc, VALUE *locals) 
   | 
||
| 
     { 
   | 
||
| 
         long len; 
   | 
||
| 
         args_copy(args); 
   | 
||
| 
         len = RARRAY_LEN(args->rest); 
   | 
||
| 
         MEMCPY(locals, RARRAY_CONST_PTR(args->rest) + len - argc, VALUE, argc); 
   | 
||
| 
         rb_ary_resize(args->rest, len - argc); 
   | 
||
| ... | ... | |
| 
     static inline void 
   | 
||
| 
     args_setup_rest_parameter(struct args_info *args, VALUE *locals) 
   | 
||
| 
     { 
   | 
||
| 
         args_copy(args); 
   | 
||
| 
         *locals = args_rest_array(args); 
   | 
||
| 
     } 
   | 
||
| ... | ... | |
| 
         args = &args_body; 
   | 
||
| 
         given_argc = args->argc = calling->argc; 
   | 
||
| 
         args->argv = locals; 
   | 
||
| 
         args->rest_dupped = FALSE; 
   | 
||
| 
         if (ci->flag & VM_CALL_KWARG) { 
   | 
||
| 
     	args->kw_arg = ((struct rb_call_info_with_kwarg *)ci)->kw_arg; 
   | 
||
| ... | ... | |
| 
     	args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0); 
   | 
||
| 
         } 
   | 
||
| 
         if (iseq->body->param.flags.has_rest || iseq->body->param.flags.has_post){ 
   | 
||
| 
             args_copy(args); 
   | 
||
| 
         } 
   | 
||
| 
         if (iseq->body->param.flags.has_post) { 
   | 
||
| 
     	args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start); 
   | 
||
| 
         } 
   | 
||
- « Previous
 - 1
 - 2
 - 3
 - 4
 - Next »