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

ruby-changes:6705

From: nobu <ko1@a...>
Date: Fri, 25 Jul 2008 23:49:56 +0900 (JST)
Subject: [ruby-changes:6705] Ruby:r18221 (trunk): * gc.c (gc_sweep, obj_free, run_final): defer finalizers of IO and

nobu	2008-07-25 23:48:12 +0900 (Fri, 25 Jul 2008)

  New Revision: 18221

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

  Log:
    * gc.c (gc_sweep, obj_free, run_final): defer finalizers of IO and
      Data.  [ruby-dev:35578]

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 18220)
+++ ChangeLog	(revision 18221)
@@ -1,3 +1,8 @@
+Fri Jul 25 23:48:10 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (gc_sweep, obj_free, run_final): defer finalizers of IO and
+	  Data.  [ruby-dev:35578]
+
 Fri Jul 25 23:35:18 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/webrick/httputils.rb (WEBrick::HTTPUtils#split_header_value):
Index: gc.c
===================================================================
--- gc.c	(revision 18220)
+++ gc.c	(revision 18221)
@@ -1316,6 +1316,9 @@
 	}
 	break;
 
+      case T_UNDEF:
+	break;
+
       default:
 	rb_bug("rb_gc_mark(): unknown data type 0x%lx(%p) %s",
 	       obj->as.basic.flags & T_MASK, obj,
@@ -1323,7 +1326,7 @@
     }
 }
 
-static void obj_free(rb_objspace_t *, VALUE);
+static int obj_free(rb_objspace_t *, VALUE);
 
 static void
 finalize_list(rb_objspace_t *objspace, RVALUE *p)
@@ -1401,11 +1404,9 @@
 	p = heaps[i].slot; pend = p + heaps[i].limit;
 	while (p < pend) {
 	    if (!(p->as.basic.flags & FL_MARK)) {
-		if (p->as.basic.flags) {
-		    obj_free(objspace, (VALUE)p);
-		}
-		if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
-		    p->as.free.flags = FL_MARK; /* remain marked */
+		if (p->as.basic.flags && obj_free(objspace, (VALUE)p) ||
+		    need_call_final && FL_TEST(p, FL_FINALIZE)) {
+		    p->as.free.flags |= FL_MARK; /* remain marked */
 		    p->as.free.next = final_list;
 		    final_list = p;
 		}
@@ -1469,7 +1470,7 @@
     freelist = RANY(p);
 }
 
-static void
+static int
 obj_free(rb_objspace_t *objspace, VALUE obj)
 {
     switch (RANY(obj)->as.basic.flags & T_MASK) {
@@ -1526,7 +1527,9 @@
 		xfree(DATA_PTR(obj));
 	    }
 	    else if (RANY(obj)->as.data.dfree) {
-		(*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
+		RANY(obj)->as.basic.flags &= ~T_MASK;
+		RANY(obj)->as.basic.flags |= T_UNDEF;
+		return 1;
 	    }
 	}
 	break;
@@ -1541,7 +1544,12 @@
 	break;
       case T_FILE:
 	if (RANY(obj)->as.file.fptr) {
-	    rb_io_fptr_finalize(RANY(obj)->as.file.fptr);
+	    rb_io_t *fptr = RANY(obj)->as.file.fptr;
+	    RANY(obj)->as.basic.flags &= ~T_MASK;
+	    RANY(obj)->as.basic.flags |= T_UNDEF;
+	    RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;
+	    RDATA(obj)->data = fptr;
+	    return 1;
 	}
 	break;
       case T_RATIONAL:
@@ -1570,7 +1578,7 @@
 	    xfree(RANY(obj)->as.node.u1.node);
 	    break;
 	}
-	return;			/* no need to free iv_tbl */
+	break;			/* no need to free iv_tbl */
 
       case T_STRUCT:
 	if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
@@ -1579,10 +1587,15 @@
 	}
 	break;
 
+      case T_UNDEF:
+	break;
+
       default:
 	rb_bug("gc_sweep(): unknown data type 0x%lx(%p)",
 	       RANY(obj)->as.basic.flags & T_MASK, (void*)obj);
     }
+    RANY(obj)->as.basic.flags &= ~T_MASK;
+    return 0;
 }
 
 #ifdef __GNUC__
@@ -1854,6 +1867,7 @@
 		  case T_NONE:
 		  case T_ICLASS:
 		  case T_NODE:
+		  case T_UNDEF:
 		    continue;
 		  case T_CLASS:
 		    if (FL_TEST(p, FL_SINGLETON)) continue;
@@ -2009,6 +2023,9 @@
 
     objid = rb_obj_id(obj);	/* make obj into id */
     rb_thread_critical = Qtrue;
+    if ((RANY(obj)->as.basic.flags & T_MASK) == T_UNDEF) {
+	(*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
+    }
     args[1] = 0;
     args[2] = (VALUE)rb_safe_level();
     if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {

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

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