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

ruby-changes:29247

From: ko1 <ko1@a...>
Date: Fri, 14 Jun 2013 18:24:34 +0900 (JST)
Subject: [ruby-changes:29247] ko1:r41299 (trunk): * class.c, include/ruby/ruby.h: add write barriers for T_CLASS,

ko1	2013-06-14 18:23:54 +0900 (Fri, 14 Jun 2013)

  New Revision: 41299

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

  Log:
    * class.c, include/ruby/ruby.h: add write barriers for T_CLASS,
      T_MODULE, T_ICLASS.
    * constant.h: constify rb_const_entry_t::value and file to detect
      assignment.
    * variable.c, internal.h (rb_st_insert_id_and_value, rb_st_copy):
      added. update table with write barrier.
    * method.h: constify some variables to detect assignment.
    * object.c (init_copy): add WBs.
    * variable.c: ditto.
    * vm_method.c (rb_add_method): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/constant.h
    trunk/include/ruby/ruby.h
    trunk/internal.h
    trunk/method.h
    trunk/object.c
    trunk/variable.c
    trunk/vm_method.c

Index: method.h
===================================================================
--- method.h	(revision 41298)
+++ method.h	(revision 41299)
@@ -68,7 +68,7 @@ typedef struct rb_method_cfunc_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L68
 
 typedef struct rb_method_attr_struct {
     ID id;
-    VALUE location;
+    const VALUE location;
 } rb_method_attr_t;
 
 typedef struct rb_iseq_struct rb_iseq_t;
@@ -77,10 +77,10 @@ typedef struct rb_method_definition_stru https://github.com/ruby/ruby/blob/trunk/method.h#L77
     rb_method_type_t type; /* method type */
     ID original_id;
     union {
-	rb_iseq_t *iseq;            /* should be mark */
+	rb_iseq_t * const iseq;            /* should be mark */
 	rb_method_cfunc_t cfunc;
 	rb_method_attr_t attr;
-	VALUE proc;                 /* should be mark */
+	const VALUE proc;                 /* should be mark */
 	enum method_optimized_type {
 	    OPTIMIZED_METHOD_TYPE_SEND,
 	    OPTIMIZED_METHOD_TYPE_CALL,
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 41298)
+++ include/ruby/ruby.h	(revision 41299)
@@ -700,17 +700,18 @@ VALUE rb_obj_setup(VALUE obj, VALUE klas https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L700
 #ifndef RGENGC_WB_PROTECTED_ARRAY
 #define RGENGC_WB_PROTECTED_ARRAY 1
 #endif
-
 #ifndef RGENGC_WB_PROTECTED_HASH
 #define RGENGC_WB_PROTECTED_HASH 1
 #endif
-
 #ifndef RGENGC_WB_PROTECTED_STRING
 #define RGENGC_WB_PROTECTED_STRING 1
 #endif
 #ifndef RGENGC_WB_PROTECTED_OBJECT
 #define RGENGC_WB_PROTECTED_OBJECT 1
 #endif
+#ifndef RGENGC_WB_PROTECTED_CLASS
+#define RGENGC_WB_PROTECTED_CLASS 1
+#endif
 #ifndef RGENGC_WB_PROTECTED_FLOAT
 #define RGENGC_WB_PROTECTED_FLOAT 1
 #endif
@@ -1228,6 +1229,7 @@ struct RBignum { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1229
 #define OBJ_PROMOTED(x)             (SPECIAL_CONST_P(x) ? 0 : FL_TEST_RAW((x), FL_OLDGEN))
 #define OBJ_WB_PROTECTED(x)         (SPECIAL_CONST_P(x) ? 1 : FL_TEST_RAW((x), FL_WB_PROTECTED))
 #define OBJ_WB_GIVEUP(x)            rb_obj_wb_giveup(x, __FILE__, __LINE__)
+#define OBJ_WB_
 
 void rb_gc_writebarrier(VALUE a, VALUE b);
 void rb_gc_giveup_promoted_writebarrier(VALUE obj);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41298)
+++ ChangeLog	(revision 41299)
@@ -1,3 +1,22 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jun 14 18:18:07 2013  Koichi Sasada  <ko1@a...>
+
+	* class.c, include/ruby/ruby.h: add write barriers for T_CLASS,
+	  T_MODULE, T_ICLASS.
+
+	* constant.h: constify rb_const_entry_t::value and file to detect
+	  assignment.
+
+	* variable.c, internal.h (rb_st_insert_id_and_value, rb_st_copy): 
+	  added. update table with write barrier.
+
+	* method.h: constify some variables to detect assignment.
+
+	* object.c (init_copy): add WBs.
+
+	* variable.c: ditto.
+
+	* vm_method.c (rb_add_method): ditto.
+
 Fri Jun 14 14:33:47 2013  Shugo Maeda  <shugo@r...>
 
 	* NEWS: add a note for Module#using.
Index: variable.c
===================================================================
--- variable.c	(revision 41298)
+++ variable.c	(revision 41299)
@@ -143,7 +143,8 @@ find_class_path(VALUE klass, ID preferre https://github.com/ruby/ruby/blob/trunk/variable.c#L143
 	if (!RCLASS_IV_TBL(klass)) {
 	    RCLASS_IV_TBL(klass) = st_init_numtable();
 	}
-	st_insert(RCLASS_IV_TBL(klass), (st_data_t)classpath, arg.path);
+	rb_st_insert_id_and_value(klass, RCLASS_IV_TBL(klass), (st_data_t)classpath, arg.path);
+
 	st_delete(RCLASS_IV_TBL(klass), &tmp, 0);
 	return arg.path;
     }
@@ -1184,8 +1185,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L1185
       case T_CLASS:
       case T_MODULE:
 	if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
-	st_insert(RCLASS_IV_TBL(obj), (st_data_t)id, val);
-	OBJ_WRITTEN(obj, Qundef, val);
+	rb_st_insert_id_and_value(obj, RCLASS_IV_TBL(obj), (st_data_t)id, val);
         break;
       default:
       generic:
@@ -2180,8 +2180,8 @@ rb_const_set(VALUE klass, ID id, VALUE v https://github.com/ruby/ruby/blob/trunk/variable.c#L2180
 
     ce = ALLOC(rb_const_entry_t);
     ce->flag = visibility;
-    ce->value = val;
-    ce->file = rb_sourcefilename();
+    OBJ_WRITE(klass, (VALUE *)&ce->value, val);
+    OBJ_WRITE(klass, (VALUE *)&ce->file, rb_sourcefilename());
     ce->line = rb_sourceline();
 
     st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
@@ -2339,7 +2339,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE va https://github.com/ruby/ruby/blob/trunk/variable.c#L2339
 	RCLASS_IV_TBL(target) = st_init_numtable();
     }
 
-    st_insert(RCLASS_IV_TBL(target), (st_data_t)id, (st_data_t)val);
+    rb_st_insert_id_and_value(target, RCLASS_IV_TBL(target), (st_data_t)id, (st_data_t)val);
 }
 
 VALUE
@@ -2576,3 +2576,27 @@ rb_iv_set(VALUE obj, const char *name, V https://github.com/ruby/ruby/blob/trunk/variable.c#L2576
 
     return rb_ivar_set(obj, id, val);
 }
+
+/* tbl = xx(obj); tbl[key] = value; */
+int
+rb_st_insert_id_and_value(VALUE obj, st_table *tbl, ID key, VALUE value)
+{
+    int result = st_insert(tbl, (st_data_t)key, (st_data_t)value);
+    OBJ_WRITTEN(obj, Qundef, value);
+    return result;
+}
+
+static int
+tbl_copy_i(st_data_t key, st_data_t value, st_data_t data)
+{
+    OBJ_WRITTEN((VALUE)data, Qundef, (VALUE)value);
+    return ST_CONTINUE;
+}
+
+st_table *
+rb_st_copy(VALUE obj, struct st_table *orig_tbl)
+{
+    st_table *new_tbl = st_copy(orig_tbl);
+    st_foreach(new_tbl, tbl_copy_i, (st_data_t)obj);
+    return new_tbl;
+}
Index: object.c
===================================================================
--- object.c	(revision 41298)
+++ object.c	(revision 41299)
@@ -295,7 +295,7 @@ init_copy(VALUE dest, VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L295
 	    RCLASS_CONST_TBL(dest) = 0;
 	}
 	if (RCLASS_IV_TBL(obj)) {
-	    RCLASS_IV_TBL(dest) = st_copy(RCLASS_IV_TBL(obj));
+	    RCLASS_IV_TBL(dest) = rb_st_copy(dest, RCLASS_IV_TBL(obj));
 	}
         break;
     }
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 41298)
+++ vm_method.c	(revision 41299)
@@ -411,9 +411,12 @@ rb_add_method(VALUE klass, ID mid, rb_me https://github.com/ruby/ruby/blob/trunk/vm_method.c#L411
     def->original_id = mid;
     def->alias_count = 0;
     switch (type) {
-      case VM_METHOD_TYPE_ISEQ:
-	def->body.iseq = (rb_iseq_t *)opts;
-	break;
+      case VM_METHOD_TYPE_ISEQ: {
+	  rb_iseq_t *iseq = (rb_iseq_t *)opts;
+	  *(rb_iseq_t **)&def->body.iseq = iseq;
+	  OBJ_WRITTEN(klass, Qundef, iseq->self);
+	  break;
+      }
       case VM_METHOD_TYPE_CFUNC:
 	{
 	    rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
@@ -423,16 +426,16 @@ rb_add_method(VALUE klass, ID mid, rb_me https://github.com/ruby/ruby/blob/trunk/vm_method.c#L426
       case VM_METHOD_TYPE_ATTRSET:
       case VM_METHOD_TYPE_IVAR:
 	def->body.attr.id = (ID)opts;
-	def->body.attr.location = Qfalse;
+	OBJ_WRITE(klass, (VALUE *)&def->body.attr.location, Qfalse);
 	th = GET_THREAD();
 	cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
 	if (cfp && (line = rb_vm_get_sourceline(cfp))) {
 	    VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
-	    def->body.attr.location = rb_ary_freeze(location);
+	    OBJ_WRITE(klass, (VALUE *)&def->body.attr.location, rb_ary_freeze(location));
 	}
 	break;
       case VM_METHOD_TYPE_BMETHOD:
-	def->body.proc = (VALUE)opts;
+	OBJ_WRITE(klass, (VALUE *)&def->body.proc, (VALUE)opts);
 	break;
       case VM_METHOD_TYPE_NOTIMPLEMENTED:
 	setup_method_cfunc_struct(&def->body.cfunc, rb_f_notimplement, -1);
Index: class.c
===================================================================
--- class.c	(revision 41298)
+++ class.c	(revision 41299)
@@ -49,7 +49,7 @@ extern st_table *rb_class_tbl; https://github.com/ruby/ruby/blob/trunk/class.c#L49
 static VALUE
 class_alloc(VALUE flags, VALUE klass)
 {
-    NEWOBJ_OF(obj, struct RClass, klass, flags);
+    NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0));
     obj->ptr = ALLOC(rb_classext_t);
     RCLASS_IV_TBL(obj) = 0;
     RCLASS_CONST_TBL(obj) = 0;
@@ -162,19 +162,27 @@ clone_method_i(st_data_t key, st_data_t https://github.com/ruby/ruby/blob/trunk/class.c#L162
     return ST_CONTINUE;
 }
 
+struct clone_const_arg {
+    VALUE klass;
+    st_table *tbl;
+};
+
 static int
-clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
+clone_const(ID key, const rb_const_entry_t *ce, struct clone_const_arg *arg)
 {
     rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
-    *nce = *ce;
-    st_insert(tbl, key, (st_data_t)nce);
+    MEMCPY(nce, ce, rb_const_entry_t, 1);
+    OBJ_WRITTEN(arg->klass, Qundef, ce->value);
+    OBJ_WRITTEN(arg->klass, Qundef, ce->file);
+
+    st_insert(arg->tbl, key, (st_data_t)nce);
     return ST_CONTINUE;
 }
 
 static int
 clone_const_i(st_data_t key, st_data_t value, st_data_t data)
 {
-    return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
+    return clone_const((ID)key, (const rb_const_entry_t *)value, (struct clone_const_arg *)data);
 }
 
 static void
@@ -211,7 +219,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig https://github.com/ruby/ruby/blob/trunk/class.c#L219
 	if (RCLASS_IV_TBL(clone)) {
 	    st_free_table(RCLASS_IV_TBL(clone));
 	}
-	RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
+	RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
 	CONST_ID(id, "__tmp_classpath__");
 	st_delete(RCLASS_IV_TBL(clone), &id, 0);
 	CONST_ID(id, "__classpath__");
@@ -220,11 +228,14 @@ rb_mod_init_copy(VALUE clone, VALUE orig https://github.com/ruby/ruby/blob/trunk/class.c#L228
 	st_delete(RCLASS_IV_TBL(clone), &id, 0);
     }
     if (RCLASS_CONST_TBL(orig)) {
+	struct clone_const_arg arg;
 	if (RCLASS_CONST_TBL(clone)) {
 	    rb_free_const_table(RCLASS_CONST_TBL(clone));
 	}
 	RCLASS_CONST_TBL(clone) = st_init_numtable();
-	st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
+	arg.klass = clone;
+	arg.tbl = RCLASS_CONST_TBL(clone);
+	st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)&arg);
     }
     if (RCLASS_M_TBL(orig)) {
 	if (RCLASS_M_TBL(clone)) {
@@ -264,11 +275,14 @@ rb_singleton_class_clone_and_attach(VALU https://github.com/ruby/ruby/blob/trunk/class.c#L275
 	RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
 	RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
 	if (RCLASS_IV_TBL(klass)) {
-	    RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
+	    RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(klass));
 	}
 	if (RCLASS_CONST_TBL(klass)) {
+	    struct clone_const_arg arg;
 	    RCLASS_CONST_TBL(clone) = st_init_numtable();
-	    st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
+	    arg.klass = clone;
+	    arg.tbl = RCLASS_CONST_TBL(clone);
+	    st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)&arg);
 	}
 	if (attach != Qundef) {
 	    rb_singleton_class_attached(clone, attach);
@@ -277,6 +291,7 @@ rb_singleton_class_clone_and_attach(VALU https://github.com/ruby/ruby/blob/trunk/class.c#L291
 	st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone);
 	rb_singleton_class_attached(RBASIC(clone)->klass, clone);
 	FL_SET(clone, FL_SINGLETON);
+
 	return clone;
     }
 }
@@ -292,7 +307,7 @@ rb_singleton_class_attached(VALUE klass, https://github.com/ruby/ruby/blob/trunk/class.c#L307
 	if (!RCLASS_IV_TBL(klass)) {
 	    RCLASS_IV_TBL(klass) = st_init_numtable();
 	}
-	st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
+	rb_st_insert_id_and_value(klass, RCLASS_IV_TBL(klass), id_attached, obj);
     }
 }
 
Index: internal.h
===================================================================
--- internal.h	(revision 41298)
+++ internal.h	(revision 41299)
@@ -473,6 +473,9 @@ void rb_gc_mark_global_tbl(void); https://github.com/ruby/ruby/blob/trunk/internal.h#L473
 void rb_mark_generic_ivar(VALUE);
 void rb_mark_generic_ivar_tbl(void);
 
+int rb_st_insert_id_and_value(VALUE obj, st_table *tbl, ID key, VALUE value);
+st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
+
 /* gc.c */
 size_t rb_gc_count();
 
Index: constant.h
===================================================================
--- constant.h	(revision 41298)
+++ constant.h	(revision 41299)
@@ -18,8 +18,8 @@ typedef enum { https://github.com/ruby/ruby/blob/trunk/constant.h#L18
 
 typedef struct rb_const_entry_struct {
     rb_const_flag_t flag;
-    VALUE value;            /* should be mark */
-    VALUE file;
+    const VALUE value;            /* should be mark */
+    const VALUE file;             /* should be mark */
     int line;
 } rb_const_entry_t;
 

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

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