diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | gc.c | 17 |
2 files changed, 21 insertions, 4 deletions
@@ -1,3 +1,11 @@ +Tue Dec 10 14:41:53 2013 Aman Gupta <ruby@tmm1.net> + + * gc.c (reflist_add): return 0 if reference already exists + * gc.c (allrefs_add): return 1 on newly added references + * gc.c (allrefs_i): follow references to construct complete object + graph. before this patch, RGENGC_CHECK could fail to verify some WB + miss issues. [Bug #9226] [ruby-core:58959] + Tue Dec 10 11:20:56 2013 Aman Gupta <ruby@tmm1.net> * ext/objspace/objspace_dump.c (dump_object): include fstring flag on @@ -4164,14 +4164,21 @@ reflist_destruct(struct reflist *refs) xfree(refs); } -static void +static int reflist_add(struct reflist *refs, VALUE obj) { + int i = 0; if (refs->pos == refs->size) { refs->size *= 2; SIZED_REALLOC_N(refs->list, VALUE, refs->size, refs->size/2); } + + for (i=0; i<refs->pos; i++) + if (refs->list[i] == obj) + return 0; /* already exists */ + refs->list[refs->pos++] = obj; + return 1; /* added */ } static void @@ -4215,17 +4222,18 @@ struct allrefs { VALUE root_obj; }; -static void +static int allrefs_add(struct allrefs *data, VALUE obj) { struct reflist *refs; if (st_lookup(data->references, obj, (st_data_t *)&refs)) { - reflist_add(refs, data->root_obj); + return reflist_add(refs, data->root_obj); } else { refs = reflist_create(data->root_obj); st_insert(data->references, obj, (st_data_t)refs); + return 1; } } @@ -4233,7 +4241,8 @@ static void allrefs_i(VALUE obj, void *ptr) { struct allrefs *data = (struct allrefs *)ptr; - allrefs_add(data, obj); + if (allrefs_add(data, obj)) /* follow new reference */ + push_mark_stack(&data->objspace->mark_stack, obj); } static void |