/[cvs]/stack/stack.c
ViewVC logotype

Diff of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.136 by masse, Mon Aug 18 14:39:16 2003 UTC revision 1.137 by masse, Thu Feb 19 15:35:38 2004 UTC
# Line 132  value* new_val(environment *env) Line 132  value* new_val(environment *env)
132  }  }
133    
134    
 /* 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; i<HASHTBLSIZE; i++)  
     for(tsymb= env->symbols[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(" <unknown %d>", (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));  
   }  
 }  
   
   
135  /* Push a value onto the stack */  /* Push a value onto the stack */
136  void push_val(environment *env, value *val)  void push_val(environment *env, value *val)
137  {  {

Legend:
Removed from v.1.136  
changed lines
  Added in v.1.137

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26