summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--gc.c47
-rw-r--r--lib.c19
-rw-r--r--lib.h1
4 files changed, 68 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 4b3d95c6..b1db5a92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
2012-04-05 Kaz Kylheku <kaz@kylheku.com>
+ Code cleanup and tweaking.
+
+ * gc.c (BACKPTR_VEC_SIZE): Preprocessor symbol renamed to
+ CHECKOBJ_VEC_SIZE.
+ (FULL_GC_INTERVAL): Increased to 40 since the modified
+ algorithm now leaves less work for the full gc to do.
+ (backptr, backptr_idx): Static variables renamed to
+ checkobj and checkobj_idx.
+ (mark): Follows rename of backptr and backptr_idx.
+ (gc): Commented out handy printf added.
+ (gc_set): Use in_malloc_range check to avoid adding to
+ the check array pointers which are being stored in non-heap locations,
+ since non-heap locations are already GC roots.
+ (gc_mutated): Follows variable renaming.
+ (gc_push): Just do the push using gc_set.
+
+ * lib.c (malloc_low_bound, malloc_high_bound): New variables.
+ (chk_malloc, chk_calloc, chk_realloc): Updated malloc_low_bound
+ and malloc_high_bound.
+ (in_malloc_range): New function.
+
+ * lib.h (in_malloc_range): Declared.
+
+2012-04-05 Kaz Kylheku <kaz@kylheku.com>
+
The mut macro should only be used for vectors or vector-like objects
which hold direct references to other objects and must be used
each time a mutation takes place.
diff --git a/gc.c b/gc.c
index c5a66f57..d2bc39e9 100644
--- a/gc.c
+++ b/gc.c
@@ -44,8 +44,8 @@
#define PROT_STACK_SIZE 1024
#define HEAP_SIZE 16384
-#define BACKPTR_VEC_SIZE (2 * HEAP_SIZE)
-#define FULL_GC_INTERVAL 20
+#define CHECKOBJ_VEC_SIZE (2 * HEAP_SIZE)
+#define FULL_GC_INTERVAL 40
#define FRESHQ_SIZE (2 * HEAP_SIZE)
typedef struct heap {
@@ -76,8 +76,8 @@ static val heap_min_bound, heap_max_bound;
int gc_enabled = 1;
#if CONFIG_GEN_GC
-static val backptr[BACKPTR_VEC_SIZE];
-static int backptr_idx;
+static val checkobj[CHECKOBJ_VEC_SIZE];
+static int checkobj_idx;
static val freshobj[FRESHQ_SIZE];
static int freshobj_idx;
static int full_gc;
@@ -403,13 +403,13 @@ static void mark(mach_context_t *pmc, val *gc_stack_top)
#if CONFIG_GEN_GC
/*
- * Mark the backpointers.
+ * Mark the additional objects indicated for marking.
*/
if (!full_gc)
{
int i;
- for (i = 0; i < backptr_idx; i++)
- mark_obj(backptr[i]);
+ for (i = 0; i < checkobj_idx; i++)
+ mark_obj(checkobj[i]);
}
#endif
@@ -555,6 +555,10 @@ void gc(void)
hash_process_weak();
swept = sweep();
#if CONFIG_GEN_GC
+#if 0
+ printf("sweep: freed %d full_gc == %d exhausted == %d\n",
+ (int) swept, full_gc, exhausted);
+#endif
if (full_gc && swept < 3 * HEAP_SIZE / 4)
more();
else if (!full_gc && swept < HEAP_SIZE / 4 && exhausted)
@@ -565,7 +569,7 @@ void gc(void)
#endif
#if CONFIG_GEN_GC
- backptr_idx = 0;
+ checkobj_idx = 0;
freshobj_idx = 0;
full_gc = 0;
#endif
@@ -609,32 +613,27 @@ int gc_is_reachable(val obj)
#if CONFIG_GEN_GC
-val gc_set(val *ptr, val val)
+val gc_set(val *ptr, val obj)
{
- if (!is_ptr(val))
- goto out;
- if (val->t.gen != 0)
- goto out;
- if (backptr_idx >= BACKPTR_VEC_SIZE)
- gc();
- backptr[backptr_idx++] = val;
-out:
- *ptr = val;
- return val;
+ if (in_malloc_range((mem_t *) ptr) && is_ptr(obj) && obj->t.gen == 0) {
+ if (checkobj_idx >= CHECKOBJ_VEC_SIZE)
+ gc();
+ checkobj[checkobj_idx++] = obj;
+ }
+ *ptr = obj;
+ return obj;
}
val gc_mutated(val obj)
{
- if (backptr_idx >= BACKPTR_VEC_SIZE)
+ if (checkobj_idx >= CHECKOBJ_VEC_SIZE)
gc();
- return backptr[backptr_idx++] = obj;
+ return checkobj[checkobj_idx++] = obj;
}
val gc_push(val obj, val *plist)
{
- val ret = push(obj, plist);
- gc_mutated(*plist);
- return ret;
+ return gc_set(plist, cons(obj, *plist));
}
#endif
diff --git a/lib.c b/lib.c
index ae6fd998..52197df1 100644
--- a/lib.c
+++ b/lib.c
@@ -930,11 +930,17 @@ val cobj_equal_op(val left, val right)
return eq(left, right);
}
+static mem_t *malloc_low_bound, *malloc_high_bound;
+
mem_t *chk_malloc(size_t size)
{
mem_t *ptr = (mem_t *) malloc(size);
if (size && ptr == 0)
ptr = (mem_t *) oom_realloc(0, size);
+ if (ptr < malloc_low_bound)
+ malloc_low_bound = ptr;
+ else if (ptr + size > malloc_high_bound)
+ malloc_high_bound = ptr + size;
return ptr;
}
@@ -945,6 +951,10 @@ mem_t *chk_calloc(size_t n, size_t size)
ptr = (mem_t *) oom_realloc(0, size);
memset(ptr, 0, n * size);
}
+ if (ptr < malloc_low_bound)
+ malloc_low_bound = ptr;
+ else if (ptr + size > malloc_high_bound)
+ malloc_high_bound = ptr + size;
return ptr;
}
@@ -953,9 +963,18 @@ mem_t *chk_realloc(mem_t *old, size_t size)
mem_t *newptr = (mem_t *) realloc(old, size);
if (size != 0 && newptr == 0)
newptr = oom_realloc(old, size);
+ if (newptr < malloc_low_bound)
+ malloc_low_bound = newptr;
+ else if (newptr + size > malloc_high_bound)
+ malloc_high_bound = newptr + size;
return newptr;
}
+int in_malloc_range(mem_t *ptr)
+{
+ return ptr >= malloc_low_bound && ptr < malloc_high_bound;
+}
+
wchar_t *chk_strdup(const wchar_t *str)
{
size_t nchar = wcslen(str) + 1;
diff --git a/lib.h b/lib.h
index 2b6baecc..1f8360c1 100644
--- a/lib.h
+++ b/lib.h
@@ -393,6 +393,7 @@ val equal(val left, val right);
mem_t *chk_malloc(size_t size);
mem_t *chk_calloc(size_t n, size_t size);
mem_t *chk_realloc(mem_t *, size_t size);
+int in_malloc_range(mem_t *);
wchar_t *chk_strdup(const wchar_t *str);
val cons(val car, val cdr);
val make_lazy_cons(val func);