[前][次][番号順一覧][スレッド一覧]

ruby-changes:8296

From: wanabe <ko1@a...>
Date: Fri, 17 Oct 2008 22:09:53 +0900 (JST)
Subject: [ruby-changes:8296] Ruby:r19824 (trunk): * array.c: recycle shared-array when it isn't referenced.

wanabe	2008-10-17 22:09:33 +0900 (Fri, 17 Oct 2008)

  New Revision: 19824

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19824

  Log:
    * array.c: recycle shared-array when it isn't referenced.

  Modified files:
    trunk/ChangeLog
    trunk/array.c

Index: array.c
===================================================================
--- array.c	(revision 19823)
+++ array.c	(revision 19824)
@@ -111,7 +111,8 @@
     } \
 } while (0)
 
-#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : RARRAY(ary)->as.heap.aux.capa)
+#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \
+		       ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : RARRAY(ary)->as.heap.aux.capa)
 #define ARY_SET_CAPA(ary, n) do { \
     assert(!ARY_EMBED_P(ary)); \
     assert(!ARY_SHARED_P(ary)); \
@@ -123,8 +124,21 @@
 #define ARY_SET_SHARED(ary, value) do { \
     assert(!ARY_EMBED_P(ary)); \
     assert(ARY_SHARED_P(ary)); \
+    assert(ARY_SHARED_ROOT_P(value)); \
     RARRAY(ary)->as.heap.aux.shared = (value); \
 } while (0)
+#define RARRAY_SHARED_ROOT_FLAG FL_USER5
+#define ARY_SHARED_ROOT_P(ary) (FL_TEST(ary, RARRAY_SHARED_ROOT_FLAG))
+#define ARY_SHARED_NUM(ary) \
+    (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
+#define ARY_SET_SHARED_NUM(ary, value) do { \
+    assert(ARY_SHARED_ROOT_P(ary)); \
+    RARRAY(ary)->as.heap.aux.capa = (value); \
+} while (0)
+#define FL_SET_SHARED_ROOT(ary) do { \
+    assert(!ARY_EMBED_P(ary)); \
+    FL_SET(ary, RARRAY_SHARED_ROOT_FLAG); \
+} while (0)
 
 static void
 ary_resize_capa(VALUE ary, long capacity)
@@ -158,7 +172,48 @@
     }
 }
 
+static void
+rb_ary_decrement_share(VALUE shared)
+{
+    if (shared) {
+	int num = ARY_SHARED_NUM(shared) - 1;
+	if (num == 0) {
+	    rb_ary_free(shared);
+	    rb_gc_force_recycle(shared);
+	}
+	else if (num > 0) {
+	    ARY_SET_SHARED_NUM(shared, num);
+	}
+    }
+}
+
+static void
+rb_ary_unshare(VALUE ary)
+{
+    VALUE shared = RARRAY(ary)->as.heap.aux.shared;
+    rb_ary_decrement_share(shared);
+    FL_UNSET_SHARED(ary);
+}
+
 static inline void
+rb_ary_unshare_safe(VALUE ary) {
+    if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
+	rb_ary_unshare(ary);
+    }
+}
+
+static void
+rb_ary_set_shared(VALUE ary, VALUE shared)
+{
+    int num = ARY_SHARED_NUM(shared);
+    if (num >= 0) {
+	ARY_SET_SHARED_NUM(shared, num + 1);
+    }
+    FL_SET_SHARED(ary);
+    ARY_SET_SHARED(ary, shared);
+}
+
+static inline void
 rb_ary_modify_check(VALUE ary)
 {
     if (OBJ_FROZEN(ary)) rb_error_frozen("array");
@@ -174,16 +229,18 @@
         long len = RARRAY_LEN(ary);
         if (len <= RARRAY_EMBED_LEN_MAX) {
             VALUE *ptr = ARY_HEAP_PTR(ary);
+            VALUE shared = ARY_SHARED(ary);
             FL_UNSET_SHARED(ary);
             FL_SET_EMBED(ary);
             MEMCPY(ARY_EMBED_PTR(ary), ptr, VALUE, len);
+            rb_ary_decrement_share(shared);
             ARY_SET_EMBED_LEN(ary, len);
         }
         else {
             VALUE *ptr = ALLOC_N(VALUE, len);
-            FL_UNSET_SHARED(ary);
+            MEMCPY(ptr, RARRAY_PTR(ary), VALUE, len);
+            rb_ary_unshare(ary);
             ARY_SET_CAPA(ary, len);
-            MEMCPY(ptr, RARRAY_PTR(ary), VALUE, len);
             ARY_SET_PTR(ary, ptr);
         }
     }
@@ -319,7 +376,8 @@
 
         ARY_SET_LEN((VALUE)shared, RARRAY_LEN(ary));
         ARY_SET_PTR((VALUE)shared, RARRAY_PTR(ary));
-        ARY_SET_CAPA((VALUE)shared, ARY_CAPA(ary));
+	FL_SET_SHARED_ROOT(shared);
+	ARY_SET_SHARED_NUM((VALUE)shared, 1);
 	FL_SET_SHARED(ary);
 	ARY_SET_SHARED(ary, (VALUE)shared);
 	OBJ_FREEZE(shared);
@@ -435,7 +493,7 @@
 	if (ARY_OWNS_HEAP_P(ary) && RARRAY_PTR(ary)) {
 	    xfree(RARRAY_PTR(ary));
 	}
-        FL_UNSET_SHARED(ary);
+        rb_ary_unshare_safe(ary);
         FL_SET_EMBED(ary);
 	ARY_SET_EMBED_LEN(ary, 0);
 	if (rb_block_given_p()) {
@@ -555,8 +613,7 @@
         shared = ary_make_shared(ary);
         ARY_SET_PTR(result, RARRAY_PTR(ary));
         ARY_SET_LEN(result, RARRAY_LEN(ary));
-        FL_SET_SHARED(result);
-        ARY_SET_SHARED(result, shared);
+        rb_ary_set_shared(result, shared);
 
         ARY_INCREASE_PTR(result, offset);
         ARY_SET_LEN(result, len);
@@ -1705,7 +1762,7 @@
             if (RARRAY_PTR(ary) != RARRAY_PTR(tmp)) {
                 assert(!ARY_SHARED_P(tmp));
                 if (ARY_SHARED_P(ary)) {
-                    FL_UNSET_SHARED(ary);
+                    rb_ary_unshare(ary);
                 }
                 else {
                     xfree(ARY_HEAP_PTR(ary));
@@ -2251,23 +2308,34 @@
 
     if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
         VALUE *ptr;
-        if (ARY_OWNS_HEAP_P(copy)) xfree(RARRAY_PTR(copy));
-        FL_UNSET_SHARED(copy);
+        VALUE shared = 0;
+        
+        if (ARY_OWNS_HEAP_P(copy)) {
+            xfree(RARRAY_PTR(copy));
+        }
+        else if (ARY_SHARED_P(copy)) {
+            shared = ARY_SHARED(copy);
+            FL_UNSET_SHARED(copy);
+        }
         FL_SET_EMBED(copy);
         ptr = RARRAY_PTR(orig);
         MEMCPY(RARRAY_PTR(copy), ptr, VALUE, RARRAY_LEN(orig));
+        if (shared) {
+            rb_ary_decrement_share(shared);
+        }
         ARY_SET_LEN(copy, RARRAY_LEN(orig));
     }
     else {
         VALUE shared = ary_make_shared(orig);
         if (ARY_OWNS_HEAP_P(copy)) {
             xfree(RARRAY_PTR(copy));
+        } else {
+            rb_ary_unshare_safe(copy);
         }
         FL_UNSET_EMBED(copy);
-        FL_SET_SHARED(copy);
         ARY_SET_PTR(copy, RARRAY_PTR(orig));
         ARY_SET_LEN(copy, RARRAY_LEN(orig));
-        ARY_SET_SHARED(copy, shared);
+        rb_ary_set_shared(copy, shared);
     }
     return copy;
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 19823)
+++ ChangeLog	(revision 19824)
@@ -1,3 +1,7 @@
+Fri Oct 17 22:04:38 2008  wanabe  <s.wanabe@g...>
+
+	* array.c: recycle shared-array when it isn't referenced.
+
 Fri Oct 17 19:46:20 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* tool/ifchange, win32/ifchange.bat: --timestamp option added.

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]