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

ruby-changes:7557

From: nobu <ko1@a...>
Date: Wed, 3 Sep 2008 16:53:32 +0900 (JST)
Subject: [ruby-changes:7557] Ruby:r19078 (ruby_1_8): * gc.c (rb_mark_set): new function to mark keys.

nobu	2008-09-03 16:53:19 +0900 (Wed, 03 Sep 2008)

  New Revision: 19078

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

  Log:
    * gc.c (rb_mark_set): new function to mark keys.
    
    * marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
      data entries.  backport from trunk r13527,r13528,r13961,r16533.
      [ruby-dev:36082]

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/gc.c
    branches/ruby_1_8/intern.h
    branches/ruby_1_8/marshal.c
    branches/ruby_1_8/test/ruby/marshaltestlib.rb
    branches/ruby_1_8/test/ruby/test_marshal.rb

Index: ruby_1_8/intern.h
===================================================================
--- ruby_1_8/intern.h	(revision 19077)
+++ ruby_1_8/intern.h	(revision 19078)
@@ -257,6 +257,7 @@
 char *rb_source_filename _((const char*));
 void rb_gc_mark_locations _((VALUE*, VALUE*));
 void rb_mark_tbl _((struct st_table*));
+void rb_mark_set _((struct st_table*));
 void rb_mark_hash _((struct st_table*));
 void rb_gc_mark_maybe _((VALUE));
 void rb_gc_mark _((VALUE));
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 19077)
+++ ruby_1_8/ChangeLog	(revision 19078)
@@ -1,3 +1,11 @@
+Wed Sep  3 16:53:17 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (rb_mark_set): new function to mark keys.
+
+	* marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
+	  data entries.  backport from trunk r13527,r13528,r13961,r16533.
+	  [ruby-dev:36082]
+
 Tue Sep  2 23:39:45 2008  Yusuke Endoh  <mame@t...>
 
 	* marshal.c (w_object): add a check for modification of array during
Index: ruby_1_8/marshal.c
===================================================================
--- ruby_1_8/marshal.c	(revision 19077)
+++ ruby_1_8/marshal.c	(revision 19078)
@@ -84,22 +84,13 @@
 static ID s_dump_data, s_load_data, s_alloc, s_call;
 static ID s_getc, s_read, s_write, s_binmode;
 
-static void
-reentrant_check(obj, sym)
-    VALUE obj;
-    ID sym;
-{
-    if (obj && RBASIC(obj)->klass) {
-        rb_raise(rb_eRuntimeError, "%s reentered", rb_id2name(sym));
-    }
-}
-
 struct dump_arg {
     VALUE obj;
     VALUE str, dest;
     st_table *symbols;
     st_table *data;
     int taint;
+    VALUE wrapper;
 };
 
 struct dump_call_arg {
@@ -108,6 +99,27 @@
     int limit;
 };
 
+static void
+check_dump_arg(arg, sym)
+    struct dump_arg *arg;
+    ID sym;
+{
+    if (!DATA_PTR(arg->wrapper)) {
+        rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
+		 rb_id2name(sym));
+    }
+}
+
+static void
+mark_dump_arg(ptr)
+    void *ptr;
+{
+    struct dump_arg *p = ptr;
+    if (!ptr)
+        return;
+    rb_mark_set(p->data);
+}
+
 static VALUE
 class2path(klass)
     VALUE klass;
@@ -515,7 +527,7 @@
 	    volatile VALUE v;
 
 	    v = rb_funcall(obj, s_mdump, 0, 0);
-	    reentrant_check(arg->str, s_mdump);
+	    check_dump_arg(arg, s_mdump);
 	    w_class(TYPE_USRMARSHAL, obj, arg, Qfalse);
 	    w_object(v, arg, limit);
 	    if (ivtbl) w_ivar(0, &c_arg);
@@ -525,7 +537,7 @@
 	    VALUE v;
 
 	    v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));
-	    reentrant_check(arg->str, s_dump);
+	    check_dump_arg(arg, s_dump);
 	    if (TYPE(v) != T_STRING) {
 		rb_raise(rb_eTypeError, "_dump() must return string");
 	    }
@@ -671,7 +683,7 @@
 			     rb_obj_classname(obj));
 		}
 		v = rb_funcall(obj, s_dump_data, 0);
-		reentrant_check(arg->str, s_dump_data);
+		check_dump_arg(arg, s_dump_data);
 		w_class(TYPE_DATA, obj, arg, Qtrue);
 		w_object(v, arg, limit);
 	    }
@@ -704,9 +716,11 @@
 dump_ensure(arg)
     struct dump_arg *arg;
 {
-    if (RBASIC(arg->str)->klass) return 0; /* ignore reentrant */
+    if (!DATA_PTR(arg->wrapper)) return 0;
     st_free_table(arg->symbols);
     st_free_table(arg->data);
+    DATA_PTR(arg->wrapper) = 0;
+    arg->wrapper = 0;
     if (arg->taint) {
 	OBJ_TAINT(arg->str);
     }
@@ -773,7 +787,7 @@
 	arg.dest = port;
 	if (rb_respond_to(port, s_binmode)) {
 	    rb_funcall2(port, s_binmode, 0, 0);
-	    reentrant_check(arg.str, s_dump_data);
+	    check_dump_arg(&arg, s_dump_data);
 	}
     }
     else {
@@ -783,6 +797,7 @@
     arg.symbols = st_init_numtable();
     arg.data    = st_init_numtable();
     arg.taint   = Qfalse;
+    arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg);
     c_arg.obj   = obj;
     c_arg.arg   = &arg;
     c_arg.limit = limit;
@@ -800,11 +815,33 @@
     VALUE src;
     long offset;
     st_table *symbols;
-    VALUE data;
+    st_table *data;
     VALUE proc;
     int taint;
+    VALUE wrapper;
 };
 
+static void
+check_load_arg(arg, sym)
+    struct load_arg *arg;
+    ID sym;
+{
+    if (!DATA_PTR(arg->wrapper)) {
+        rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
+		 rb_id2name(sym));
+    }
+}
+
+static void
+mark_load_arg(ptr)
+    void *ptr;
+{
+    struct load_arg *p = ptr;
+    if (!ptr)
+        return;
+    rb_mark_tbl(p->data);
+}
+
 static VALUE r_object _((struct load_arg *arg));
 
 static int
@@ -824,7 +861,7 @@
     else {
 	VALUE src = arg->src;
 	VALUE v = rb_funcall2(src, s_getc, 0, 0);
-	reentrant_check(arg->data, s_getc);
+	check_load_arg(arg, s_getc);
 	if (NIL_P(v)) rb_eof_error();
 	c = (unsigned char)FIX2INT(v);
     }
@@ -905,7 +942,7 @@
 	VALUE src = arg->src;
 	VALUE n = LONG2NUM(len);
 	str = rb_funcall2(src, s_read, 1, &n);
-	reentrant_check(arg->data, s_read);
+	check_load_arg(arg, s_read);
 	if (NIL_P(str)) goto too_short;
 	StringValue(str);
 	if (RSTRING(str)->len != len) goto too_short;
@@ -968,7 +1005,7 @@
     VALUE v;
     struct load_arg *arg;
 {
-    rb_hash_aset(arg->data, INT2FIX(RHASH(arg->data)->tbl->num_entries), v);
+    st_insert(arg->data, arg->data->num_entries, (st_data_t)v);
     if (arg->taint) OBJ_TAINT(v);
     return v;
 }
@@ -1024,14 +1061,15 @@
     VALUE v = Qnil;
     int type = r_byte(arg);
     long id;
+    st_data_t link;
 
     switch (type) {
       case TYPE_LINK:
 	id = r_long(arg);
-	v = rb_hash_aref(arg->data, LONG2FIX(id));
-	if (NIL_P(v)) {
+ 	if (!st_lookup(arg->data, (st_data_t)id, &link)) {
 	    rb_raise(rb_eArgError, "dump format error (unlinked)");
 	}
+	v = (st_data_t)link;
 	return v;
 
       case TYPE_IVAR:
@@ -1256,7 +1294,7 @@
 		*ivp = Qfalse;
 	    }
 	    v = rb_funcall(klass, s_load, 1, data);
-	    reentrant_check(arg->data, s_load);
+	    check_load_arg(arg, s_load);
 	    r_entry(v, arg);
 	}
         break;
@@ -1280,7 +1318,7 @@
 	    r_entry(v, arg);
 	    data = r_object(arg);
 	    rb_funcall(v, s_mload, 1, data);
-	    reentrant_check(arg->data, s_mload);
+	    check_load_arg(arg, s_mload);
 	}
         break;
 
@@ -1307,7 +1345,7 @@
 		   warn = Qfalse;
 	       }
 	       v = rb_funcall(klass, s_alloc, 0);
-	       reentrant_check(arg->data, s_alloc);
+	       check_load_arg(arg, s_alloc);
            }
 	   else {
 	       v = rb_obj_alloc(klass);
@@ -1322,7 +1360,7 @@
                         rb_class2name(klass));
            }
            rb_funcall(v, s_load_data, 1, r_object0(arg, 0, 0, extmod));
-	   reentrant_check(arg->data, s_load_data);
+	   check_load_arg(arg, s_load_data);
        }
        break;
 
@@ -1366,7 +1404,7 @@
     }
     if (proc) {
 	rb_funcall(proc, s_call, 1, v);
-	reentrant_check(arg->data, s_call);
+	check_load_arg(arg, s_call);
     }
     return v;
 }
@@ -1389,8 +1427,11 @@
 load_ensure(arg)
     struct load_arg *arg;
 {
-    if (RBASIC(arg->data)->klass) return 0; /* ignore reentrant */
+    if (!DATA_PTR(arg->wrapper)) return 0;
     st_free_table(arg->symbols);
+    st_free_table(arg->data);
+    DATA_PTR(arg->wrapper) = 0;
+    arg->wrapper = 0;
     return 0;
 }
 
@@ -1432,7 +1473,10 @@
     }
     arg.src = port;
     arg.offset = 0;
-    arg.data = 0;
+    arg.symbols = st_init_numtable();
+    arg.data    = st_init_numtable();
+    arg.proc = 0;
+    arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg);
 
     major = r_byte(&arg);
     minor = r_byte(&arg);
@@ -1447,11 +1491,7 @@
 		MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
     }
 
-    arg.symbols = st_init_numtable();
-    arg.data   = rb_hash_new();
-    RBASIC(arg.data)->klass = 0;
-    if (NIL_P(proc)) arg.proc = 0;
-    else             arg.proc = proc;
+    if (!NIL_P(proc)) arg.proc = proc;
     v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);
     RBASIC(arg.data)->klass = rb_cHash;
 
Index: ruby_1_8/test/ruby/test_marshal.rb
===================================================================
--- ruby_1_8/test/ruby/test_marshal.rb	(revision 19077)
+++ ruby_1_8/test/ruby/test_marshal.rb	(revision 19078)
@@ -12,11 +12,17 @@
   include MarshalTestLib
 
   def encode(o)
+    stress, GC.stress = GC.stress, true
     Marshal.dump(o)
+  ensure
+    GC.stress = stress
   end
 
   def decode(s)
+    stress, GC.stress = GC.stress, true
     Marshal.load(s)
+  ensure
+    GC.stress = stress
   end
 
   def fact(n)
Index: ruby_1_8/test/ruby/marshaltestlib.rb
===================================================================
--- ruby_1_8/test/ruby/marshaltestlib.rb	(revision 19077)
+++ ruby_1_8/test/ruby/marshaltestlib.rb	(revision 19078)
@@ -193,6 +193,12 @@
     1.instance_eval { remove_instance_variable("@iv") }
   end
 
+  def test_fixnum_64bit
+    obj = [1220278665, 1220278662, 1220278661, 1220278661, 1220278656]
+
+    marshal_equal(obj)
+  end
+
   def test_float
     marshal_equal(-1.0)
     marshal_equal(0.0)
Index: ruby_1_8/gc.c
===================================================================
--- ruby_1_8/gc.c	(revision 19077)
+++ ruby_1_8/gc.c	(revision 19078)
@@ -734,6 +734,31 @@
 }
 
 static int
+mark_key(key, value, lev)
+    VALUE key, value;
+    int lev;
+{
+    gc_mark(key, lev);
+    return ST_CONTINUE;
+}
+
+static void
+mark_set(tbl, lev)
+    st_table *tbl;
+    int lev;
+{
+    if (!tbl) return;
+    st_foreach(tbl, mark_key, lev);
+}
+
+void
+rb_mark_set(tbl)
+    st_table *tbl;
+{
+    mark_set(tbl, 0);
+}
+
+static int
 mark_keyvalue(key, value, lev)
     VALUE key;
     VALUE value;

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

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