summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--array.c7
-rw-r--r--gc.c5
3 files changed, 14 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 88d1d17203..2a761f3f86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Sep 25 08:14:43 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_shift): should clear shifting top element.
+ [ruby-talk:216055]
+
+ * array.c (rb_ary_shift): avoid creating shared object if array
+ size is small.
+
Mon Sep 25 08:11:35 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* random.c (rb_f_rand): RDoc typo fix. a patch from Frederick
diff --git a/array.c b/array.c
index d154bf35e9..87044a856a 100644
--- a/array.c
+++ b/array.c
@@ -578,11 +578,14 @@ rb_ary_shift(VALUE ary)
rb_ary_modify_check(ary);
if (RARRAY_LEN(ary) == 0) return Qnil;
top = RARRAY_PTR(ary)[0];
- if (ARY_EMBED_P(ary)) {
+ if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+1, VALUE, RARRAY_LEN(ary));
- ARY_SET_EMBED_LEN(ary, RARRAY_LEN(ary)-1);
+ ARY_SET_LEN(ary, RARRAY_LEN(ary)-1);
}
else {
+ if (!FL_TEST(ary, ELTS_SHARED)) {
+ RARRAY(ary)->ptr[0] = Qnil;
+ }
ary_make_shared(ary);
RARRAY(ary)->as.heap.ptr++; /* shift ptr */
RARRAY(ary)->as.heap.len--;
diff --git a/gc.c b/gc.c
index d7e431a704..6c83bd43b5 100644
--- a/gc.c
+++ b/gc.c
@@ -866,10 +866,6 @@ gc_mark_children(VALUE ptr, int lev)
ptr = (VALUE)obj->as.node.u1.node;
goto again;
- case NODE_POSTEXE: /* 2 */
- ptr = (VALUE)obj->as.node.u2.node;
- goto again;
-
case NODE_SCOPE: /* 2,3 */
case NODE_CDECL:
gc_mark((VALUE)obj->as.node.u3.node, lev);
@@ -896,6 +892,7 @@ gc_mark_children(VALUE ptr, int lev)
case NODE_ERRINFO:
case NODE_ATTRSET:
case NODE_BLOCK_ARG:
+ case NODE_POSTEXE:
break;
case NODE_ALLOCA:
mark_locations_array((VALUE*)obj->as.node.u1.value,