[前][次][番号順一覧][スレッド一覧]

ruby-changes:52374

From: ko1 <ko1@a...>
Date: Tue, 28 Aug 2018 16:06:12 +0900 (JST)
Subject: [ruby-changes:52374] ko1:r64583 (trunk): rest parameter optimization [Feature #15010]

ko1	2018-08-28 16:06:06 +0900 (Tue, 28 Aug 2018)

  New Revision: 64583

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64583

  Log:
    rest parameter optimization [Feature #15010]
    
    * vm_args.c: rb_ary_dup(args->rest) to be used at most once during
      parameter setup. [Feature #15010]
      A patch by chopraanmol1 (Anmol Chopra) <chopraanmol1@g...>.
    
    * array.c (rb_ary_behead): added to remove first n elements.

  Modified files:
    trunk/array.c
    trunk/internal.h
    trunk/vm_args.c
Index: internal.h
===================================================================
--- internal.h	(revision 64582)
+++ internal.h	(revision 64583)
@@ -1087,6 +1087,7 @@ size_t rb_ary_memsize(VALUE); https://github.com/ruby/ruby/blob/trunk/internal.h#L1087
 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__ ({ \
Index: array.c
===================================================================
--- array.c	(revision 64582)
+++ array.c	(revision 64583)
@@ -1076,6 +1076,17 @@ rb_ary_shift_m(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/array.c#L1076
     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:
@@ -1096,7 +1107,7 @@ rb_ary_shift_m(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/array.c#L1107
     }
     ARY_INCREASE_LEN(ary, -n);
 
-    return result;
+    return ary;
 }
 
 static VALUE
Index: vm_args.c
===================================================================
--- vm_args.c	(revision 64582)
+++ vm_args.c	(revision 64583)
@@ -22,6 +22,7 @@ struct args_info { https://github.com/ruby/ruby/blob/trunk/vm_args.c#L22
 
     /* additional args info */
     int rest_index;
+    int rest_dupped;
     const struct rb_call_info_kw_arg *kw_arg;
     VALUE *kw_argv;
     VALUE rest;
@@ -32,6 +33,15 @@ enum arg_setup_type { https://github.com/ruby/ruby/blob/trunk/vm_args.c#L33
     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)
 {
@@ -49,7 +59,7 @@ args_extend(struct args_info *args, cons https://github.com/ruby/ruby/blob/trunk/vm_args.c#L59
     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);
@@ -69,7 +79,7 @@ args_reduce(struct args_info *args, int https://github.com/ruby/ruby/blob/trunk/vm_args.c#L79
 	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;
 	}
@@ -114,7 +124,7 @@ args_copy(struct args_info *args) https://github.com/ruby/ruby/blob/trunk/vm_args.c#L124
     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]
@@ -146,6 +156,7 @@ args_copy(struct args_info *args) https://github.com/ruby/ruby/blob/trunk/vm_args.c#L156
     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;
     }
 }
@@ -162,7 +173,8 @@ args_rest_array(struct args_info *args) https://github.com/ruby/ruby/blob/trunk/vm_args.c#L173
     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 {
@@ -219,7 +231,7 @@ args_pop_keyword_hash(struct args_info * https://github.com/ruby/ruby/blob/trunk/vm_args.c#L231
 		    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;
 		}
@@ -269,7 +281,7 @@ args_stored_kw_argv_to_hash(struct args_ https://github.com/ruby/ruby/blob/trunk/vm_args.c#L281
     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 {
@@ -301,7 +313,6 @@ static inline void https://github.com/ruby/ruby/blob/trunk/vm_args.c#L313
 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);
@@ -343,7 +354,6 @@ args_setup_opt_parameters(struct args_in https://github.com/ruby/ruby/blob/trunk/vm_args.c#L354
 static inline void
 args_setup_rest_parameter(struct args_info *args, VALUE *locals)
 {
-    args_copy(args);
     *locals = args_rest_array(args);
 }
 
@@ -538,6 +548,7 @@ setup_parameters_complex(rb_execution_co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L548
     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;
@@ -628,6 +639,10 @@ setup_parameters_complex(rb_execution_co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L639
 	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);
     }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]