From a2dc66961f22df647e0428b1e12bae8a2922c503 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 25 Nov 2009 16:05:45 -0800 Subject: Refinements to Valgrind support. --- ChangeLog | 19 +++++++++++++++++++ gc.c | 23 +++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 18dbddfd..3afe57dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2009-11-25 Kaz Kylheku + + Refinements to Valgrind support. + + * gc.c (mark_mem_region): If a pointer from the stack is valid + for the heap, it may point to a free object, which is marked + in accessible. We must grant the garbage collector access + to the object. If the object is free, close off access. + This is not 100% correct, because if the object is accessible + but undefined, then we end up flipping it to defined. + (sweep): Before sweeping each heap, mark the entire block as defined. + This is necessary because sweep accesses blocks, which may be free, + and thus inaccessible. Then, during the sweep, any block + which is already free must be marked inaccessible again. + This means that the remaining blocks that are reachable become defined. + Here that is okay, because gc has marked all those blocks. If any + of them had uninitialized members, that would have been caught + by valgrind during the marking phase, if not sooner. + 2009-11-25 Kaz Kylheku More Valgrind support. New option --vg-debug which turns on diff --git a/gc.c b/gc.c index a8919390..2ba3231f 100644 --- a/gc.c +++ b/gc.c @@ -300,9 +300,17 @@ static void mark_mem_region(val *low, val *high) VALGRIND_MAKE_MEM_DEFINED(&maybe_obj, sizeof maybe_obj); #endif if (in_heap(maybe_obj)) { +#ifdef HAVE_VALGRIND + VALGRIND_MAKE_MEM_DEFINED(maybe_obj, sizeof *maybe_obj); +#endif type_t t = maybe_obj->t.type; - if ((t & FREE) == 0) + if ((t & FREE) == 0) { mark_obj(maybe_obj); + } else { +#ifdef HAVE_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(maybe_obj, sizeof *maybe_obj); +#endif + } } low++; } @@ -335,6 +343,12 @@ static void sweep(void) for (heap = heap_list; heap != 0; heap = heap->next) { obj_t *block, *end; + +#ifdef HAVE_VALGRIND + if (vg_dbg) + VALGRIND_MAKE_MEM_DEFINED(&heap->block, sizeof heap->block); +#endif + for (block = heap->block, end = heap->block + HEAP_SIZE; block < end; block++) @@ -347,8 +361,13 @@ static void sweep(void) continue; } - if (block->t.type & FREE) + if (block->t.type & FREE) { +#ifdef HAVE_VALGRIND + if (vg_dbg) + VALGRIND_MAKE_MEM_NOACCESS(block, sizeof *block); +#endif continue; + } if (0 && gc_dbg) { format(std_error, lit("~a: finalizing: "), progname, nao); -- cgit v1.2.3