Fix root being possibly uncounted in check_gc_root

This commit is contained in:
2025-09-10 02:50:45 -07:00
parent 4fe4e293ad
commit ae7b645b7a

View File

@ -648,7 +648,11 @@ static ptrdiff_t check_gc_root(RefcountContext *ctx, RefcountList **root_ptr) {
*root_ptr = (*root_ptr)->next; *root_ptr = (*root_ptr)->next;
return -1; return -1;
} }
size_t seen_objects = 0; // initialize information for the root
ht_insert(
counts, root->data,
HT_STUFF(
REFCOUNT_OBJECT_ENTRY(ctx, root->data)->impl.counted.ref_count));
size_t clear_objects = 0; size_t clear_objects = 0;
// ignore allocation errors until I decide how to deal with them (in the far // ignore allocation errors until I decide how to deal with them (in the far
// future) // future)
@ -663,7 +667,6 @@ static ptrdiff_t check_gc_root(RefcountContext *ctx, RefcountList **root_ptr) {
count = HT_UUNSTUFF(ht_get(counts, obj)); count = HT_UUNSTUFF(ht_get(counts, obj));
} else { } else {
count = REFCOUNT_OBJECT_ENTRY(ctx, obj)->impl.counted.ref_count; count = REFCOUNT_OBJECT_ENTRY(ctx, obj)->impl.counted.ref_count;
++seen_objects;
// don't recuse into objects multiple times // don't recuse into objects multiple times
obj_held_refs(ctx, obj, &queue); obj_held_refs(ctx, obj, &queue);
} }
@ -674,6 +677,7 @@ static ptrdiff_t check_gc_root(RefcountContext *ctx, RefcountList **root_ptr) {
} }
} }
} }
size_t seen_objects = ht_count(counts);
ptrdiff_t freed_count = 0; ptrdiff_t freed_count = 0;
if (seen_objects == clear_objects if (seen_objects == clear_objects
&& !call_destructors_for_gc(ctx, counts)) { && !call_destructors_for_gc(ctx, counts)) {