diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-11 06:47:12 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-11 06:47:12 +0000 |
commit | c9aabf37eadfdbbdcc5bc3fbf775f44d3e6eabcb (patch) | |
tree | cf60e4dcdc0564ebc15e85682089a8ea03823e06 /array.c | |
parent | 748c14b3c15972d7a975eef644c8d116ef3654ec (diff) | |
download | ruby-c9aabf37eadfdbbdcc5bc3fbf775f44d3e6eabcb.tar.gz ruby-c9aabf37eadfdbbdcc5bc3fbf775f44d3e6eabcb.tar.xz ruby-c9aabf37eadfdbbdcc5bc3fbf775f44d3e6eabcb.zip |
* array.c (ary_make_shared): returns shared root array itself, and
frozen array can be shared.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@22231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 18 |
1 files changed, 15 insertions, 3 deletions
@@ -211,14 +211,16 @@ rb_ary_unshare(VALUE ary) } static inline void -rb_ary_unshare_safe(VALUE ary) { +rb_ary_unshare_safe(VALUE ary) +{ if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) { rb_ary_unshare(ary); } } static VALUE -rb_ary_increment_share(VALUE shared) { +rb_ary_increment_share(VALUE shared) +{ int num = ARY_SHARED_NUM(shared); if (num >= 0) { ARY_SET_SHARED_NUM(shared, num + 1); @@ -390,6 +392,15 @@ ary_make_shared(VALUE ary) if (ARY_SHARED_P(ary)) { return ARY_SHARED(ary); } + else if (ARY_SHARED_ROOT_P(ary)) { + return ary; + } + else if (OBJ_FROZEN(ary)) { + ary_resize_capa(ary, ARY_HEAP_LEN(ary)); + FL_SET_SHARED_ROOT(ary); + ARY_SET_SHARED_NUM(ary, 0); + return ary; + } else { NEWOBJ(shared, struct RArray); OBJSETUP(shared, 0, T_ARRAY); @@ -2389,7 +2400,8 @@ rb_ary_replace(VALUE copy, VALUE orig) VALUE shared = ary_make_shared(orig); if (ARY_OWNS_HEAP_P(copy)) { xfree(RARRAY_PTR(copy)); - } else { + } + else { rb_ary_unshare_safe(copy); } FL_UNSET_EMBED(copy); |