aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2019-10-28 16:14:50 -0700
committerAaron Patterson <tenderlove@ruby-lang.org>2019-10-28 16:14:50 -0700
commitda3774e5eb6de9dfe5c2ec6f3444c81d22c0e00a (patch)
tree1b93d5b01162a5a81100a7ea7a7ff8779ecf6b83 /gc.c
parent60a7f9f446604571f8a81499080c57c47baf0e6b (diff)
downloadruby-da3774e5eb6de9dfe5c2ec6f3444c81d22c0e00a.tar.gz
Revert "Protect finalizer references during execution"
This reverts commit 60a7f9f446604571f8a81499080c57c47baf0e6b. We can't have Ruby objects pointing at T_ZOMBIE objects otherwise we get an error in the GC. We need to find a different way to update references.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/gc.c b/gc.c
index 19551ac760..6fcdf2a53c 100644
--- a/gc.c
+++ b/gc.c
@@ -3370,7 +3370,12 @@ struct force_finalize_list {
static int
force_chain_object(st_data_t key, st_data_t val, st_data_t arg)
{
- rb_ary_push((VALUE)arg, rb_ary_new_from_args(2, (VALUE)key, (VALUE)val));
+ struct force_finalize_list **prev = (struct force_finalize_list **)arg;
+ struct force_finalize_list *curr = ALLOC(struct force_finalize_list);
+ curr->obj = key;
+ curr->table = val;
+ curr->next = *prev;
+ *prev = curr;
return ST_CONTINUE;
}
@@ -3397,18 +3402,16 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
/* force to run finalizer */
while (finalizer_table->num_entries) {
- long i;
- VALUE list = rb_ary_new_capa(finalizer_table->num_entries);
-
- st_foreach(finalizer_table, force_chain_object, (st_data_t)list);
-
- for (i = 0; i < RARRAY_LEN(list); i++) {
- VALUE tuple = RARRAY_AREF(list, i);
- VALUE obj = RARRAY_AREF(tuple, 0);
- VALUE table = RARRAY_AREF(tuple, 1);
- run_finalizer(objspace, obj, table);
+ struct force_finalize_list *list = 0;
+ st_foreach(finalizer_table, force_chain_object, (st_data_t)&list);
+ while (list) {
+ struct force_finalize_list *curr = list;
+ st_data_t obj = (st_data_t)curr->obj;
+ run_finalizer(objspace, curr->obj, curr->table);
st_delete(finalizer_table, &obj, 0);
- }
+ list = curr->next;
+ xfree(curr);
+ }
}
/* prohibit GC because force T_DATA finalizers can break an object graph consistency */