diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | gc.c | 47 | ||||
-rw-r--r-- | lib.c | 19 | ||||
-rw-r--r-- | lib.h | 1 |
4 files changed, 68 insertions, 24 deletions
@@ -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. @@ -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 @@ -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; @@ -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); |