diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-06-16 06:59:13 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-06-16 06:59:13 -0700 |
commit | a6c50d7ce44dd36c650a085f8bca4fe2e9074001 (patch) | |
tree | eb334c2e366659d8d7f48543e8b4ceac040a682d | |
parent | 73cc669cc401be80d323864b7591a79cda8f5ff7 (diff) | |
download | txr-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.
-rw-r--r-- | gc.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -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; |