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

ruby-changes:6219

From: nobu <ko1@a...>
Date: Mon, 30 Jun 2008 18:57:28 +0900 (JST)
Subject: [ruby-changes:6219] Ruby:r17732 (trunk): * gc.c (gc_finalize_deferred): allow object allocation in finalizers.

nobu	2008-06-30 18:57:07 +0900 (Mon, 30 Jun 2008)

  New Revision: 17732

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

  Log:
    * gc.c (gc_finalize_deferred): allow object allocation in finalizers.
    
    * gc.c (rb_gc_call_finalizer_at_exit): ditto.



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

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=17732&r2=17731&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/gc.c?r1=17732&r2=17731&diff_format=u

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 17731)
+++ ChangeLog	(revision 17732)
@@ -1,3 +1,9 @@
+Mon Jun 30 18:57:05 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (gc_finalize_deferred): allow object allocation in finalizers.
+
+	* gc.c (rb_gc_call_finalizer_at_exit): ditto.
+
 Mon Jun 30 14:41:36 2008  NAKAMURA Usaku  <usa@r...>
 
 	* gc.c (rb_newobj): prohibit call of rb_newobj() during gc when
Index: gc.c
===================================================================
--- gc.c	(revision 17731)
+++ gc.c	(revision 17732)
@@ -168,7 +168,6 @@
 	int during_gc;
     } flags;
     struct {
-	int need_call;
 	st_table *table;
 	RVALUE *deferred;
     } final;
@@ -203,7 +202,6 @@
 #define heaps_freed		objspace->heap.freed
 #define dont_gc 		objspace->flags.dont_gc
 #define during_gc		objspace->flags.during_gc
-#define need_call_final 	objspace->final.need_call
 #define finalizer_table 	objspace->final.table
 #define deferred_final_list	objspace->final.deferred
 #define mark_stack		objspace->markstack.buffer
@@ -212,6 +210,8 @@
 #define global_List		objspace->global_list
 #define ruby_gc_stress		objspace->gc_stress
 
+#define need_call_final 	(finalizer_table && finalizer_table->num_entries)
+
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
 rb_objspace_t *
 rb_objspace_alloc(void)
@@ -1364,8 +1364,6 @@
     }
 }
 
-void rb_gc_abort_threads(void);
-
 static void
 gc_sweep(rb_objspace_t *objspace)
 {
@@ -1953,7 +1951,6 @@
 	rb_raise(rb_eArgError, "wrong type argument %s (should be callable)",
 		 rb_obj_classname(block));
     }
-    need_call_final = 1;
     FL_SET(obj, FL_FINALIZE);
 
     block = rb_ary_new3(2, INT2FIX(rb_safe_level()), block);
@@ -2022,13 +2019,11 @@
 {
     RVALUE *p = deferred_final_list;
 
-    during_gc++;
     deferred_final_list = 0;
     if (p) {
 	finalize_list(objspace, p);
     }
     free_unused_heaps(objspace);
-    during_gc = 0;
 }
 
 void
@@ -2037,6 +2032,18 @@
     gc_finalize_deferred(&rb_objspace);
 }
 
+static int
+chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
+{
+    RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
+    if (p->as.basic.flags & FL_FINALIZE) {
+	p->as.free.flags = FL_MARK; /* remain marked */
+	p->as.free.next = *final_list;
+	*final_list = p;
+    }
+    return ST_DELETE;
+}
+
 void
 rb_gc_call_finalizer_at_exit(void)
 {
@@ -2044,25 +2051,17 @@
     RVALUE *p, *pend;
     size_t i;
 
-    /* finalizers are part of garbage collection */
-    during_gc++;
     /* run finalizers */
     if (need_call_final) {
-	p = deferred_final_list;
-	deferred_final_list = 0;
-	finalize_list(objspace, p);
-	for (i = 0; i < heaps_used; i++) {
-	    p = heaps[i].slot; pend = p + heaps[i].limit;
-	    while (p < pend) {
-		if (FL_TEST(p, FL_FINALIZE)) {
-		    FL_UNSET(p, FL_FINALIZE);
-		    p->as.basic.klass = 0;
-		    run_final(objspace, (VALUE)p);
-		}
-		p++;
-	    }
+	while ((p = deferred_final_list) != 0) {
+	    deferred_final_list = 0;
+	    finalize_list(objspace, p);
+	    st_foreach(finalizer_table, chain_finalized_object,
+		       (st_data_t)&deferred_final_list);
 	}
     }
+    /* finalizers are part of garbage collection */
+    during_gc++;
     /* run data object's finalizers */
     for (i = 0; i < heaps_used; i++) {
 	p = heaps[i].slot; pend = p + heaps[i].limit;

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

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