diff options
author | tmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-10 05:46:48 +0000 |
---|---|---|
committer | tmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-10 05:46:48 +0000 |
commit | 3705007e7a66e35725167871260d01065837e707 (patch) | |
tree | 4f79e5f71a47d1d80ace801208e16aa9461b2b76 /gc.c | |
parent | 0326725b24dee6a82bb21bfa370072b326403155 (diff) | |
download | ruby-3705007e7a66e35725167871260d01065837e707.tar.gz |
gc.c: build complete object graph for RGENGC_CHECK_MODE
* 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]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44109 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 17 |
1 files changed, 13 insertions, 4 deletions
@@ -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 |