123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- #include "lib9.h"
- #include "isa.h"
- #include "interp.h"
- #include "pool.h"
- #include "raise.h"
- void freearray(Heap*, int);
- void freelist(Heap*, int);
- void freemodlink(Heap*, int);
- void freechan(Heap*, int);
- Type Tarray = { 1, freearray, markarray, sizeof(Array) };
- Type Tstring = { 1, freestring, noptrs, sizeof(String) };
- Type Tlist = { 1, freelist, marklist, sizeof(List) };
- Type Tmodlink = { 1, freemodlink, markheap, -1, 1, 0, 0, { 0x80 } };
- Type Tchannel = { 1, freechan, markheap, sizeof(Channel), 1,0,0,{0x80} };
- Type Tptr = { 1, 0, markheap, sizeof(WORD*), 1, 0, 0, { 0x80 } };
- Type Tbyte = { 1, 0, 0, 1 };
- Type Tword = { 1, 0, 0, sizeof(WORD) };
- Type Tlong = { 1, 0, 0, sizeof(LONG) };
- Type Treal = { 1, 0, 0, sizeof(REAL) };
- extern Pool* heapmem;
- extern int mutator;
- void (*heapmonitor)(int, void*, ulong);
- #define BIT(bt, nb) (bt & (1<<nb))
- void
- freeptrs(void *v, Type *t)
- {
- int c;
- WORD **w, *x;
- uchar *p, *ep;
- if(t->np == 0)
- return;
- w = (WORD**)v;
- p = t->map;
- ep = p + t->np;
- while(p < ep) {
- c = *p;
- if(c != 0) {
- if(BIT(c, 0) && (x = w[7]) != H) destroy(x);
- if(BIT(c, 1) && (x = w[6]) != H) destroy(x);
- if(BIT(c, 2) && (x = w[5]) != H) destroy(x);
- if(BIT(c, 3) && (x = w[4]) != H) destroy(x);
- if(BIT(c, 4) && (x = w[3]) != H) destroy(x);
- if(BIT(c, 5) && (x = w[2]) != H) destroy(x);
- if(BIT(c, 6) && (x = w[1]) != H) destroy(x);
- if(BIT(c, 7) && (x = w[0]) != H) destroy(x);
- }
- p++;
- w += 8;
- }
- }
- /*
- void
- nilptrs(void *v, Type *t)
- {
- int c, i;
- WORD **w;
- uchar *p, *ep;
- w = (WORD**)v;
- p = t->map;
- ep = p + t->np;
- while(p < ep) {
- c = *p;
- for(i = 0; i < 8; i++){
- if(BIT(c, 7)) *w = H;
- c <<= 1;
- w++;
- }
- p++;
- }
- }
- */
- void
- freechan(Heap *h, int swept)
- {
- Channel *c;
- USED(swept);
- c = H2D(Channel*, h);
- if(c->mover == movtmp)
- freetype(c->mid.t);
- killcomm(&c->send);
- killcomm(&c->recv);
- if (!swept && c->buf != H)
- destroy(c->buf);
- }
- void
- freestring(Heap *h, int swept)
- {
- String *s;
- USED(swept);
- s = H2D(String*, h);
- if(s->tmp != nil)
- free(s->tmp);
- }
- void
- freearray(Heap *h, int swept)
- {
- int i;
- Type *t;
- uchar *v;
- Array *a;
- a = H2D(Array*, h);
- t = a->t;
- if(!swept) {
- if(a->root != H)
- destroy(a->root);
- else
- if(t->np != 0) {
- v = a->data;
- for(i = 0; i < a->len; i++) {
- freeptrs(v, t);
- v += t->size;
- }
- }
- }
- if(t->ref-- == 1) {
- free(t->initialize);
- free(t);
- }
- }
- void
- freelist(Heap *h, int swept)
- {
- Type *t;
- List *l;
- Heap *th;
- l = H2D(List*, h);
- t = l->t;
- if(t != nil) {
- if(!swept && t->np)
- freeptrs(l->data, t);
- t->ref--;
- if(t->ref == 0) {
- free(t->initialize);
- free(t);
- }
- }
- if(swept)
- return;
- l = l->tail;
- while(l != (List*)H) {
- t = l->t;
- th = D2H(l);
- if(th->ref-- != 1)
- break;
- th->t->ref--; /* should be &Tlist and ref shouldn't go to 0 here nor be 0 already */
- if(t != nil) {
- if (t->np)
- freeptrs(l->data, t);
- t->ref--;
- if(t->ref == 0) {
- free(t->initialize);
- free(t);
- }
- }
- l = l->tail;
- if(heapmonitor != nil)
- heapmonitor(1, th, 0);
- poolfree(heapmem, th);
- }
- }
- void
- freemodlink(Heap *h, int swept)
- {
- Modlink *ml;
- ml = H2D(Modlink*, h);
- if(ml->m->rt == DYNMOD)
- freedyndata(ml);
- else if(!swept)
- destroy(ml->MP);
- unload(ml->m);
- }
- int
- heapref(void *v)
- {
- return D2H(v)->ref;
- }
- void
- freeheap(Heap *h, int swept)
- {
- Type *t;
- if(swept)
- return;
- t = h->t;
- if (t->np)
- freeptrs(H2D(void*, h), t);
- }
- void
- destroy(void *v)
- {
- Heap *h;
- Type *t;
- if(v == H)
- return;
- h = D2H(v);
- { Bhdr *b; D2B(b, h); } /* consistency check */
- if(--h->ref > 0 || gchalt > 64) /* Protect 'C' thread stack */
- return;
- if(heapmonitor != nil)
- heapmonitor(1, h, 0);
- t = h->t;
- if(t != nil) {
- gclock();
- t->free(h, 0);
- gcunlock();
- freetype(t);
- }
- poolfree(heapmem, h);
- }
- Type*
- dtype(void (*destroy)(Heap*, int), int size, uchar *map, int mapsize)
- {
- Type *t;
- t = malloc(sizeof(Type)-sizeof(t->map)+mapsize);
- if(t != nil) {
- t->ref = 1;
- t->free = destroy;
- t->mark = markheap;
- t->size = size;
- t->np = mapsize;
- memmove(t->map, map, mapsize);
- }
- return t;
- }
- void*
- checktype(void *v, Type *t, char *name, int newref)
- {
- Heap *h;
- if(v == H || v == nil)
- error(exNilref);
- h = D2H(v);
- if(t == nil || h->t != t)
- errorf("%s: %s", exType, name);
- if(newref){
- h->ref++;
- Setmark(h);
- }
- return v;
- }
- void
- freetype(Type *t)
- {
- if(t == nil || --t->ref > 0)
- return;
- free(t->initialize);
- free(t);
- }
- void
- incmem(void *vw, Type *t)
- {
- Heap *h;
- uchar *p;
- int i, c, m;
- WORD **w, **q, *wp;
- w = (WORD**)vw;
- p = t->map;
- for(i = 0; i < t->np; i++) {
- c = *p++;
- if(c != 0) {
- q = w;
- for(m = 0x80; m != 0; m >>= 1) {
- if((c & m) && (wp = *q) != H) {
- h = D2H(wp);
- h->ref++;
- Setmark(h);
- }
- q++;
- }
- }
- w += 8;
- }
- }
- void
- scanptrs(void *vw, Type *t, void (*f)(void*))
- {
- uchar *p;
- int i, c, m;
- WORD **w, **q, *wp;
- w = (WORD**)vw;
- p = t->map;
- for(i = 0; i < t->np; i++) {
- c = *p++;
- if(c != 0) {
- q = w;
- for(m = 0x80; m != 0; m >>= 1) {
- if((c & m) && (wp = *q) != H)
- f(D2H(wp));
- q++;
- }
- }
- w += 8;
- }
- }
- void
- initmem(Type *t, void *vw)
- {
- int c;
- WORD **w;
- uchar *p, *ep;
- w = (WORD**)vw;
- p = t->map;
- ep = p + t->np;
- while(p < ep) {
- c = *p;
- if(c != 0) {
- if(BIT(c, 0)) w[7] = H;
- if(BIT(c, 1)) w[6] = H;
- if(BIT(c, 2)) w[5] = H;
- if(BIT(c, 3)) w[4] = H;
- if(BIT(c, 4)) w[3] = H;
- if(BIT(c, 5)) w[2] = H;
- if(BIT(c, 6)) w[1] = H;
- if(BIT(c, 7)) w[0] = H;
- }
- p++;
- w += 8;
- }
- }
- Heap*
- nheap(int n)
- {
- Heap *h;
- h = poolalloc(heapmem, sizeof(Heap)+n);
- if(h == nil)
- error(exHeap);
- h->t = nil;
- h->ref = 1;
- h->color = mutator;
- if(heapmonitor != nil)
- heapmonitor(0, h, n);
- return h;
- }
- Heap*
- heapz(Type *t)
- {
- Heap *h;
- h = poolalloc(heapmem, sizeof(Heap)+t->size);
- if(h == nil)
- error(exHeap);
- h->t = t;
- t->ref++;
- h->ref = 1;
- h->color = mutator;
- memset(H2D(void*, h), 0, t->size);
- if(t->np)
- initmem(t, H2D(void*, h));
- if(heapmonitor != nil)
- heapmonitor(0, h, t->size);
- return h;
- }
- Heap*
- heap(Type *t)
- {
- Heap *h;
- h = poolalloc(heapmem, sizeof(Heap)+t->size);
- if(h == nil)
- error(exHeap);
- h->t = t;
- t->ref++;
- h->ref = 1;
- h->color = mutator;
- if(t->np)
- initmem(t, H2D(void*, h));
- if(heapmonitor != nil)
- heapmonitor(0, h, t->size);
- return h;
- }
- Heap*
- heaparray(Type *t, int sz)
- {
- Heap *h;
- Array *a;
- h = nheap(sizeof(Array) + (t->size*sz));
- h->t = &Tarray;
- Tarray.ref++;
- a = H2D(Array*, h);
- a->t = t;
- a->len = sz;
- a->root = H;
- a->data = (uchar*)a + sizeof(Array);
- initarray(t, a);
- return h;
- }
- int
- hmsize(void *v)
- {
- return poolmsize(heapmem, v);
- }
- void
- initarray(Type *t, Array *a)
- {
- int i;
- uchar *p;
- t->ref++;
- if(t->np == 0)
- return;
- p = a->data;
- for(i = 0; i < a->len; i++) {
- initmem(t, p);
- p += t->size;
- }
- }
- void*
- arraycpy(Array *sa)
- {
- int i;
- Heap *dh;
- Array *da;
- uchar *elemp;
- void **sp, **dp;
- if(sa == H)
- return H;
- dh = nheap(sizeof(Array) + sa->t->size*sa->len);
- dh->t = &Tarray;
- Tarray.ref++;
- da = H2D(Array*, dh);
- da->t = sa->t;
- da->t->ref++;
- da->len = sa->len;
- da->root = H;
- da->data = (uchar*)da + sizeof(Array);
- if(da->t == &Tarray) {
- dp = (void**)da->data;
- sp = (void**)sa->data;
- /*
- * Maximum depth of this recursion is set by DADEPTH
- * in include/isa.h
- */
- for(i = 0; i < sa->len; i++)
- dp[i] = arraycpy(sp[i]);
- }
- else {
- memmove(da->data, sa->data, da->len*sa->t->size);
- elemp = da->data;
- for(i = 0; i < sa->len; i++) {
- incmem(elemp, da->t);
- elemp += da->t->size;
- }
- }
- return da;
- }
- void
- newmp(void *dst, void *src, Type *t)
- {
- Heap *h;
- int c, i, m;
- void **uld, *wp, **q;
- memmove(dst, src, t->size);
- uld = dst;
- for(i = 0; i < t->np; i++) {
- c = t->map[i];
- if(c != 0) {
- m = 0x80;
- q = uld;
- while(m != 0) {
- if((m & c) && (wp = *q) != H) {
- h = D2H(wp);
- if(h->t == &Tarray)
- *q = arraycpy(wp);
- else {
- h->ref++;
- Setmark(h);
- }
- }
- m >>= 1;
- q++;
- }
- }
- uld += 8;
- }
- }
|