gc.c (3337B)
1 /* 15nov07abu 2 * (c) Software Lab. Alexander Burger 3 */ 4 5 #include "pico.h" 6 7 /* Mark data */ 8 static void mark(any x) { 9 while (isCell(x)) { 10 if (!(num(cdr(x)) & 1)) 11 return; 12 *(long*)&cdr(x) &= ~1; 13 mark(car(x)), x = cdr(x); 14 } 15 if (!isNum(x) && num(val(x)) & 1) { 16 *(long*)&val(x) &= ~1; 17 mark(val(x)), x = tail(x); 18 while (isCell(x)) { 19 if (!(num(cdr(x)) & 1)) 20 return; 21 *(long*)&cdr(x) &= ~1; 22 mark(cdr(x)), x = car(x); 23 } 24 if (!isTxt(x)) 25 do { 26 if (!(num(val(x)) & 1)) 27 return; 28 *(long*)&val(x) &= ~1; 29 } while (!isNum(x = val(x))); 30 } 31 } 32 33 /* Garbage collector */ 34 static void gc(long c) { 35 any p; 36 heap *h; 37 int i; 38 39 h = Heaps; 40 do { 41 p = h->cells + CELLS-1; 42 do 43 *(long*)&cdr(p) |= 1; 44 while (--p >= h->cells); 45 } while (h = h->next); 46 /* Mark */ 47 mark(Nil+1); 48 mark(Intern[0]), mark(Intern[1]); 49 mark(Transient[0]), mark(Transient[1]); 50 mark(ApplyArgs), mark(ApplyBody); 51 mark(Reloc); 52 for (p = Env.stack; p; p = cdr(p)) 53 mark(car(p)); 54 for (p = (any)Env.bind; p; p = (any)((bindFrame*)p)->link) 55 for (i = ((bindFrame*)p)->cnt; --i >= 0;) { 56 mark(((bindFrame*)p)->bnd[i].sym); 57 mark(((bindFrame*)p)->bnd[i].val); 58 } 59 for (p = (any)CatchPtr; p; p = (any)((catchFrame*)p)->link) 60 mark(((catchFrame*)p)->tag); 61 for (p = (any)Env.meth; p; p = (any)((methFrame*)p)->link) 62 mark(((methFrame*)p)->key), mark(((methFrame*)p)->cls); 63 if (Env.make) 64 mark(car(Env.make)); 65 if (Env.parser) 66 mark(Env.parser->sym); 67 /* Sweep */ 68 Avail = NULL; 69 h = Heaps; 70 if (c) { 71 do { 72 p = h->cells + CELLS-1; 73 do 74 if (num(p->cdr) & 1) 75 Free(p), --c; 76 while (--p >= h->cells); 77 } while (h = h->next); 78 while (c >= 0) 79 heapAlloc(), c -= CELLS; 80 } 81 else { 82 heap **hp = &Heaps; 83 cell *av; 84 85 do { 86 c = CELLS; 87 av = Avail; 88 p = h->cells + CELLS-1; 89 do 90 if (num(p->cdr) & 1) 91 Free(p), --c; 92 while (--p >= h->cells); 93 if (c) 94 hp = &h->next, h = h->next; 95 else 96 Avail = av, h = h->next, free(*hp), *hp = h; 97 } while (h); 98 } 99 } 100 101 // (gc ['num]) -> num | NIL 102 any doGc(any x) { 103 x = cdr(x); 104 gc(isNum(x = EVAL(car(x)))? CELLS*unBox(x) : CELLS); 105 return x; 106 } 107 108 /* Construct a cell */ 109 any cons(any x, any y) { 110 cell *p; 111 112 if (!(p = Avail)) { 113 cell c1, c2; 114 115 Push(c1,x); 116 Push(c2,y); 117 gc(CELLS); 118 drop(c1); 119 p = Avail; 120 } 121 Avail = p->car; 122 p->car = x; 123 p->cdr = y; 124 return p; 125 } 126 127 /* Construct a symbol */ 128 any consSym(any val, word w) { 129 cell *p; 130 131 if (!(p = Avail)) { 132 cell c1; 133 134 if (!val) 135 gc(CELLS); 136 else { 137 Push(c1,val); 138 gc(CELLS); 139 drop(c1); 140 } 141 p = Avail; 142 } 143 Avail = p->car; 144 p = symPtr(p); 145 val(p) = val ?: p; 146 tail(p) = txt(w); 147 return p; 148 } 149 150 /* Construct a name cell */ 151 any consName(word w, any n) { 152 cell *p; 153 154 if (!(p = Avail)) { 155 gc(CELLS); 156 p = Avail; 157 } 158 Avail = p->car; 159 p = symPtr(p); 160 val(p) = n; 161 tail(p) = (any)w; 162 return p; 163 }