summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--gc.c23
2 files changed, 40 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 18dbddfd..3afe57dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2009-11-25 Kaz Kylheku <kkylheku@gmail.com>
+ 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 <kkylheku@gmail.com>
+
More Valgrind support. New option --vg-debug which turns on
Valgrind protection of free blocks. This works independently
of --gc-debug.
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);