summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--array.c18
2 files changed, 20 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index bac9758b39..00bad3641b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Feb 11 15:47:10 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * array.c (ary_make_shared): returns shared root array itself, and
+ frozen array can be shared.
+
Wed Feb 11 14:46:16 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* insns.def (setspecial, putstring): fixed typos in rdoc.
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);