Project

General

Profile

Feature #15010 ยป Reduce-allocation-for-rest-parameters-v1.patch

Patch 1 - chopraanmol1 (Anmol Chopra), 08/27/2018 09:36 AM

View differences:

array.c
1076 1076
    rb_ary_modify_check(ary);
1077 1077
    result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1078 1078
    n = RARRAY_LEN(result);
1079
    rb_ary_behead(ary,n);
1080

  
1081
    return result;
1082
}
1083

  
1084
MJIT_FUNC_EXPORTED VALUE
1085
rb_ary_behead(VALUE ary, long n)
1086
{
1087
    if(n<=0) return ary;
1088

  
1089
    rb_ary_modify_check(ary);
1079 1090
    if (ARY_SHARED_P(ary)) {
1080 1091
	if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) {
1081 1092
	  setup_occupied_shared:
......
1096 1107
    }
1097 1108
    ARY_INCREASE_LEN(ary, -n);
1098
    return result;
1109
    return ary;
1099 1110
}
1100 1111
static VALUE
internal.h
1087 1087
VALUE rb_to_array_type(VALUE obj);
1088 1088
VALUE rb_check_to_array(VALUE ary);
1089 1089
VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
1090
VALUE rb_ary_behead(VALUE, long);
1090 1091
#if defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO)
1091 1092
#define rb_ary_new_from_args(n, ...) \
1092 1093
    __extension__ ({ \
vm_args.c
22 22
    /* additional args info */
23 23
    int rest_index;
24
    int rest_dupped;
24 25
    const struct rb_call_info_kw_arg *kw_arg;
25 26
    VALUE *kw_argv;
26 27
    VALUE rest;
......
32 33
    arg_setup_block
33 34
};
35
static inline void
36
arg_rest_dup(struct args_info *args)
37
{
38
    if(!args->rest_dupped) {
39
        args->rest = rb_ary_dup(args->rest);
40
        args->rest_dupped = TRUE;
41
    }
42
}
43

  
34 44
static inline int
35 45
args_argc(struct args_info *args)
36 46
{
......
49 59
    int i;
50 60
    if (args->rest) {
51
	args->rest = rb_ary_dup(args->rest);
61
        arg_rest_dup(args);
52 62
	VM_ASSERT(args->rest_index == 0);
53 63
	for (i=args->argc + RARRAY_LENINT(args->rest); i<min_argc; i++) {
54 64
	    rb_ary_push(args->rest, Qnil);
......
69 79
	const long len = RARRAY_LEN(args->rest);
70 80
	if (len > over_argc) {
71
	    args->rest = rb_ary_dup(args->rest);
81
	    arg_rest_dup(args);
72 82
	    rb_ary_resize(args->rest, len - over_argc);
73 83
	    return;
74 84
	}
......
114 124
    if (args->rest != Qfalse) {
115 125
	int argc = args->argc;
116 126
	args->argc = 0;
117
	args->rest = rb_ary_dup(args->rest); /* make dup */
127
        arg_rest_dup(args);
118 128
	/*
119 129
	 * argv: [m0, m1, m2, m3]
......
146 156
    else if (args->argc > 0) {
147 157
	args->rest = rb_ary_new_from_values(args->argc, args->argv);
148 158
	args->rest_index = 0;
159
        args->rest_dupped = TRUE;
149 160
	args->argc = 0;
150 161
    }
151 162
}
......
162 173
    VALUE ary;
163 174
    if (args->rest) {
164
	ary = rb_ary_subseq(args->rest, args->rest_index, RARRAY_LEN(args->rest) - args->rest_index);
175
        ary = rb_ary_behead(args->rest, args->rest_index);
176
        args->rest_index = 0;
165 177
	args->rest = 0;
166 178
    }
167 179
    else {
......
219 231
		    RARRAY_ASET(args->rest, len - 1, rest_hash);
220 232
		}
221 233
		else {
222
		    args->rest = rb_ary_dup(args->rest);
234
		    arg_rest_dup(args);
223 235
		    rb_ary_pop(args->rest);
224 236
		    return TRUE;
225 237
		}
......
269 281
    args->kw_argv = NULL;
270 282
    if (args->rest) {
271
	args->rest = rb_ary_dup(args->rest);
283
	arg_rest_dup(args);
272 284
	rb_ary_push(args->rest, h);
273 285
    }
274 286
    else {
......
301 313
args_setup_post_parameters(struct args_info *args, int argc, VALUE *locals)
302 314
{
303 315
    long len;
304
    args_copy(args);
305 316
    len = RARRAY_LEN(args->rest);
306 317
    MEMCPY(locals, RARRAY_CONST_PTR(args->rest) + len - argc, VALUE, argc);
307 318
    rb_ary_resize(args->rest, len - argc);
......
343 354
static inline void
344 355
args_setup_rest_parameter(struct args_info *args, VALUE *locals)
345 356
{
346
    args_copy(args);
347 357
    *locals = args_rest_array(args);
348 358
}
......
538 548
    args = &args_body;
539 549
    given_argc = args->argc = calling->argc;
540 550
    args->argv = locals;
551
    args->rest_dupped = FALSE;
541 552
    if (ci->flag & VM_CALL_KWARG) {
542 553
	args->kw_arg = ((struct rb_call_info_with_kwarg *)ci)->kw_arg;
......
628 639
	args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0);
629 640
    }
641
    if (iseq->body->param.flags.has_rest || iseq->body->param.flags.has_post){
642
        args_copy(args);
643
    }
644

  
630 645
    if (iseq->body->param.flags.has_post) {
631 646
	args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start);
632 647
    }