From 87a120fbdc25544135e8d625e8dc11950b7245a3 Mon Sep 17 00:00:00 2001 From: ko1 Date: Fri, 14 Jun 2013 09:23:54 +0000 Subject: * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41299 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- class.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'class.c') diff --git a/class.c b/class.c index 8ab8d052f4..c72bd8168f 100644 --- a/class.c +++ b/class.c @@ -49,7 +49,7 @@ extern st_table *rb_class_tbl; 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 value, st_data_t data) 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) 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) 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(VALUE obj, VALUE attach) 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(VALUE obj, VALUE attach) 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, VALUE obj) 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); } } -- cgit v1.2.3