ruby-changes:29360
From: ko1 <ko1@a...>
Date: Wed, 19 Jun 2013 15:26:13 +0900 (JST)
Subject: [ruby-changes:29360] ko1:r41412 (trunk): * include/ruby/ruby.h (struct rb_data_type_struct), gc.c: add
ko1 2013-06-19 15:26:01 +0900 (Wed, 19 Jun 2013) New Revision: 41412 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41412 Log: * include/ruby/ruby.h (struct rb_data_type_struct), gc.c: add rb_data_type_struct::flags. Now, this flags is passed at T_DATA object creation. You can specify FL_WB_PROTECTED on this flag. * iseq.c: making non-shady iseq objects. * class.c, compile.c, proc.c, vm.c: add WB for iseq objects. * vm_core.h, iseq.h: constify fields to detect WB insertion. Modified files: trunk/ChangeLog trunk/class.c trunk/compile.c trunk/gc.c trunk/include/ruby/ruby.h trunk/iseq.c trunk/iseq.h trunk/proc.c trunk/vm.c trunk/vm_core.h Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 41411) +++ include/ruby/ruby.h (revision 41412) @@ -1037,6 +1037,7 @@ struct rb_data_type_struct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1037 const rb_data_type_t *parent; void *data; /* This area can be used for any purpose by a programmer who define the type. */ + VALUE flags; /* FL_WB_PROTECTED */ }; #define HAVE_TYPE_RB_DATA_TYPE_T 1 Index: ChangeLog =================================================================== --- ChangeLog (revision 41411) +++ ChangeLog (revision 41412) @@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jun 19 15:14:30 2013 Koichi Sasada <ko1@a...> + + * include/ruby/ruby.h (struct rb_data_type_struct), gc.c: add + rb_data_type_struct::flags. Now, this flags is passed + at T_DATA object creation. You can specify FL_WB_PROTECTED + on this flag. + + * iseq.c: making non-shady iseq objects. + + * class.c, compile.c, proc.c, vm.c: add WB for iseq objects. + + * vm_core.h, iseq.h: constify fields to detect WB insertion. + Wed Jun 19 15:11:13 2013 Nobuyoshi Nakada <nobu@r...> * gc.c (gc_mark_children): show more info for broken object. Index: vm_core.h =================================================================== --- vm_core.h (revision 41411) +++ vm_core.h (revision 41412) @@ -186,10 +186,10 @@ typedef struct rb_call_info_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L186 GetCoreDataFromValue((obj), rb_iseq_t, (ptr)) typedef struct rb_iseq_location_struct { - VALUE path; - VALUE absolute_path; - VALUE base_label; - VALUE label; + const VALUE path; + const VALUE absolute_path; + const VALUE base_label; + const VALUE label; size_t first_lineno; } rb_iseq_location_t; @@ -217,8 +217,8 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L217 VALUE *iseq; /* iseq (insn number and operands) */ VALUE *iseq_encoded; /* encoded iseq */ unsigned long iseq_size; - VALUE mark_ary; /* Array: includes operands which should be GC marked */ - VALUE coverage; /* coverage array */ + const VALUE mark_ary; /* Array: includes operands which should be GC marked */ + const VALUE coverage; /* coverage array */ /* insn info, must be freed */ struct iseq_line_info_entry *line_info_table; @@ -293,7 +293,7 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L293 /****************/ VALUE self; - VALUE orig; /* non-NULL if its data have origin */ + const VALUE orig; /* non-NULL if its data have origin */ /* block inlining */ /* @@ -304,8 +304,8 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L304 */ /* klass/module nest information stack (cref) */ - NODE *cref_stack; - VALUE klass; + NODE * const cref_stack; + const VALUE klass; /* misc */ ID defined_method_id; /* for define_method */ Index: iseq.c =================================================================== --- iseq.c (revision 41411) +++ iseq.c (revision 41412) @@ -112,10 +112,6 @@ iseq_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L112 RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack); RUBY_MARK_UNLESS_NULL(iseq->klass); RUBY_MARK_UNLESS_NULL(iseq->coverage); -#if 0 - RUBY_MARK_UNLESS_NULL((VALUE)iseq->node); - RUBY_MARK_UNLESS_NULL(iseq->cached_special_block); -#endif RUBY_MARK_UNLESS_NULL(iseq->orig); if (iseq->compile_data != 0) { @@ -171,7 +167,10 @@ static const rb_data_type_t iseq_data_ty https://github.com/ruby/ruby/blob/trunk/iseq.c#L167 iseq_mark, iseq_free, iseq_memsize, - }, + }, /* functions */ + 0, /* parent */ + 0, /* data */ + FL_WB_PROTECTED /* flags */ }; static VALUE @@ -185,16 +184,21 @@ static rb_iseq_location_t * https://github.com/ruby/ruby/blob/trunk/iseq.c#L184 iseq_location_setup(rb_iseq_t *iseq, VALUE path, VALUE absolute_path, VALUE name, size_t first_lineno) { rb_iseq_location_t *loc = &iseq->location; - loc->path = path; - if (RTEST(absolute_path) && rb_str_cmp(path, absolute_path) == 0) - loc->absolute_path = path; - else - loc->absolute_path = absolute_path; - loc->label = loc->base_label = name; + OBJ_WRITE(iseq->self, (VALUE *)&loc->path, path); + if (RTEST(absolute_path) && rb_str_cmp(path, absolute_path) == 0) { + OBJ_WRITE(iseq->self, (VALUE *)&loc->absolute_path, path); + } + else { + OBJ_WRITE(iseq->self, (VALUE *)&loc->absolute_path, absolute_path); + } + OBJ_WRITE(iseq->self, (VALUE *)&loc->label, name); + OBJ_WRITE(iseq->self, (VALUE *)&loc->base_label, name); loc->first_lineno = first_lineno; return loc; } +#define ISEQ_SET_CREF(iseq, cref) OBJ_WRITE((iseq)->self, (VALUE *)&(iseq)->cref_stack, (cref)) + static void set_relation(rb_iseq_t *iseq, const VALUE parent) { @@ -205,7 +209,7 @@ set_relation(rb_iseq_t *iseq, const VALU https://github.com/ruby/ruby/blob/trunk/iseq.c#L209 /* set class nest stack */ if (type == ISEQ_TYPE_TOP) { /* toplevel is private */ - iseq->cref_stack = NEW_CREF(rb_cObject); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->cref_stack, NEW_CREF(rb_cObject)); iseq->cref_stack->nd_refinements = Qnil; iseq->cref_stack->nd_visi = NOEX_PRIVATE; if (th->top_wrapper) { @@ -213,18 +217,18 @@ set_relation(rb_iseq_t *iseq, const VALU https://github.com/ruby/ruby/blob/trunk/iseq.c#L217 cref->nd_refinements = Qnil; cref->nd_visi = NOEX_PRIVATE; cref->nd_next = iseq->cref_stack; - iseq->cref_stack = cref; + ISEQ_SET_CREF(iseq, cref); } iseq->local_iseq = iseq; } else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) { - iseq->cref_stack = NEW_CREF(0); /* place holder */ + ISEQ_SET_CREF(iseq, NEW_CREF(0)); /* place holder */ iseq->cref_stack->nd_refinements = Qnil; iseq->local_iseq = iseq; } else if (RTEST(parent)) { GetISeqPtr(parent, piseq); - iseq->cref_stack = piseq->cref_stack; + ISEQ_SET_CREF(iseq, piseq->cref_stack); iseq->local_iseq = piseq->local_iseq; } @@ -242,7 +246,7 @@ void https://github.com/ruby/ruby/blob/trunk/iseq.c#L246 rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj) { if (!RTEST(iseq->mark_ary)) { - iseq->mark_ary = rb_ary_tmp_new(3); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->mark_ary, rb_ary_tmp_new(3)); RBASIC_CLEAR_CLASS(iseq->mark_ary); } rb_ary_push(iseq->mark_ary, obj); @@ -258,7 +262,7 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L262 iseq->arg_rest = -1; iseq->arg_block = -1; iseq->arg_keyword = -1; - iseq->klass = 0; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->klass, 0); set_relation(iseq, parent); OBJ_FREEZE(name); @@ -266,11 +270,11 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L270 iseq_location_setup(iseq, path, absolute_path, name, first_lineno); if (iseq != iseq->local_iseq) { - iseq->location.base_label = iseq->local_iseq->location.label; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->location.base_label, iseq->local_iseq->location.label); } iseq->defined_method_id = 0; - iseq->mark_ary = 0; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->mark_ary, 0); /* * iseq->special_block_builder = GC_GUARDED_PTR_REF(block_opt); @@ -280,15 +284,15 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L284 iseq->compile_data = ALLOC(struct iseq_compile_data); MEMZERO(iseq->compile_data, struct iseq_compile_data, 1); - iseq->compile_data->err_info = Qnil; - iseq->compile_data->mark_ary = rb_ary_tmp_new(3); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->err_info, Qnil); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->mark_ary, rb_ary_tmp_new(3)); iseq->compile_data->storage_head = iseq->compile_data->storage_current = (struct iseq_compile_data_storage *) ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE + sizeof(struct iseq_compile_data_storage)); - iseq->compile_data->catch_table_ary = rb_ary_new(); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->catch_table_ary, rb_ary_new()); iseq->compile_data->storage_head->pos = 0; iseq->compile_data->storage_head->next = 0; iseq->compile_data->storage_head->size = @@ -298,12 +302,12 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L302 iseq->compile_data->option = option; iseq->compile_data->last_coverable_line = -1; - iseq->coverage = Qfalse; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, Qfalse); if (!GET_THREAD()->parse_in_eval) { VALUE coverages = rb_get_coverages(); if (RTEST(coverages)) { - iseq->coverage = rb_hash_lookup(coverages, path); - if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, rb_hash_lookup(coverages, path)); + if (NIL_P(iseq->coverage)) OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, Qfalse); } } @@ -1899,22 +1903,23 @@ rb_iseq_clone(VALUE iseqval, VALUE newcb https://github.com/ruby/ruby/blob/trunk/iseq.c#L1903 GetISeqPtr(iseqval, iseq0); GetISeqPtr(newiseq, iseq1); - *iseq1 = *iseq0; + MEMCPY(iseq1, iseq0, rb_iseq_t, 1); /* TODO: write barrier? */ + iseq1->self = newiseq; if (!iseq1->orig) { - iseq1->orig = iseqval; + OBJ_WRITE(iseq1->self, (VALUE *)&iseq1->orig, iseqval); } if (iseq0->local_iseq == iseq0) { iseq1->local_iseq = iseq1; } if (newcbase) { - iseq1->cref_stack = NEW_CREF(newcbase); + ISEQ_SET_CREF(iseq1, NEW_CREF(newcbase)); iseq1->cref_stack->nd_refinements = iseq0->cref_stack->nd_refinements; iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi; if (iseq0->cref_stack->nd_next) { iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next; } - iseq1->klass = newcbase; + OBJ_WRITE(iseq1, (VALUE *)&iseq1->klass, newcbase); } return newiseq; @@ -2065,11 +2070,11 @@ rb_iseq_build_for_ruby2cext( https://github.com/ruby/ruby/blob/trunk/iseq.c#L2070 GetISeqPtr(iseqval, iseq); /* copy iseq */ - *iseq = *iseq_template; - iseq->location.label = rb_str_new2(name); - iseq->location.path = rb_str_new2(path); + MEMCPY(iseq, iseq_template, rb_iseq_t, 1); /* TODO: write barrier, *iseq = *iseq_template; */ + OBJ_WRITE(iseq->self, (VALUE *)&iseq->location.label, rb_str_new2(name)); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->location.path, rb_str_new2(path)); iseq->location.first_lineno = first_lineno; - iseq->mark_ary = 0; + OBJ_WRITE(iseq->self, (VALUE *)&iseq->mark_ary, 0); iseq->self = iseqval; iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size); Index: iseq.h =================================================================== --- iseq.h (revision 41411) +++ iseq.h (revision 41412) @@ -79,9 +79,9 @@ struct iseq_compile_data_storage { https://github.com/ruby/ruby/blob/trunk/iseq.h#L79 struct iseq_compile_data { /* GC is needed */ - VALUE err_info; + const VALUE err_info; VALUE mark_ary; - VALUE catch_table_ary; /* Array */ + const VALUE catch_table_ary; /* Array */ /* GC is not needed */ struct iseq_label_data *start_label; Index: compile.c =================================================================== --- compile.c (revision 41411) +++ compile.c (revision 41412) @@ -278,7 +278,7 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/compile.c#L278 if (compile_debug) rb_compile_bug strs; \ GET_THREAD()->errinfo = iseq->compile_data->err_info; \ rb_compile_error strs; \ - iseq->compile_data->err_info = GET_THREAD()->errinfo; \ + OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->err_info, GET_THREAD()->errinfo); \ GET_THREAD()->errinfo = tmp; \ ret = 0; \ break; \ @@ -1706,7 +1706,7 @@ iseq_set_exception_table(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L1706 } } - iseq->compile_data->catch_table_ary = 0; /* free */ + OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->catch_table_ary, 0); /* free */ return COMPILE_OK; } Index: proc.c =================================================================== --- proc.c (revision 41411) +++ proc.c (revision 41412) @@ -1467,7 +1467,7 @@ rb_mod_define_method(int argc, VALUE *ar https://github.com/ruby/ruby/blob/trunk/proc.c#L1467 GetProcPtr(body, proc); if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) { proc->block.iseq->defined_method_id = id; - proc->block.iseq->klass = mod; + OBJ_WRITE(proc->block.iseq->self, (VALUE *)&proc->block.iseq->klass, mod); proc->is_lambda = TRUE; proc->is_from_method = TRUE; proc->block.klass = mod; Index: gc.c =================================================================== --- gc.c (revision 41411) +++ gc.c (revision 41412) @@ -996,7 +996,7 @@ VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L996 rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type) { if (klass) Check_Type(klass, T_CLASS); - return newobj_of(klass, T_DATA, (VALUE)type, (VALUE)1, (VALUE)datap); + return newobj_of(klass, T_DATA | type->flags, (VALUE)type, (VALUE)1, (VALUE)datap); } size_t Index: class.c =================================================================== --- class.c (revision 41411) +++ class.c (revision 41412) @@ -146,7 +146,7 @@ clone_method(VALUE klass, ID mid, const https://github.com/ruby/ruby/blob/trunk/class.c#L146 rb_iseq_t *iseq; newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass); GetISeqPtr(newiseqval, iseq); - iseq->cref_stack = rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass); + OBJ_WRITE(iseq->self, (VALUE *)&iseq->cref_stack, rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass)); rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); RB_GC_GUARD(newiseqval); } Index: vm.c =================================================================== --- vm.c (revision 41411) +++ vm.c (revision 41412) @@ -2031,7 +2031,7 @@ vm_define_method(rb_thread_t *th, VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L2031 /* dup */ COPY_CREF(miseq->cref_stack, cref); miseq->cref_stack->nd_visi = NOEX_PUBLIC; - miseq->klass = klass; + OBJ_WRITE(miseq->self, (VALUE *)&miseq->klass, klass); miseq->defined_method_id = id; rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex); @@ -2532,7 +2532,7 @@ rb_vm_set_progname(VALUE filename) https://github.com/ruby/ruby/blob/trunk/vm.c#L2532 rb_thread_t *th = GET_VM()->main_thread; rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size); --cfp; - cfp->iseq->location.path = filename; + OBJ_WRITE(cfp->iseq->self, (VALUE *)&cfp->iseq->location.path, filename); } #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/