123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- #ifndef NORCSID
- static char rcsid[] = "$Id$";
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include "param.h"
- #include "types.h"
- #include "tes.h"
- #include "assert.h"
- #include "alloc.h"
- #include "line.h"
- #include "lookup.h"
- #include "proinf.h"
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- * Author: Hans van Staveren
- */
- #ifdef USEMALLOC
- short * myalloc();
- #define newcore(size) myalloc(size)
- #define oldcore(p,size) free(p)
- #else
- #undef CORECHECK /* if defined tests are made to insure
- each block occurs at most once */
- #define CCHUNK 1024 /* number of shorts asked from system */
- short *newcore(),*freshcore();
- extern char *sbrk();
- #ifdef COREDEBUG
- int shortsasked=0;
- #endif
- #endif
- /*
- * The following two sizetables contain the sizes of the various kinds
- * of line and argument structures.
- * Care has been taken to make this table implementation independent,
- * but if you think very hard you might find a compiler failing the
- * assumptions made.
- * A wasteful but safe approach is to replace every line of them by
- * sizeof(line_t)
- * and
- * sizeof(arg_t)
- * respectively.
- */
- #define LBASE (sizeof(line_t)-sizeof(un_l_a))
- int lsizetab[] = {
- LBASE,
- LBASE+sizeof(short),
- LBASE+sizeof(offset),
- LBASE+sizeof(num_p),
- LBASE+sizeof(sym_p),
- LBASE+sizeof(s_la_sval),
- LBASE+sizeof(s_la_lval),
- LBASE+sizeof(arg_p),
- LBASE
- };
- #define ABASE (sizeof(arg_t)-sizeof(un_a_a))
- int asizetab[] = {
- ABASE+sizeof(offset),
- ABASE+sizeof(num_p),
- ABASE+sizeof(sym_p),
- ABASE+sizeof(s_a_val),
- ABASE+sizeof(argb_t),
- ABASE+sizeof(s_a_con),
- ABASE+sizeof(s_a_con),
- ABASE+sizeof(s_a_con),
- };
- /*
- * alloc routines:
- * Two parts:
- * 1) typed alloc and free routines
- * 2) untyped raw core allocation
- */
- /*
- * PART 1
- */
- line_p newline(optyp) int optyp; {
- register line_p lnp;
- register kind=optyp;
- if (kind>OPMINI)
- kind = OPMINI;
- lnp = (line_p) newcore(lsizetab[kind]);
- lnp->l_optyp = optyp;
- return(lnp);
- }
- oldline(lnp) register line_p lnp; {
- register kind=lnp->l_optyp&BMASK;
- if (kind>OPMINI)
- kind = OPMINI;
- if (kind == OPLIST)
- oldargs(lnp->l_a.la_arg);
- oldcore((short *) lnp,lsizetab[kind]);
- }
- arg_p newarg(kind) int kind; {
- register arg_p ap;
- ap = (arg_p) newcore(asizetab[kind]);
- ap->a_typ = kind;
- return(ap);
- }
- oldargs(ap) register arg_p ap; {
- register arg_p next;
- while (ap != (arg_p) 0) {
- next = ap->a_next;
- switch(ap->a_typ) {
- case ARGSTR:
- oldargb(ap->a_a.a_string.ab_next);
- break;
- case ARGICN:
- case ARGUCN:
- case ARGFCN:
- oldargb(ap->a_a.a_con.ac_con.ab_next);
- break;
- }
- oldcore((short *) ap,asizetab[ap->a_typ]);
- ap = next;
- }
- }
- oldargb(abp) register argb_p abp; {
- register argb_p next;
- while (abp != (argb_p) 0) {
- next = abp->ab_next;
- oldcore((short *) abp,sizeof (argb_t));
- abp = next;
- }
- }
- reg_p newreg() {
- return((reg_p) newcore(sizeof(reg_t)));
- }
- oldreg(rp) reg_p rp; {
- oldcore((short *) rp,sizeof(reg_t));
- }
- num_p newnum() {
- return((num_p) newcore(sizeof(num_t)));
- }
- oldnum(lp) num_p lp; {
- oldcore((short *) lp,sizeof(num_t));
- }
- offset *newrom() {
- return((offset *) newcore(MAXROM*sizeof(offset)));
- }
- sym_p newsym(len) int len; {
- /*
- * sym_t includes a 2 character s_name at the end
- * extend this structure with len-2 characters
- */
- return((sym_p) newcore(sizeof(sym_t) - 2 + len));
- }
- argb_p newargb() {
- return((argb_p) newcore(sizeof(argb_t)));
- }
- #ifndef USEMALLOC
- /******************************************************************/
- /****** Start of raw core management package *****************/
- /******************************************************************/
- #define MAXSHORT 30 /* Maximum number of shorts one can ask for */
- short *freelist[MAXSHORT];
- typedef struct coreblock {
- struct coreblock *co_next;
- short co_size;
- } core_t,*core_p;
- #define SINC (sizeof(core_t)/sizeof(short))
- #ifdef COREDEBUG
- coreverbose() {
- register size;
- register short *p;
- register sum;
- sum = 0;
- for(size=1;size<MAXSHORT;size++)
- for (p=freelist[size];p!=0;p = *(short **) p)
- sum += size;
- fprintf(stderr,"Used core %u\n",(shortsasked-sum)*sizeof(short));
- }
- #endif
- #ifdef SEPID
- compactcore() {
- register core_p corelist=0,tp,cl;
- int size;
- #ifdef COREDEBUG
- fprintf(stderr,"Almost out of core\n");
- #endif
- for(size=SINC;size<MAXSHORT;size++) {
- while ((tp = (core_p) freelist[size]) != (core_p) 0) {
- freelist[size] = (short *) tp->co_next;
- tp->co_size = size;
- if (corelist==0 || tp<corelist) {
- tp->co_next = corelist;
- corelist = tp;
- } else {
- for(cl=corelist;cl->co_next != 0 && tp>cl->co_next;
- cl = cl->co_next)
- ;
- tp->co_next = cl->co_next;
- cl->co_next = tp;
- }
- }
- }
- while (corelist != 0) {
- while ((short *) corelist->co_next ==
- (short *) corelist + corelist->co_size) {
- corelist->co_size += corelist->co_next->co_size;
- corelist->co_next = corelist->co_next->co_next;
- }
- assert(corelist->co_next==0 ||
- (short *) corelist->co_next >
- (short *) corelist + corelist->co_size);
- while (corelist->co_size >= MAXSHORT+SINC) {
- oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1),
- sizeof(short)*(MAXSHORT-1));
- corelist->co_size -= MAXSHORT;
- }
- if (corelist->co_size >= MAXSHORT) {
- oldcore((short *) corelist + corelist->co_size-SINC,
- sizeof(short)*SINC);
- corelist->co_size -= SINC;
- }
- cl = corelist->co_next;
- oldcore((short *) corelist, sizeof(short)*corelist->co_size);
- corelist = cl;
- }
- }
- short *grabcore(size) int size; {
- register short *p;
- register trysize;
- /*
- * Desperate situation, can't get more core from system.
- * Postpone giving up just a little bit by splitting up
- * larger free blocks if possible.
- * Algorithm is worst fit.
- */
- assert(size<2*MAXSHORT);
- for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
- p = freelist[trysize/sizeof(short)];
- if ( p != (short *) 0) {
- freelist[trysize/sizeof(short)] = *(short **) p;
- oldcore(p+size/sizeof(short),trysize-size);
- return(p);
- }
- }
- /*
- * Can't get more core from the biggies, try to combine the
- * little ones. This is expensive but probably better than
- * giving up.
- */
- compactcore();
- if ((p=freelist[size/sizeof(short)]) != 0) {
- freelist[size/sizeof(short)] = * (short **) p;
- return(p);
- }
- for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
- p = freelist[trysize/sizeof(short)];
- if ( p != (short *) 0) {
- freelist[trysize/sizeof(short)] = *(short **) p;
- oldcore(p+size/sizeof(short),trysize-size);
- return(p);
- }
- }
- /*
- * That's it then. Finished.
- */
- return(0);
- }
- #endif /* SEPID */
- short *newcore(size) int size; {
- register short *p,*q;
- size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
- if( size < 2*MAXSHORT ) {
- if ((p=freelist[size/sizeof(short)]) != (short *) 0)
- freelist[size/sizeof(short)] = *(short **) p;
- else {
- p = freshcore(size);
- #ifdef SEPID
- if (p == (short *) 0)
- p = grabcore(size);
- #endif
- }
- } else
- p = freshcore(size);
- if (p == 0)
- error("out of memory");
- for (q=p; size > 0 ; size -= sizeof(short))
- *q++ = 0;
- return(p);
- }
- #ifndef USEMALLOC
- /*
- * stdio uses malloc and free.
- * you can use these as substitutes
- */
- char *malloc(size) int size; {
- /*
- * malloc(III) is called by stdio,
- * this routine is a substitute.
- */
- return( (char *) newcore(size));
- }
- free() {
- }
- #endif
- oldcore(p,size) short *p; int size; {
- #ifdef CORECHECK
- register short *cp;
- #endif
- assert(size<2*MAXSHORT);
- #ifdef CORECHECK
- for (cp=freelist[size/sizeof(short)]; cp != (short *) 0;
- cp = *(short **) cp)
- assert(cp != p);
- #endif
- *(short **) p = freelist[size/sizeof(short)];
- freelist[size/sizeof(short)] = p;
- }
- short *ccur,*cend;
- coreinit(p1,p2) short *p1,*p2; {
- /*
- * coreinit is called with the boundaries of a piece of
- * memory that can be used for starters.
- */
- ccur = p1;
- cend = p2;
- }
- short *freshcore(size) int size; {
- register short *temp;
- static int cchunk=CCHUNK;
-
- while(&ccur[size/sizeof(short)] >= cend && cchunk>0) {
- do {
- temp = (short *) sbrk(cchunk*sizeof(short));
- if (temp == (short *) -1)
- cchunk >>= 1;
- else if (temp != cend)
- ccur = cend = temp;
- } while (temp == (short *) -1 && cchunk>0);
- cend += cchunk;
- #ifdef COREDEBUG
- shortsasked += cchunk;
- #endif
- }
- if (cchunk==0)
- return(0);
- temp = ccur;
- ccur = &ccur[size/sizeof(short)];
- return(temp);
- }
- #else /* USEMALLOC */
- coreinit() {
- /*
- * Empty function, no initialization needed
- */
- }
- short *myalloc(size) register size; {
- register short *p,*q;
- p = (short *)malloc(size);
- if (p == 0)
- error("out of memory");
- for(q=p;size>0;size -= sizeof(short))
- *q++ = 0;
- return(p);
- }
- #endif
|