summaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-05-06 08:26:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-05-06 08:26:11 -0700
commitb4fd90ddf5aa2019548997d8fc99c1e7e3c10fa6 (patch)
tree4de96730bb8fcf0c81d8084cd3b426b9ec610c72 /gc.c
parent4516a7472d34a74f89b7b5d26db4f26d62bf9f83 (diff)
downloadtxr-b4fd90ddf5aa2019548997d8fc99c1e7e3c10fa6.tar.gz
txr-b4fd90ddf5aa2019548997d8fc99c1e7e3c10fa6.tar.bz2
txr-b4fd90ddf5aa2019548997d8fc99c1e7e3c10fa6.zip
gc: fight spurious retention.
I've noticed that the January 9, 2020 commit "gc: obtain stack top using alloca" triggers spurious retention when compiling with HAVE_VALGRIND. The finalization test case tests/012/fini.tl breaks because the expected finalizers are not called. Changing the (sys:gc) call to two calls to (sys:gc 1) makes it pass. The culprit seems to be the inlining of the complex function sweep into gc. It has local variables for which spaces has to be reserved, which are not used until after mark() is called; likely the values in those spaces are picked up by the stack scan. Let's make sure that functions called out of gc() are not inlined. * gc.c (mark, sweep, prepare_finals, call_finals): Mark NOTINLINE.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index ce4d5ef7..4f9e6f60 100644
--- a/gc.c
+++ b/gc.c
@@ -519,7 +519,7 @@ static void mark_mem_region(val *low, val *high)
mark_obj_maybe(*low);
}
-static void mark(val *gc_stack_top)
+NOINLINE static void mark(val *gc_stack_top)
{
val **rootloc;
@@ -625,7 +625,7 @@ static int sweep_one(obj_t *block)
return 1;
}
-static int_ptr_t sweep(void)
+NOINLINE static int_ptr_t sweep(void)
{
int_ptr_t free_count = 0;
heap_t **pph;
@@ -731,7 +731,7 @@ static int is_reachable(val obj)
return (t & REACHABLE) != 0;
}
-static void prepare_finals(void)
+NOINLINE static void prepare_finals(void)
{
struct fin_reg *f;
@@ -807,7 +807,7 @@ static int is_unreachable_final(struct fin_reg *f, val ctx)
return !f->reachable;
}
-static void call_finals(void)
+NOINLINE static void call_finals(void)
{
(void) call_finalizers_impl(nil, is_unreachable_final);
}