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 »