summaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-06-16 06:59:13 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-06-16 06:59:13 -0700
commita6c50d7ce44dd36c650a085f8bca4fe2e9074001 (patch)
treeeb334c2e366659d8d7f48543e8b4ceac040a682d /gc.c
parent73cc669cc401be80d323864b7591a79cda8f5ff7 (diff)
downloadtxr-a6c50d7ce44dd36c650a085f8bca4fe2e9074001.tar.gz
txr-a6c50d7ce44dd36c650a085f8bca4fe2e9074001.tar.bz2
txr-a6c50d7ce44dd36c650a085f8bca4fe2e9074001.zip
gc bugfix: maintain free_tail properly.
* gc.c (more): Only set the free_tail if the new memory is being added to an empty free_list. Otherwise free_tail is valid. (make_obj): If we empty the free_list, then reset the free_tail pointer, so it doesn't continue pointing into the object we are returning. (sweep): Remove defensive code which tries to reset the free_tail in the empty free_list case, but assumes that free_tail is correct in the non-empty case.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/gc.c b/gc.c
index a06e7d57..ab7eb7f8 100644
--- a/gc.c
+++ b/gc.c
@@ -130,6 +130,9 @@ static void more(void)
heap_t *heap = coerce(heap_t *, chk_malloc_gc_more(sizeof *heap));
obj_t *block = heap->block, *end = heap->block + HEAP_SIZE;
+ if (free_list == 0)
+ free_tail = &heap->block[0].t.next;
+
if (end > heap_max_bound)
heap_max_bound = end;
@@ -142,8 +145,6 @@ static void more(void)
free_list = block++;
}
- free_tail = &heap->block[0].t.next;
-
heap->next = heap_list;
heap_list = heap;
@@ -183,6 +184,9 @@ val make_obj(void)
VALGRIND_MAKE_MEM_DEFINED(free_list, sizeof *free_list);
#endif
free_list = free_list->t.next;
+
+ if (free_list == 0)
+ free_tail = &free_list;
#if HAVE_VALGRIND
if (opt_vg_debug)
VALGRIND_MAKE_MEM_UNDEFINED(ret, sizeof *ret);
@@ -542,9 +546,6 @@ static int_ptr_t sweep(void)
const int vg_dbg = opt_vg_debug;
#endif
- if (free_list == 0)
- free_tail = &free_list;
-
#if CONFIG_GEN_GC
if (!full_gc) {
int i;