summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-11 06:47:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-11 06:47:12 +0000
commitf23292afb45db6a52e8e4949620162a230a2eea7 (patch)
treecf60e4dcdc0564ebc15e85682089a8ea03823e06 /array.c
parent9da4ec12dffb1b5b281ef854e57c95c1a4f51fc7 (diff)
* array.c (ary_make_shared): returns shared root array itself, and
frozen array can be shared. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r--array.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/array.c b/array.c
index c35e113851..35023f3209 100644
--- a/array.c
+++ b/array.c
@@ -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);