From 06ced4e18fd69399e7419a59dbe477e9a92c23e1 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 3 Apr 2012 08:40:31 -0700 Subject: * configure: Support a gen-gc configuration variable which causes CONFIG_GEN_GC to be defined as 1 in config.h. * eval.c (op_defvar, dwim_loc, op_modplace, transform_op): Handle mutating assignments via set macro. (op_dohash): Inform gc about mutated variables. TODO here. * filter.c (trie_add, trie_compress): Handle mutating assignments via set macro. * gc.c (BACKPTR_VEC_SIZE, FULL_GC_INTERVAL): New preprocessor symbols. (backptr, backptr_idx, partial_gc_count, full): New static variables. (make_obj): Initialize generation to zero. (gc): Added logic for deciding between full and partial gc. (gc_set, gc_mutated): New functions. * gc.h (gc_set, gc_mutated): Declared. * hash.c (hash_mark): Changed useless use of vecref_l to vecref. (gethash_f): Use set when assigning through *found since it is a possible mutation. * lib.c (car_l, cdr_l, vecref_l): Got rid of loc macro uses. Using the value properly is going to be the caller's responsibility. (push): push may be a mutation, so use set. (intern): Uset set to mutate a hash entry. (acons_new_l, aconsq_new_l): Use set when replacing *list. * lib.h (PTR_BIT): New preprocessor symbol. (obj_common): New macro for defining common object fields. type_t is split into two bitfields, half a pointer wide, allowing for generation to be represented. (struct any, struct cons, struct string, struct sym, struct package, struct func, struct vec, struct lazy_cons, struct cobj, struct env, struct bignum, struct flonum): Use obj_common macro to defined common fields. (loc): Macro removed. (set, mut): Macros conditionally defined for real functionality. (list_collect, list_collect_nconc, list_collect_append): Replace mutating operations with set. * match.c (dest_set, v_cat, v_output, v_filter): Replace mutating operations with set. * stream.c (string_in_get_line, string_in_get_char, strlist_out_put_string, strlist_out_put_char): Replace mutating operations with set. * unwind.c (uw_register_subtype): Replace mutating operation with set. --- gc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'gc.c') diff --git a/gc.c b/gc.c index 7df908c6..a644be3a 100644 --- a/gc.c +++ b/gc.c @@ -44,6 +44,8 @@ #define PROT_STACK_SIZE 1024 #define HEAP_SIZE 16384 +#define BACKPTR_VEC_SIZE 4096 +#define FULL_GC_INTERVAL 10 typedef struct heap { struct heap *next; @@ -72,6 +74,13 @@ 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 int partial_gc_count; +static int full; +#endif + #if EXTRA_DEBUGGING static val break_obj; #endif @@ -164,6 +173,9 @@ val make_obj(void) #ifdef HAVE_VALGRIND if (opt_vg_debug) VALGRIND_MAKE_MEM_UNDEFINED(ret, sizeof *ret); +#endif +#if CONFIG_GEN_GC + ret->t.gen = 0; #endif return ret; } @@ -472,6 +484,16 @@ void gc(void) { val gc_stack_top = nil; +#if CONFIG_GEN_GC + if (backptr_idx && ++partial_gc_count == FULL_GC_INTERVAL) { + full = 1; + partial_gc_count = 0; + backptr_idx = 0; + } else { + full = 0; + } +#endif + if (gc_enabled) { mach_context_t mc; save_context(mc); @@ -513,6 +535,34 @@ int gc_is_reachable(val obj) return (t & REACHABLE) != 0; } +#if CONFIG_GEN_GC + +val gc_set(val *ptr, val val) +{ + if (!is_ptr(val)) + goto out; + if (val->t.gen != 0) + goto out; + + backptr[backptr_idx++] = val; +out: + *ptr = val; + + if (backptr_idx == BACKPTR_VEC_SIZE) + gc(); + + return val; +} + +void gc_mutated(val obj) +{ + backptr[backptr_idx++] = obj; + if (backptr_idx == BACKPTR_VEC_SIZE) + gc(); +} + +#endif + /* * Useful functions for gdb'ing. */ -- cgit v1.2.3