ruby-changes:30013
From: ko1 <ko1@a...>
Date: Fri, 19 Jul 2013 19:11:02 +0900 (JST)
Subject: [ruby-changes:30013] ko1:r42065 (trunk): * array.c (ary_memcpy): add a function to copy VALUEs into ary
ko1 2013-07-19 19:10:31 +0900 (Fri, 19 Jul 2013) New Revision: 42065 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42065 Log: * array.c (ary_memcpy): add a function to copy VALUEs into ary with write barrier. If ary is promoted, use write barrier correctly. * array.c (rb_ary_cat, rb_ary_unshift_m, rb_ary_dup, rb_ary_sort_bang, rb_ary_replace, rb_ary_plus): use ary_memcpy(). Modified files: trunk/ChangeLog trunk/array.c Index: array.c =================================================================== --- array.c (revision 42064) +++ array.c (revision 42065) @@ -93,6 +93,38 @@ memfill(register VALUE *mem, register lo https://github.com/ruby/ruby/blob/trunk/array.c#L93 } } +static void +ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv) +{ +#if 1 + if (OBJ_PROMOTED(ary)) { + if (0 /* disalbe now, because it cause mysterious error. */ + && argc > 32 /* 32 is magic number */) { + rb_gc_writebarrier_remember_promoted(ary); + RARRAY_PTR_USE(ary, ptr, { + MEMCPY(ptr+beg, argv, VALUE, argc); + }); + } + else { + int i; + RARRAY_PTR_USE(ary, ptr, { + for (i=0; i<argc; i++) { + OBJ_WRITE(ary, &ptr[i+beg], argv[i]); + } + }); + } + } + else { + RARRAY_PTR_USE(ary, ptr, { + MEMCPY(ptr+beg, argv, VALUE, argc); + }); + } +#else + /* use shady (traditional way) */ + MEMCPY(RARRAY_PTR(ary)+beg, argv, VALUE, argc); +#endif +} + # define ARY_SHARED_P(ary) \ (assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)), \ FL_TEST((ary),ELTS_SHARED)!=0) @@ -913,7 +945,7 @@ rb_ary_cat(VALUE ary, const VALUE *ptr, https://github.com/ruby/ruby/blob/trunk/array.c#L945 long oldlen = RARRAY_LEN(ary); ary_ensure_room_for_push(ary, len); - MEMCPY(RARRAY_PTR(ary) + oldlen, ptr, VALUE, len); + ary_memcpy(ary, oldlen, len, ptr); ARY_SET_LEN(ary, oldlen + len); return ary; } @@ -1140,7 +1172,7 @@ rb_ary_unshift_m(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/array.c#L1172 } ary_ensure_room_for_unshift(ary, argc); - MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc); + ary_memcpy(ary, 0, argc, argv); ARY_SET_LEN(ary, len + argc); return ary; } @@ -1849,9 +1881,10 @@ rb_ary_empty_p(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L1881 VALUE rb_ary_dup(VALUE ary) { - VALUE dup = rb_ary_new2(RARRAY_LEN(ary)); - MEMCPY(RARRAY_PTR(dup), RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary)); - ARY_SET_LEN(dup, RARRAY_LEN(ary)); + long len = RARRAY_LEN(ary); + VALUE dup = rb_ary_new2(len); + ary_memcpy(dup, 0, len, RARRAY_RAWPTR(ary)); + ARY_SET_LEN(dup, len); return dup; } @@ -2372,7 +2405,7 @@ rb_ary_sort_bang(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L2405 rb_ary_unshare(ary); } FL_SET_EMBED(ary); - MEMCPY(RARRAY_PTR(ary), ARY_EMBED_PTR(tmp), VALUE, ARY_EMBED_LEN(tmp)); + ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp)); ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp)); } else { @@ -3234,7 +3267,6 @@ rb_ary_replace(VALUE copy, VALUE orig) https://github.com/ruby/ruby/blob/trunk/array.c#L3267 if (copy == orig) return copy; if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) { - VALUE *ptr; VALUE shared = 0; if (ARY_OWNS_HEAP_P(copy)) { @@ -3245,8 +3277,7 @@ rb_ary_replace(VALUE copy, VALUE orig) https://github.com/ruby/ruby/blob/trunk/array.c#L3277 FL_UNSET_SHARED(copy); } FL_SET_EMBED(copy); - ptr = RARRAY_PTR(orig); - MEMCPY(RARRAY_PTR(copy), ptr, VALUE, RARRAY_LEN(orig)); + ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_RAWPTR(orig)); if (shared) { rb_ary_decrement_share(shared); } @@ -3413,13 +3444,16 @@ VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L3444 rb_ary_plus(VALUE x, VALUE y) { VALUE z; - long len; + long len, xlen, ylen; y = to_ary(y); - len = RARRAY_LEN(x) + RARRAY_LEN(y); + xlen = RARRAY_LEN(x); + ylen = RARRAY_LEN(y); + len = xlen + ylen; z = rb_ary_new2(len); - MEMCPY(RARRAY_PTR(z), RARRAY_PTR(x), VALUE, RARRAY_LEN(x)); - MEMCPY(RARRAY_PTR(z) + RARRAY_LEN(x), RARRAY_PTR(y), VALUE, RARRAY_LEN(y)); + + ary_memcpy(z, 0, xlen, RARRAY_RAWPTR(x)); + ary_memcpy(z, xlen, ylen, RARRAY_RAWPTR(y)); ARY_SET_LEN(z, len); return z; } Index: ChangeLog =================================================================== --- ChangeLog (revision 42064) +++ ChangeLog (revision 42065) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Jul 19 19:07:31 2013 Koichi Sasada <ko1@a...> + + * array.c (ary_memcpy): add a function to copy VALUEs into ary + with write barrier. If ary is promoted, use write barrier correctly. + + * array.c (rb_ary_cat, rb_ary_unshift_m, rb_ary_dup, + rb_ary_sort_bang, rb_ary_replace, rb_ary_plus): use ary_memcpy(). + Fri Jul 19 15:32:57 2013 Koichi Sasada <ko1@a...> * array.c (rb_ary_store): use RARRAY_PTR_USE() intead of RARRAY_PTR(). -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/