137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "isa.h"
337da2899SCharles.Forsyth #include "interp.h"
437da2899SCharles.Forsyth #include "pool.h"
537da2899SCharles.Forsyth #include "raise.h"
637da2899SCharles.Forsyth
737da2899SCharles.Forsyth void freearray(Heap*, int);
837da2899SCharles.Forsyth void freelist(Heap*, int);
937da2899SCharles.Forsyth void freemodlink(Heap*, int);
1037da2899SCharles.Forsyth void freechan(Heap*, int);
1137da2899SCharles.Forsyth Type Tarray = { 1, freearray, markarray, sizeof(Array) };
1237da2899SCharles.Forsyth Type Tstring = { 1, freestring, noptrs, sizeof(String) };
1337da2899SCharles.Forsyth Type Tlist = { 1, freelist, marklist, sizeof(List) };
1437da2899SCharles.Forsyth Type Tmodlink = { 1, freemodlink, markheap, -1, 1, 0, 0, { 0x80 } };
1537da2899SCharles.Forsyth Type Tchannel = { 1, freechan, markheap, sizeof(Channel), 1,0,0,{0x80} };
1637da2899SCharles.Forsyth Type Tptr = { 1, 0, markheap, sizeof(WORD*), 1, 0, 0, { 0x80 } };
1737da2899SCharles.Forsyth Type Tbyte = { 1, 0, 0, 1 };
1837da2899SCharles.Forsyth Type Tword = { 1, 0, 0, sizeof(WORD) };
1937da2899SCharles.Forsyth Type Tlong = { 1, 0, 0, sizeof(LONG) };
2037da2899SCharles.Forsyth Type Treal = { 1, 0, 0, sizeof(REAL) };
2137da2899SCharles.Forsyth
2237da2899SCharles.Forsyth extern Pool* heapmem;
2337da2899SCharles.Forsyth extern int mutator;
2437da2899SCharles.Forsyth
2537da2899SCharles.Forsyth void (*heapmonitor)(int, void*, ulong);
2637da2899SCharles.Forsyth
2737da2899SCharles.Forsyth #define BIT(bt, nb) (bt & (1<<nb))
2837da2899SCharles.Forsyth
2937da2899SCharles.Forsyth void
freeptrs(void * v,Type * t)3037da2899SCharles.Forsyth freeptrs(void *v, Type *t)
3137da2899SCharles.Forsyth {
3237da2899SCharles.Forsyth int c;
3337da2899SCharles.Forsyth WORD **w, *x;
3437da2899SCharles.Forsyth uchar *p, *ep;
3537da2899SCharles.Forsyth
3637da2899SCharles.Forsyth if(t->np == 0)
3737da2899SCharles.Forsyth return;
3837da2899SCharles.Forsyth
3937da2899SCharles.Forsyth w = (WORD**)v;
4037da2899SCharles.Forsyth p = t->map;
4137da2899SCharles.Forsyth ep = p + t->np;
4237da2899SCharles.Forsyth while(p < ep) {
4337da2899SCharles.Forsyth c = *p;
4437da2899SCharles.Forsyth if(c != 0) {
4537da2899SCharles.Forsyth if(BIT(c, 0) && (x = w[7]) != H) destroy(x);
4637da2899SCharles.Forsyth if(BIT(c, 1) && (x = w[6]) != H) destroy(x);
4737da2899SCharles.Forsyth if(BIT(c, 2) && (x = w[5]) != H) destroy(x);
4837da2899SCharles.Forsyth if(BIT(c, 3) && (x = w[4]) != H) destroy(x);
4937da2899SCharles.Forsyth if(BIT(c, 4) && (x = w[3]) != H) destroy(x);
5037da2899SCharles.Forsyth if(BIT(c, 5) && (x = w[2]) != H) destroy(x);
5137da2899SCharles.Forsyth if(BIT(c, 6) && (x = w[1]) != H) destroy(x);
5237da2899SCharles.Forsyth if(BIT(c, 7) && (x = w[0]) != H) destroy(x);
5337da2899SCharles.Forsyth }
5437da2899SCharles.Forsyth p++;
5537da2899SCharles.Forsyth w += 8;
5637da2899SCharles.Forsyth }
5737da2899SCharles.Forsyth }
5837da2899SCharles.Forsyth
5937da2899SCharles.Forsyth /*
6037da2899SCharles.Forsyth void
6137da2899SCharles.Forsyth nilptrs(void *v, Type *t)
6237da2899SCharles.Forsyth {
6337da2899SCharles.Forsyth int c, i;
6437da2899SCharles.Forsyth WORD **w;
6537da2899SCharles.Forsyth uchar *p, *ep;
6637da2899SCharles.Forsyth
6737da2899SCharles.Forsyth w = (WORD**)v;
6837da2899SCharles.Forsyth p = t->map;
6937da2899SCharles.Forsyth ep = p + t->np;
7037da2899SCharles.Forsyth while(p < ep) {
7137da2899SCharles.Forsyth c = *p;
7237da2899SCharles.Forsyth for(i = 0; i < 8; i++){
7337da2899SCharles.Forsyth if(BIT(c, 7)) *w = H;
7437da2899SCharles.Forsyth c <<= 1;
7537da2899SCharles.Forsyth w++;
7637da2899SCharles.Forsyth }
7737da2899SCharles.Forsyth p++;
7837da2899SCharles.Forsyth }
7937da2899SCharles.Forsyth }
8037da2899SCharles.Forsyth */
8137da2899SCharles.Forsyth
8237da2899SCharles.Forsyth void
freechan(Heap * h,int swept)8337da2899SCharles.Forsyth freechan(Heap *h, int swept)
8437da2899SCharles.Forsyth {
8537da2899SCharles.Forsyth Channel *c;
8637da2899SCharles.Forsyth
8737da2899SCharles.Forsyth USED(swept);
8837da2899SCharles.Forsyth c = H2D(Channel*, h);
8937da2899SCharles.Forsyth if(c->mover == movtmp)
9037da2899SCharles.Forsyth freetype(c->mid.t);
9137da2899SCharles.Forsyth killcomm(&c->send);
9237da2899SCharles.Forsyth killcomm(&c->recv);
9337da2899SCharles.Forsyth if (!swept && c->buf != H)
9437da2899SCharles.Forsyth destroy(c->buf);
9537da2899SCharles.Forsyth }
9637da2899SCharles.Forsyth
9737da2899SCharles.Forsyth void
freestring(Heap * h,int swept)9837da2899SCharles.Forsyth freestring(Heap *h, int swept)
9937da2899SCharles.Forsyth {
10037da2899SCharles.Forsyth String *s;
10137da2899SCharles.Forsyth
10237da2899SCharles.Forsyth USED(swept);
10337da2899SCharles.Forsyth s = H2D(String*, h);
10437da2899SCharles.Forsyth if(s->tmp != nil)
10537da2899SCharles.Forsyth free(s->tmp);
10637da2899SCharles.Forsyth }
10737da2899SCharles.Forsyth
10837da2899SCharles.Forsyth void
freearray(Heap * h,int swept)10937da2899SCharles.Forsyth freearray(Heap *h, int swept)
11037da2899SCharles.Forsyth {
11137da2899SCharles.Forsyth int i;
11237da2899SCharles.Forsyth Type *t;
11337da2899SCharles.Forsyth uchar *v;
11437da2899SCharles.Forsyth Array *a;
11537da2899SCharles.Forsyth
11637da2899SCharles.Forsyth a = H2D(Array*, h);
11737da2899SCharles.Forsyth t = a->t;
11837da2899SCharles.Forsyth
11937da2899SCharles.Forsyth if(!swept) {
12037da2899SCharles.Forsyth if(a->root != H)
12137da2899SCharles.Forsyth destroy(a->root);
12237da2899SCharles.Forsyth else
12337da2899SCharles.Forsyth if(t->np != 0) {
12437da2899SCharles.Forsyth v = a->data;
12537da2899SCharles.Forsyth for(i = 0; i < a->len; i++) {
12637da2899SCharles.Forsyth freeptrs(v, t);
12737da2899SCharles.Forsyth v += t->size;
12837da2899SCharles.Forsyth }
12937da2899SCharles.Forsyth }
13037da2899SCharles.Forsyth }
13137da2899SCharles.Forsyth if(t->ref-- == 1) {
13237da2899SCharles.Forsyth free(t->initialize);
13337da2899SCharles.Forsyth free(t);
13437da2899SCharles.Forsyth }
13537da2899SCharles.Forsyth }
13637da2899SCharles.Forsyth
13737da2899SCharles.Forsyth void
freelist(Heap * h,int swept)13837da2899SCharles.Forsyth freelist(Heap *h, int swept)
13937da2899SCharles.Forsyth {
14037da2899SCharles.Forsyth Type *t;
14137da2899SCharles.Forsyth List *l;
14237da2899SCharles.Forsyth Heap *th;
14337da2899SCharles.Forsyth
14437da2899SCharles.Forsyth l = H2D(List*, h);
14537da2899SCharles.Forsyth t = l->t;
14637da2899SCharles.Forsyth
14737da2899SCharles.Forsyth if(t != nil) {
14837da2899SCharles.Forsyth if(!swept && t->np)
14937da2899SCharles.Forsyth freeptrs(l->data, t);
15037da2899SCharles.Forsyth t->ref--;
15137da2899SCharles.Forsyth if(t->ref == 0) {
15237da2899SCharles.Forsyth free(t->initialize);
15337da2899SCharles.Forsyth free(t);
15437da2899SCharles.Forsyth }
15537da2899SCharles.Forsyth }
15637da2899SCharles.Forsyth if(swept)
15737da2899SCharles.Forsyth return;
15837da2899SCharles.Forsyth l = l->tail;
15937da2899SCharles.Forsyth while(l != (List*)H) {
16037da2899SCharles.Forsyth t = l->t;
161*4d5741c9Sforsyth th = D2H(l);
16237da2899SCharles.Forsyth if(th->ref-- != 1)
16337da2899SCharles.Forsyth break;
16437da2899SCharles.Forsyth th->t->ref--; /* should be &Tlist and ref shouldn't go to 0 here nor be 0 already */
16537da2899SCharles.Forsyth if(t != nil) {
16637da2899SCharles.Forsyth if (t->np)
16737da2899SCharles.Forsyth freeptrs(l->data, t);
16837da2899SCharles.Forsyth t->ref--;
16937da2899SCharles.Forsyth if(t->ref == 0) {
17037da2899SCharles.Forsyth free(t->initialize);
17137da2899SCharles.Forsyth free(t);
17237da2899SCharles.Forsyth }
17337da2899SCharles.Forsyth }
17437da2899SCharles.Forsyth l = l->tail;
17537da2899SCharles.Forsyth if(heapmonitor != nil)
17637da2899SCharles.Forsyth heapmonitor(1, th, 0);
17737da2899SCharles.Forsyth poolfree(heapmem, th);
17837da2899SCharles.Forsyth }
17937da2899SCharles.Forsyth }
18037da2899SCharles.Forsyth
18137da2899SCharles.Forsyth void
freemodlink(Heap * h,int swept)18237da2899SCharles.Forsyth freemodlink(Heap *h, int swept)
18337da2899SCharles.Forsyth {
18437da2899SCharles.Forsyth Modlink *ml;
18537da2899SCharles.Forsyth
18637da2899SCharles.Forsyth ml = H2D(Modlink*, h);
18737da2899SCharles.Forsyth if(ml->m->rt == DYNMOD)
18837da2899SCharles.Forsyth freedyndata(ml);
18937da2899SCharles.Forsyth else if(!swept)
19037da2899SCharles.Forsyth destroy(ml->MP);
19137da2899SCharles.Forsyth unload(ml->m);
19237da2899SCharles.Forsyth }
19337da2899SCharles.Forsyth
19437da2899SCharles.Forsyth int
heapref(void * v)19537da2899SCharles.Forsyth heapref(void *v)
19637da2899SCharles.Forsyth {
19737da2899SCharles.Forsyth return D2H(v)->ref;
19837da2899SCharles.Forsyth }
19937da2899SCharles.Forsyth
20037da2899SCharles.Forsyth void
freeheap(Heap * h,int swept)20137da2899SCharles.Forsyth freeheap(Heap *h, int swept)
20237da2899SCharles.Forsyth {
20337da2899SCharles.Forsyth Type *t;
20437da2899SCharles.Forsyth
20537da2899SCharles.Forsyth if(swept)
20637da2899SCharles.Forsyth return;
20737da2899SCharles.Forsyth
20837da2899SCharles.Forsyth t = h->t;
20937da2899SCharles.Forsyth if (t->np)
21037da2899SCharles.Forsyth freeptrs(H2D(void*, h), t);
21137da2899SCharles.Forsyth }
21237da2899SCharles.Forsyth
21337da2899SCharles.Forsyth void
destroy(void * v)21437da2899SCharles.Forsyth destroy(void *v)
21537da2899SCharles.Forsyth {
21637da2899SCharles.Forsyth Heap *h;
21737da2899SCharles.Forsyth Type *t;
21837da2899SCharles.Forsyth
21937da2899SCharles.Forsyth if(v == H)
22037da2899SCharles.Forsyth return;
22137da2899SCharles.Forsyth
22237da2899SCharles.Forsyth h = D2H(v);
22337da2899SCharles.Forsyth { Bhdr *b; D2B(b, h); } /* consistency check */
22437da2899SCharles.Forsyth
22537da2899SCharles.Forsyth if(--h->ref > 0 || gchalt > 64) /* Protect 'C' thread stack */
22637da2899SCharles.Forsyth return;
22737da2899SCharles.Forsyth
22837da2899SCharles.Forsyth if(heapmonitor != nil)
22937da2899SCharles.Forsyth heapmonitor(1, h, 0);
23037da2899SCharles.Forsyth t = h->t;
23137da2899SCharles.Forsyth if(t != nil) {
23237da2899SCharles.Forsyth gclock();
23337da2899SCharles.Forsyth t->free(h, 0);
23437da2899SCharles.Forsyth gcunlock();
23537da2899SCharles.Forsyth freetype(t);
23637da2899SCharles.Forsyth }
23737da2899SCharles.Forsyth poolfree(heapmem, h);
23837da2899SCharles.Forsyth }
23937da2899SCharles.Forsyth
2407de2b42dSforsyth Type*
dtype(void (* destroy)(Heap *,int),int size,uchar * map,int mapsize)2417de2b42dSforsyth dtype(void (*destroy)(Heap*, int), int size, uchar *map, int mapsize)
2427de2b42dSforsyth {
2437de2b42dSforsyth Type *t;
2447de2b42dSforsyth
245*4d5741c9Sforsyth t = malloc(sizeof(Type)-sizeof(t->map)+mapsize);
2467de2b42dSforsyth if(t != nil) {
2477de2b42dSforsyth t->ref = 1;
2487de2b42dSforsyth t->free = destroy;
2497de2b42dSforsyth t->mark = markheap;
2507de2b42dSforsyth t->size = size;
2517de2b42dSforsyth t->np = mapsize;
2527de2b42dSforsyth memmove(t->map, map, mapsize);
2537de2b42dSforsyth }
2547de2b42dSforsyth return t;
2557de2b42dSforsyth }
2567de2b42dSforsyth
2577de2b42dSforsyth void*
checktype(void * v,Type * t,char * name,int newref)2587de2b42dSforsyth checktype(void *v, Type *t, char *name, int newref)
2597de2b42dSforsyth {
2607de2b42dSforsyth Heap *h;
2617de2b42dSforsyth
2627de2b42dSforsyth if(v == H || v == nil)
2637de2b42dSforsyth error(exNilref);
2647de2b42dSforsyth h = D2H(v);
2657de2b42dSforsyth if(t == nil || h->t != t)
2667de2b42dSforsyth errorf("%s: %s", exType, name);
2677de2b42dSforsyth if(newref){
2687de2b42dSforsyth h->ref++;
2697de2b42dSforsyth Setmark(h);
2707de2b42dSforsyth }
2717de2b42dSforsyth return v;
2727de2b42dSforsyth }
2737de2b42dSforsyth
27437da2899SCharles.Forsyth void
freetype(Type * t)27537da2899SCharles.Forsyth freetype(Type *t)
27637da2899SCharles.Forsyth {
27737da2899SCharles.Forsyth if(t == nil || --t->ref > 0)
27837da2899SCharles.Forsyth return;
27937da2899SCharles.Forsyth
28037da2899SCharles.Forsyth free(t->initialize);
28137da2899SCharles.Forsyth free(t);
28237da2899SCharles.Forsyth }
28337da2899SCharles.Forsyth
28437da2899SCharles.Forsyth void
incmem(void * vw,Type * t)28537da2899SCharles.Forsyth incmem(void *vw, Type *t)
28637da2899SCharles.Forsyth {
28737da2899SCharles.Forsyth Heap *h;
28837da2899SCharles.Forsyth uchar *p;
28937da2899SCharles.Forsyth int i, c, m;
29037da2899SCharles.Forsyth WORD **w, **q, *wp;
29137da2899SCharles.Forsyth
29237da2899SCharles.Forsyth w = (WORD**)vw;
29337da2899SCharles.Forsyth p = t->map;
29437da2899SCharles.Forsyth for(i = 0; i < t->np; i++) {
29537da2899SCharles.Forsyth c = *p++;
29637da2899SCharles.Forsyth if(c != 0) {
29737da2899SCharles.Forsyth q = w;
29837da2899SCharles.Forsyth for(m = 0x80; m != 0; m >>= 1) {
29937da2899SCharles.Forsyth if((c & m) && (wp = *q) != H) {
30037da2899SCharles.Forsyth h = D2H(wp);
30137da2899SCharles.Forsyth h->ref++;
30237da2899SCharles.Forsyth Setmark(h);
30337da2899SCharles.Forsyth }
30437da2899SCharles.Forsyth q++;
30537da2899SCharles.Forsyth }
30637da2899SCharles.Forsyth }
30737da2899SCharles.Forsyth w += 8;
30837da2899SCharles.Forsyth }
30937da2899SCharles.Forsyth }
31037da2899SCharles.Forsyth
31137da2899SCharles.Forsyth void
scanptrs(void * vw,Type * t,void (* f)(void *))31237da2899SCharles.Forsyth scanptrs(void *vw, Type *t, void (*f)(void*))
31337da2899SCharles.Forsyth {
31437da2899SCharles.Forsyth uchar *p;
31537da2899SCharles.Forsyth int i, c, m;
31637da2899SCharles.Forsyth WORD **w, **q, *wp;
31737da2899SCharles.Forsyth
31837da2899SCharles.Forsyth w = (WORD**)vw;
31937da2899SCharles.Forsyth p = t->map;
32037da2899SCharles.Forsyth for(i = 0; i < t->np; i++) {
32137da2899SCharles.Forsyth c = *p++;
32237da2899SCharles.Forsyth if(c != 0) {
32337da2899SCharles.Forsyth q = w;
32437da2899SCharles.Forsyth for(m = 0x80; m != 0; m >>= 1) {
32537da2899SCharles.Forsyth if((c & m) && (wp = *q) != H)
32637da2899SCharles.Forsyth f(D2H(wp));
32737da2899SCharles.Forsyth q++;
32837da2899SCharles.Forsyth }
32937da2899SCharles.Forsyth }
33037da2899SCharles.Forsyth w += 8;
33137da2899SCharles.Forsyth }
33237da2899SCharles.Forsyth }
33337da2899SCharles.Forsyth
33437da2899SCharles.Forsyth void
initmem(Type * t,void * vw)33537da2899SCharles.Forsyth initmem(Type *t, void *vw)
33637da2899SCharles.Forsyth {
33737da2899SCharles.Forsyth int c;
33837da2899SCharles.Forsyth WORD **w;
33937da2899SCharles.Forsyth uchar *p, *ep;
34037da2899SCharles.Forsyth
34137da2899SCharles.Forsyth w = (WORD**)vw;
34237da2899SCharles.Forsyth p = t->map;
34337da2899SCharles.Forsyth ep = p + t->np;
34437da2899SCharles.Forsyth while(p < ep) {
34537da2899SCharles.Forsyth c = *p;
34637da2899SCharles.Forsyth if(c != 0) {
34737da2899SCharles.Forsyth if(BIT(c, 0)) w[7] = H;
34837da2899SCharles.Forsyth if(BIT(c, 1)) w[6] = H;
34937da2899SCharles.Forsyth if(BIT(c, 2)) w[5] = H;
35037da2899SCharles.Forsyth if(BIT(c, 3)) w[4] = H;
35137da2899SCharles.Forsyth if(BIT(c, 4)) w[3] = H;
35237da2899SCharles.Forsyth if(BIT(c, 5)) w[2] = H;
35337da2899SCharles.Forsyth if(BIT(c, 6)) w[1] = H;
35437da2899SCharles.Forsyth if(BIT(c, 7)) w[0] = H;
35537da2899SCharles.Forsyth }
35637da2899SCharles.Forsyth p++;
35737da2899SCharles.Forsyth w += 8;
35837da2899SCharles.Forsyth }
35937da2899SCharles.Forsyth }
36037da2899SCharles.Forsyth
36137da2899SCharles.Forsyth Heap*
nheap(int n)36237da2899SCharles.Forsyth nheap(int n)
36337da2899SCharles.Forsyth {
36437da2899SCharles.Forsyth Heap *h;
36537da2899SCharles.Forsyth
36637da2899SCharles.Forsyth h = poolalloc(heapmem, sizeof(Heap)+n);
36737da2899SCharles.Forsyth if(h == nil)
36837da2899SCharles.Forsyth error(exHeap);
36937da2899SCharles.Forsyth
37037da2899SCharles.Forsyth h->t = nil;
37137da2899SCharles.Forsyth h->ref = 1;
37237da2899SCharles.Forsyth h->color = mutator;
37337da2899SCharles.Forsyth if(heapmonitor != nil)
37437da2899SCharles.Forsyth heapmonitor(0, h, n);
37537da2899SCharles.Forsyth
37637da2899SCharles.Forsyth return h;
37737da2899SCharles.Forsyth }
37837da2899SCharles.Forsyth
37937da2899SCharles.Forsyth Heap*
heapz(Type * t)38037da2899SCharles.Forsyth heapz(Type *t)
38137da2899SCharles.Forsyth {
38237da2899SCharles.Forsyth Heap *h;
38337da2899SCharles.Forsyth
38437da2899SCharles.Forsyth h = poolalloc(heapmem, sizeof(Heap)+t->size);
38537da2899SCharles.Forsyth if(h == nil)
38637da2899SCharles.Forsyth error(exHeap);
38737da2899SCharles.Forsyth
38837da2899SCharles.Forsyth h->t = t;
38937da2899SCharles.Forsyth t->ref++;
39037da2899SCharles.Forsyth h->ref = 1;
39137da2899SCharles.Forsyth h->color = mutator;
39237da2899SCharles.Forsyth memset(H2D(void*, h), 0, t->size);
39337da2899SCharles.Forsyth if(t->np)
39437da2899SCharles.Forsyth initmem(t, H2D(void*, h));
39537da2899SCharles.Forsyth if(heapmonitor != nil)
39637da2899SCharles.Forsyth heapmonitor(0, h, t->size);
39737da2899SCharles.Forsyth return h;
39837da2899SCharles.Forsyth }
39937da2899SCharles.Forsyth
40037da2899SCharles.Forsyth Heap*
heap(Type * t)40137da2899SCharles.Forsyth heap(Type *t)
40237da2899SCharles.Forsyth {
40337da2899SCharles.Forsyth Heap *h;
40437da2899SCharles.Forsyth
40537da2899SCharles.Forsyth h = poolalloc(heapmem, sizeof(Heap)+t->size);
40637da2899SCharles.Forsyth if(h == nil)
40737da2899SCharles.Forsyth error(exHeap);
40837da2899SCharles.Forsyth
40937da2899SCharles.Forsyth h->t = t;
41037da2899SCharles.Forsyth t->ref++;
41137da2899SCharles.Forsyth h->ref = 1;
41237da2899SCharles.Forsyth h->color = mutator;
41337da2899SCharles.Forsyth if(t->np)
41437da2899SCharles.Forsyth initmem(t, H2D(void*, h));
41537da2899SCharles.Forsyth if(heapmonitor != nil)
41637da2899SCharles.Forsyth heapmonitor(0, h, t->size);
41737da2899SCharles.Forsyth return h;
41837da2899SCharles.Forsyth }
41937da2899SCharles.Forsyth
42037da2899SCharles.Forsyth Heap*
heaparray(Type * t,int sz)42137da2899SCharles.Forsyth heaparray(Type *t, int sz)
42237da2899SCharles.Forsyth {
42337da2899SCharles.Forsyth Heap *h;
42437da2899SCharles.Forsyth Array *a;
42537da2899SCharles.Forsyth
42637da2899SCharles.Forsyth h = nheap(sizeof(Array) + (t->size*sz));
42737da2899SCharles.Forsyth h->t = &Tarray;
42837da2899SCharles.Forsyth Tarray.ref++;
42937da2899SCharles.Forsyth a = H2D(Array*, h);
43037da2899SCharles.Forsyth a->t = t;
43137da2899SCharles.Forsyth a->len = sz;
43237da2899SCharles.Forsyth a->root = H;
43337da2899SCharles.Forsyth a->data = (uchar*)a + sizeof(Array);
43437da2899SCharles.Forsyth initarray(t, a);
43537da2899SCharles.Forsyth return h;
43637da2899SCharles.Forsyth }
43737da2899SCharles.Forsyth
43837da2899SCharles.Forsyth int
hmsize(void * v)43937da2899SCharles.Forsyth hmsize(void *v)
44037da2899SCharles.Forsyth {
44137da2899SCharles.Forsyth return poolmsize(heapmem, v);
44237da2899SCharles.Forsyth }
44337da2899SCharles.Forsyth
44437da2899SCharles.Forsyth void
initarray(Type * t,Array * a)44537da2899SCharles.Forsyth initarray(Type *t, Array *a)
44637da2899SCharles.Forsyth {
44737da2899SCharles.Forsyth int i;
44837da2899SCharles.Forsyth uchar *p;
44937da2899SCharles.Forsyth
45037da2899SCharles.Forsyth t->ref++;
45137da2899SCharles.Forsyth if(t->np == 0)
45237da2899SCharles.Forsyth return;
45337da2899SCharles.Forsyth
45437da2899SCharles.Forsyth p = a->data;
45537da2899SCharles.Forsyth for(i = 0; i < a->len; i++) {
45637da2899SCharles.Forsyth initmem(t, p);
45737da2899SCharles.Forsyth p += t->size;
45837da2899SCharles.Forsyth }
45937da2899SCharles.Forsyth }
46037da2899SCharles.Forsyth
46137da2899SCharles.Forsyth void*
arraycpy(Array * sa)46237da2899SCharles.Forsyth arraycpy(Array *sa)
46337da2899SCharles.Forsyth {
46437da2899SCharles.Forsyth int i;
46537da2899SCharles.Forsyth Heap *dh;
46637da2899SCharles.Forsyth Array *da;
46737da2899SCharles.Forsyth uchar *elemp;
46837da2899SCharles.Forsyth void **sp, **dp;
46937da2899SCharles.Forsyth
47037da2899SCharles.Forsyth if(sa == H)
47137da2899SCharles.Forsyth return H;
47237da2899SCharles.Forsyth
47337da2899SCharles.Forsyth dh = nheap(sizeof(Array) + sa->t->size*sa->len);
47437da2899SCharles.Forsyth dh->t = &Tarray;
47537da2899SCharles.Forsyth Tarray.ref++;
47637da2899SCharles.Forsyth da = H2D(Array*, dh);
47737da2899SCharles.Forsyth da->t = sa->t;
47837da2899SCharles.Forsyth da->t->ref++;
47937da2899SCharles.Forsyth da->len = sa->len;
48037da2899SCharles.Forsyth da->root = H;
48137da2899SCharles.Forsyth da->data = (uchar*)da + sizeof(Array);
48237da2899SCharles.Forsyth if(da->t == &Tarray) {
48337da2899SCharles.Forsyth dp = (void**)da->data;
48437da2899SCharles.Forsyth sp = (void**)sa->data;
48537da2899SCharles.Forsyth /*
48637da2899SCharles.Forsyth * Maximum depth of this recursion is set by DADEPTH
48737da2899SCharles.Forsyth * in include/isa.h
48837da2899SCharles.Forsyth */
48937da2899SCharles.Forsyth for(i = 0; i < sa->len; i++)
49037da2899SCharles.Forsyth dp[i] = arraycpy(sp[i]);
49137da2899SCharles.Forsyth }
49237da2899SCharles.Forsyth else {
49337da2899SCharles.Forsyth memmove(da->data, sa->data, da->len*sa->t->size);
49437da2899SCharles.Forsyth elemp = da->data;
49537da2899SCharles.Forsyth for(i = 0; i < sa->len; i++) {
49637da2899SCharles.Forsyth incmem(elemp, da->t);
49737da2899SCharles.Forsyth elemp += da->t->size;
49837da2899SCharles.Forsyth }
49937da2899SCharles.Forsyth }
50037da2899SCharles.Forsyth return da;
50137da2899SCharles.Forsyth }
50237da2899SCharles.Forsyth
50337da2899SCharles.Forsyth void
newmp(void * dst,void * src,Type * t)50437da2899SCharles.Forsyth newmp(void *dst, void *src, Type *t)
50537da2899SCharles.Forsyth {
50637da2899SCharles.Forsyth Heap *h;
50737da2899SCharles.Forsyth int c, i, m;
50837da2899SCharles.Forsyth void **uld, *wp, **q;
50937da2899SCharles.Forsyth
51037da2899SCharles.Forsyth memmove(dst, src, t->size);
51137da2899SCharles.Forsyth uld = dst;
51237da2899SCharles.Forsyth for(i = 0; i < t->np; i++) {
51337da2899SCharles.Forsyth c = t->map[i];
51437da2899SCharles.Forsyth if(c != 0) {
51537da2899SCharles.Forsyth m = 0x80;
51637da2899SCharles.Forsyth q = uld;
51737da2899SCharles.Forsyth while(m != 0) {
51837da2899SCharles.Forsyth if((m & c) && (wp = *q) != H) {
51937da2899SCharles.Forsyth h = D2H(wp);
52037da2899SCharles.Forsyth if(h->t == &Tarray)
52137da2899SCharles.Forsyth *q = arraycpy(wp);
52237da2899SCharles.Forsyth else {
52337da2899SCharles.Forsyth h->ref++;
52437da2899SCharles.Forsyth Setmark(h);
52537da2899SCharles.Forsyth }
52637da2899SCharles.Forsyth }
52737da2899SCharles.Forsyth m >>= 1;
52837da2899SCharles.Forsyth q++;
52937da2899SCharles.Forsyth }
53037da2899SCharles.Forsyth }
53137da2899SCharles.Forsyth uld += 8;
53237da2899SCharles.Forsyth }
53337da2899SCharles.Forsyth }
534