--- stack/stack.c 2003/08/18 14:39:16 1.136 +++ stack/stack.c 2004/02/19 15:35:38 1.137 @@ -23,7 +23,7 @@ #include "stack.h" -const char* start_message= "Stack version $Revision: 1.136 $\n\ +const char* start_message= "Stack version $Revision: 1.137 $\n\ Copyright (C) 2002 Mats Alritzson and Teddy Hogeborn\n\ Stack comes with ABSOLUTELY NO WARRANTY; for details type 'warranty;'.\n\ This is free software, and you are welcome to redistribute it\n\ @@ -132,166 +132,6 @@ } -/* Mark values recursively. - Marked values are not collected by the GC. */ -inline void gc_mark(value *val) -{ - if(val==NULL || val->gc.flag.mark) - return; - - val->gc.flag.mark= 1; - - if(val->type==tcons) { - gc_mark(CAR(val)); - gc_mark(CDR(val)); - } -} - - -/* Start GC */ -extern void gc_init(environment *env) -{ - stackitem *new_head= NULL, *titem; - symbol *tsymb; - int i; - - if(env->interactive) - printf("Garbage collecting."); - - /* Mark values on stack */ - gc_mark(env->head); - - if(env->interactive) - printf("."); - - /* Mark values in hashtable */ - for(i= 0; isymbols[i]; tsymb!=NULL; tsymb= tsymb->next) - if (tsymb->val != NULL) - gc_mark(tsymb->val); - - if(env->interactive) - printf("."); - - env->gc_count= 0; - - while(env->gc_ref!=NULL) { /* Sweep unused values */ - if(!(env->gc_ref->item->gc.no_gc)){ /* neither mark nor protect */ - - /* Remove content */ - switch(env->gc_ref->item->type){ - case string: - free(env->gc_ref->item->content.string); - break; - case tcons: - free(env->gc_ref->item->content.c); - break; - case port: - case empty: - case unknown: - case integer: - case tfloat: - case func: - case symb: - /* Symbol strings are freed when walking the hash table */ - break; - } - - free(env->gc_ref->item); /* Remove from gc_ref */ - titem= env->gc_ref->next; - free(env->gc_ref); /* Remove value */ - env->gc_ref= titem; - continue; - } - -#ifdef DEBUG - printf("Kept value (%p)", env->gc_ref->item); - if(env->gc_ref->item->gc.flag.mark) - printf(" (marked)"); - if(env->gc_ref->item->gc.flag.protect) - printf(" (protected)"); - switch(env->gc_ref->item->type){ - case integer: - printf(" integer: %d", env->gc_ref->item->content.i); - break; - case func: - printf(" func: %p", env->gc_ref->item->content.func); - break; - case symb: - printf(" symb: %s", env->gc_ref->item->content.sym->id); - break; - case tcons: - printf(" tcons: %p\t%p", CAR(env->gc_ref->item), - CDR(env->gc_ref->item)); - break; - default: - printf(" ", (env->gc_ref->item->type)); - } - printf("\n"); -#endif /* DEBUG */ - - /* Keep values */ - env->gc_count += sizeof(value); - if(env->gc_ref->item->type==string) - env->gc_count += strlen(env->gc_ref->item->content.string)+1; - - titem= env->gc_ref->next; - env->gc_ref->next= new_head; - new_head= env->gc_ref; - new_head->item->gc.flag.mark= 0; - env->gc_ref= titem; - } - - if (env->gc_limit < env->gc_count*2) - env->gc_limit= env->gc_count*2; - - env->gc_ref= new_head; - - if(env->interactive) - printf("done (%d bytes still allocated)\n", env->gc_count); - -} - - -inline void gc_maybe(environment *env) -{ - if(env->gc_count < env->gc_limit) - return; - else - return gc_init(env); -} - - -/* Protect values from GC */ -void protect(value *val) -{ - if(val==NULL || val->gc.flag.protect) - return; - - val->gc.flag.protect= 1; - - if(val->type==tcons) { - protect(CAR(val)); - protect(CDR(val)); - } -} - - -/* Unprotect values from GC */ -void unprotect(value *val) -{ - if(val==NULL || !(val->gc.flag.protect)) - return; - - val->gc.flag.protect= 0; - - if(val->type==tcons) { - unprotect(CAR(val)); - unprotect(CDR(val)); - } -} - - /* Push a value onto the stack */ void push_val(environment *env, value *val) {