1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41412 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-06-19 06:26:01 +00:00
parent 063d4e4141
commit 9b47ec04a8
10 changed files with 70 additions and 51 deletions

View file

@ -1,3 +1,16 @@
Wed Jun 19 15:14:30 2013 Koichi Sasada <ko1@atdot.net>
* 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@ruby-lang.org> Wed Jun 19 15:11:13 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* gc.c (gc_mark_children): show more info for broken object. * gc.c (gc_mark_children): show more info for broken object.

View file

@ -146,7 +146,7 @@ clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
rb_iseq_t *iseq; rb_iseq_t *iseq;
newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass); newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
GetISeqPtr(newiseqval, iseq); 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_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
RB_GC_GUARD(newiseqval); RB_GC_GUARD(newiseqval);
} }

View file

@ -278,7 +278,7 @@ r_value(VALUE value)
if (compile_debug) rb_compile_bug strs; \ if (compile_debug) rb_compile_bug strs; \
GET_THREAD()->errinfo = iseq->compile_data->err_info; \ GET_THREAD()->errinfo = iseq->compile_data->err_info; \
rb_compile_error strs; \ 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; \ GET_THREAD()->errinfo = tmp; \
ret = 0; \ ret = 0; \
break; \ break; \
@ -1706,7 +1706,7 @@ iseq_set_exception_table(rb_iseq_t *iseq)
} }
} }
iseq->compile_data->catch_table_ary = 0; /* free */ OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->catch_table_ary, 0); /* free */
return COMPILE_OK; return COMPILE_OK;
} }

2
gc.c
View file

@ -996,7 +996,7 @@ VALUE
rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type) rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
{ {
if (klass) Check_Type(klass, T_CLASS); 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 size_t

View file

@ -1037,6 +1037,7 @@ struct rb_data_type_struct {
const rb_data_type_t *parent; const rb_data_type_t *parent;
void *data; /* This area can be used for any purpose void *data; /* This area can be used for any purpose
by a programmer who define the type. */ by a programmer who define the type. */
VALUE flags; /* FL_WB_PROTECTED */
}; };
#define HAVE_TYPE_RB_DATA_TYPE_T 1 #define HAVE_TYPE_RB_DATA_TYPE_T 1

71
iseq.c
View file

@ -112,10 +112,6 @@ iseq_mark(void *ptr)
RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack); RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack);
RUBY_MARK_UNLESS_NULL(iseq->klass); RUBY_MARK_UNLESS_NULL(iseq->klass);
RUBY_MARK_UNLESS_NULL(iseq->coverage); 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); RUBY_MARK_UNLESS_NULL(iseq->orig);
if (iseq->compile_data != 0) { if (iseq->compile_data != 0) {
@ -171,7 +167,10 @@ static const rb_data_type_t iseq_data_type = {
iseq_mark, iseq_mark,
iseq_free, iseq_free,
iseq_memsize, iseq_memsize,
}, }, /* functions */
0, /* parent */
0, /* data */
FL_WB_PROTECTED /* flags */
}; };
static VALUE static VALUE
@ -185,16 +184,21 @@ static rb_iseq_location_t *
iseq_location_setup(rb_iseq_t *iseq, VALUE path, VALUE absolute_path, VALUE name, size_t first_lineno) 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; rb_iseq_location_t *loc = &iseq->location;
loc->path = path; OBJ_WRITE(iseq->self, (VALUE *)&loc->path, path);
if (RTEST(absolute_path) && rb_str_cmp(path, absolute_path) == 0) if (RTEST(absolute_path) && rb_str_cmp(path, absolute_path) == 0) {
loc->absolute_path = path; OBJ_WRITE(iseq->self, (VALUE *)&loc->absolute_path, path);
else }
loc->absolute_path = absolute_path; else {
loc->label = loc->base_label = name; 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; loc->first_lineno = first_lineno;
return loc; return loc;
} }
#define ISEQ_SET_CREF(iseq, cref) OBJ_WRITE((iseq)->self, (VALUE *)&(iseq)->cref_stack, (cref))
static void static void
set_relation(rb_iseq_t *iseq, const VALUE parent) set_relation(rb_iseq_t *iseq, const VALUE parent)
{ {
@ -205,7 +209,7 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
/* set class nest stack */ /* set class nest stack */
if (type == ISEQ_TYPE_TOP) { if (type == ISEQ_TYPE_TOP) {
/* toplevel is private */ /* 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_refinements = Qnil;
iseq->cref_stack->nd_visi = NOEX_PRIVATE; iseq->cref_stack->nd_visi = NOEX_PRIVATE;
if (th->top_wrapper) { if (th->top_wrapper) {
@ -213,18 +217,18 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
cref->nd_refinements = Qnil; cref->nd_refinements = Qnil;
cref->nd_visi = NOEX_PRIVATE; cref->nd_visi = NOEX_PRIVATE;
cref->nd_next = iseq->cref_stack; cref->nd_next = iseq->cref_stack;
iseq->cref_stack = cref; ISEQ_SET_CREF(iseq, cref);
} }
iseq->local_iseq = iseq; iseq->local_iseq = iseq;
} }
else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) { 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->cref_stack->nd_refinements = Qnil;
iseq->local_iseq = iseq; iseq->local_iseq = iseq;
} }
else if (RTEST(parent)) { else if (RTEST(parent)) {
GetISeqPtr(parent, piseq); GetISeqPtr(parent, piseq);
iseq->cref_stack = piseq->cref_stack; ISEQ_SET_CREF(iseq, piseq->cref_stack);
iseq->local_iseq = piseq->local_iseq; iseq->local_iseq = piseq->local_iseq;
} }
@ -242,7 +246,7 @@ void
rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj) rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj)
{ {
if (!RTEST(iseq->mark_ary)) { 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); RBASIC_CLEAR_CLASS(iseq->mark_ary);
} }
rb_ary_push(iseq->mark_ary, obj); rb_ary_push(iseq->mark_ary, obj);
@ -258,7 +262,7 @@ prepare_iseq_build(rb_iseq_t *iseq,
iseq->arg_rest = -1; iseq->arg_rest = -1;
iseq->arg_block = -1; iseq->arg_block = -1;
iseq->arg_keyword = -1; iseq->arg_keyword = -1;
iseq->klass = 0; OBJ_WRITE(iseq->self, (VALUE *)&iseq->klass, 0);
set_relation(iseq, parent); set_relation(iseq, parent);
OBJ_FREEZE(name); OBJ_FREEZE(name);
@ -266,11 +270,11 @@ prepare_iseq_build(rb_iseq_t *iseq,
iseq_location_setup(iseq, path, absolute_path, name, first_lineno); iseq_location_setup(iseq, path, absolute_path, name, first_lineno);
if (iseq != iseq->local_iseq) { 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->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); * iseq->special_block_builder = GC_GUARDED_PTR_REF(block_opt);
@ -280,15 +284,15 @@ prepare_iseq_build(rb_iseq_t *iseq,
iseq->compile_data = ALLOC(struct iseq_compile_data); iseq->compile_data = ALLOC(struct iseq_compile_data);
MEMZERO(iseq->compile_data, struct iseq_compile_data, 1); MEMZERO(iseq->compile_data, struct iseq_compile_data, 1);
iseq->compile_data->err_info = Qnil; OBJ_WRITE(iseq->self, (VALUE *)&iseq->compile_data->err_info, Qnil);
iseq->compile_data->mark_ary = rb_ary_tmp_new(3); 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 = iseq->compile_data->storage_head = iseq->compile_data->storage_current =
(struct iseq_compile_data_storage *) (struct iseq_compile_data_storage *)
ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE + ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
sizeof(struct iseq_compile_data_storage)); 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->pos = 0;
iseq->compile_data->storage_head->next = 0; iseq->compile_data->storage_head->next = 0;
iseq->compile_data->storage_head->size = iseq->compile_data->storage_head->size =
@ -298,12 +302,12 @@ prepare_iseq_build(rb_iseq_t *iseq,
iseq->compile_data->option = option; iseq->compile_data->option = option;
iseq->compile_data->last_coverable_line = -1; iseq->compile_data->last_coverable_line = -1;
iseq->coverage = Qfalse; OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, Qfalse);
if (!GET_THREAD()->parse_in_eval) { if (!GET_THREAD()->parse_in_eval) {
VALUE coverages = rb_get_coverages(); VALUE coverages = rb_get_coverages();
if (RTEST(coverages)) { if (RTEST(coverages)) {
iseq->coverage = rb_hash_lookup(coverages, path); OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, rb_hash_lookup(coverages, path));
if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse; if (NIL_P(iseq->coverage)) OBJ_WRITE(iseq->self, (VALUE *)&iseq->coverage, Qfalse);
} }
} }
@ -1899,22 +1903,23 @@ rb_iseq_clone(VALUE iseqval, VALUE newcbase)
GetISeqPtr(iseqval, iseq0); GetISeqPtr(iseqval, iseq0);
GetISeqPtr(newiseq, iseq1); GetISeqPtr(newiseq, iseq1);
*iseq1 = *iseq0; MEMCPY(iseq1, iseq0, rb_iseq_t, 1); /* TODO: write barrier? */
iseq1->self = newiseq; iseq1->self = newiseq;
if (!iseq1->orig) { if (!iseq1->orig) {
iseq1->orig = iseqval; OBJ_WRITE(iseq1->self, (VALUE *)&iseq1->orig, iseqval);
} }
if (iseq0->local_iseq == iseq0) { if (iseq0->local_iseq == iseq0) {
iseq1->local_iseq = iseq1; iseq1->local_iseq = iseq1;
} }
if (newcbase) { 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_refinements = iseq0->cref_stack->nd_refinements;
iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi; iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi;
if (iseq0->cref_stack->nd_next) { if (iseq0->cref_stack->nd_next) {
iseq1->cref_stack->nd_next = 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; return newiseq;
@ -2065,11 +2070,11 @@ rb_iseq_build_for_ruby2cext(
GetISeqPtr(iseqval, iseq); GetISeqPtr(iseqval, iseq);
/* copy iseq */ /* copy iseq */
*iseq = *iseq_template; MEMCPY(iseq, iseq_template, rb_iseq_t, 1); /* TODO: write barrier, *iseq = *iseq_template; */
iseq->location.label = rb_str_new2(name); OBJ_WRITE(iseq->self, (VALUE *)&iseq->location.label, rb_str_new2(name));
iseq->location.path = rb_str_new2(path); OBJ_WRITE(iseq->self, (VALUE *)&iseq->location.path, rb_str_new2(path));
iseq->location.first_lineno = first_lineno; iseq->location.first_lineno = first_lineno;
iseq->mark_ary = 0; OBJ_WRITE(iseq->self, (VALUE *)&iseq->mark_ary, 0);
iseq->self = iseqval; iseq->self = iseqval;
iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size); iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);

4
iseq.h
View file

@ -79,9 +79,9 @@ struct iseq_compile_data_storage {
struct iseq_compile_data { struct iseq_compile_data {
/* GC is needed */ /* GC is needed */
VALUE err_info; const VALUE err_info;
VALUE mark_ary; VALUE mark_ary;
VALUE catch_table_ary; /* Array */ const VALUE catch_table_ary; /* Array */
/* GC is not needed */ /* GC is not needed */
struct iseq_label_data *start_label; struct iseq_label_data *start_label;

2
proc.c
View file

@ -1467,7 +1467,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
GetProcPtr(body, proc); GetProcPtr(body, proc);
if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) { if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) {
proc->block.iseq->defined_method_id = id; 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_lambda = TRUE;
proc->is_from_method = TRUE; proc->is_from_method = TRUE;
proc->block.klass = mod; proc->block.klass = mod;

4
vm.c
View file

@ -2031,7 +2031,7 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
/* dup */ /* dup */
COPY_CREF(miseq->cref_stack, cref); COPY_CREF(miseq->cref_stack, cref);
miseq->cref_stack->nd_visi = NOEX_PUBLIC; miseq->cref_stack->nd_visi = NOEX_PUBLIC;
miseq->klass = klass; OBJ_WRITE(miseq->self, (VALUE *)&miseq->klass, klass);
miseq->defined_method_id = id; miseq->defined_method_id = id;
rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex); rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex);
@ -2532,7 +2532,7 @@ rb_vm_set_progname(VALUE filename)
rb_thread_t *th = GET_VM()->main_thread; rb_thread_t *th = GET_VM()->main_thread;
rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size); rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
--cfp; --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 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE

View file

@ -186,10 +186,10 @@ typedef struct rb_call_info_struct {
GetCoreDataFromValue((obj), rb_iseq_t, (ptr)) GetCoreDataFromValue((obj), rb_iseq_t, (ptr))
typedef struct rb_iseq_location_struct { typedef struct rb_iseq_location_struct {
VALUE path; const VALUE path;
VALUE absolute_path; const VALUE absolute_path;
VALUE base_label; const VALUE base_label;
VALUE label; const VALUE label;
size_t first_lineno; size_t first_lineno;
} rb_iseq_location_t; } rb_iseq_location_t;
@ -217,8 +217,8 @@ struct rb_iseq_struct {
VALUE *iseq; /* iseq (insn number and operands) */ VALUE *iseq; /* iseq (insn number and operands) */
VALUE *iseq_encoded; /* encoded iseq */ VALUE *iseq_encoded; /* encoded iseq */
unsigned long iseq_size; unsigned long iseq_size;
VALUE mark_ary; /* Array: includes operands which should be GC marked */ const VALUE mark_ary; /* Array: includes operands which should be GC marked */
VALUE coverage; /* coverage array */ const VALUE coverage; /* coverage array */
/* insn info, must be freed */ /* insn info, must be freed */
struct iseq_line_info_entry *line_info_table; struct iseq_line_info_entry *line_info_table;
@ -293,7 +293,7 @@ struct rb_iseq_struct {
/****************/ /****************/
VALUE self; VALUE self;
VALUE orig; /* non-NULL if its data have origin */ const VALUE orig; /* non-NULL if its data have origin */
/* block inlining */ /* block inlining */
/* /*
@ -304,8 +304,8 @@ struct rb_iseq_struct {
*/ */
/* klass/module nest information stack (cref) */ /* klass/module nest information stack (cref) */
NODE *cref_stack; NODE * const cref_stack;
VALUE klass; const VALUE klass;
/* misc */ /* misc */
ID defined_method_id; /* for define_method */ ID defined_method_id; /* for define_method */