#include #include "lisp.h" /* storage module for SIMULISP */ #define PAGEINCR 16 /* number of pages to snarf at a time */ #define NBYTES 4192 /* no. of bytes to allocate for byte pool */ objptr fr_ptr[NTYPES]; /* linked free lists for each type */ char o_size[NTYPES] = /* # of objects that make up each type */ { 0, 0, FLOSIZE, SYMSIZE, CONSSIZE, 0, 0, 0, 0 }; struct Cons nil_proto; /* actual abode of nil */ object nil; page *fr_pgs; /* linked list of free pages */ char *by_pool; /* pointer to current byte pool */ int by_index; /* gc'able pages are remembered in a table which is itself a linked * list of pages -- the first entry in each page points to the next * page in the list, if any. */ page *gc_pages; /* ptr to current page in gc page list */ int gc_index; /* index to last used entry in current page */ /* init storage data bases */ i_storage() { register int i; register cons *n = &nil_proto; register value sunn; /* for sun unix cc bug */ for (i=0; icar = nil; n->cdr = nil; } /* allocate a page -- gctype<>0 if page should be swept during garbage * collection. */ page *al_page(gctype) int gctype; { register page *nextpage = fr_pgs; register int sunnextpage; /* sun unix cc bug */ register page *temp; object p = NULL; register int i; int amount = PAGEINCR*OBJPAGESIZE*sizeof(object); /* if no more pages, allocate another batch from the system */ if (nextpage == NULL) { fr_pgs = (page *)malloc(amount); if (fr_pgs == NULL) { lprintf(stderr,"Out of room\n"); exit(-1); } for (i=0, temp=NULL, nextpage = fr_pgs; i NBYTES) amount = n; if (n>NBYTES-by_index || by_pool==NULL) { if ((by_pool = malloc(amount)) == NULL) { lprintf(stderr,"Out of room\n"); exit(-1); } by_index = 0; } p = &by_pool[by_index]; by_index += n; return(p); } /* recursively mark an object's components */ m_obj(obj) object obj; { register objptr val = (objptr)ADDR(obj); switch (TYPE(obj)) { default: return; case CONS: if (MARKED(*val)) return; SETGCBIT(*val); m_obj(((cons *)val)->car); m_obj(((cons *)val)->cdr); return; case FLONUM: SETGCBIT(*val); return; case SYMBOL: if (MARKED(*val)) return; SETGCBIT(*val); m_obj(((symbol *)val)->sym_value); m_obj(((symbol *)val)->sym_function); m_obj(((symbol *)val)->sym_plist); m_obj(((symbol *)val)->sym_pname); m_obj(((symbol *)val)->sym_hlink); return; } } /* sweep a page of the specified type */ sweep_page(ptr,type) register objptr ptr; int type; { register int size = o_size[type]; register int num = OBJPAGESIZE/size; register int i; register int sunptr; /* sun unix cc bug */ while (num-- > 0) { if (!MARKED(*ptr)) { SETVALUE(*ptr, (sunptr = (int)fr_ptr[type])); fr_ptr[type] = ptr; ptr += size; } else if (type == FLONUM) { CLEARGCBIT(*ptr); ptr += size; } else for (i=size; i-- > 0;) CLEARGCBIT(*ptr++); } } /* garbage collector */ gc() { register page *current; register int index; register cons *n = &nil_proto; object temp; /* first mark all reachable objects */ m_stack(); m_obarray(); /* we'll be reconstructing free lists from scratch */ for (index=0; indexcar); CLEARGCBIT(n->cdr); }