gc: free empty pages in gc_heap_merge()

Moving the code from gc_merge_all_heaps to gc_heap_merge removes
special handling of the start of the list and is (hopefully)
easier to read.

Partial work towards addressing issue #534.
This commit is contained in:
Yorick Hardy 2024-12-31 11:40:10 +02:00
parent 48b95db3d2
commit 546eb76861

33
gc.c
View file

@ -2741,8 +2741,22 @@ void gc_thread_data_free(gc_thread_data * thd)
*/
void gc_heap_merge(gc_heap * hdest, gc_heap * hsrc)
{
int freed = 0;
gc_heap *last = gc_heap_last(hdest);
gc_heap *cur = hsrc, *prev = last, *next;
last->next = hsrc;
// free any empty heaps
while (cur != NULL) {
next = cur->next;
if (gc_is_heap_empty(cur)) {
freed += cur->size;
gc_heap_free(cur, prev);
} else {
prev = cur;
}
cur = next;
}
return freed;
}
/**
@ -2765,23 +2779,10 @@ void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src)
heap_type, hdest, hsrc, hsrc->size);
fflush(stderr);
}
if (hsrc) {
prev = hsrc;
cur = hsrc->next;
while (cur != NULL) {
if (gc_is_heap_empty(cur)) {
gc_heap_free(cur, prev);
}
prev = prev->next;
cur = prev->next;
}
if (gc_is_heap_empty(hsrc) && hsrc->next == NULL) {
free(hsrc);
hsrc = NULL;
}
}
if (hdest && hsrc) {
gc_heap_merge(hdest, hsrc);
freed = gc_heap_merge(hdest, hsrc);
ck_pr_add_ptr(&(dest->cached_heap_total_sizes[heap_type]),
ck_pr_load_ptr(&(src->cached_heap_total_sizes[heap_type]))-freed);
ck_pr_add_ptr(&(dest->cached_heap_total_sizes[heap_type]),
ck_pr_load_ptr(&(src->cached_heap_total_sizes[heap_type])));
ck_pr_add_ptr(&(dest->cached_heap_free_sizes[heap_type]),