3 #include "structdefs.h"
5 #include "SimpleHash.h"
6 #include "GenericHashtable.h"
11 #define INITIALHEAPSIZE 10*1024
12 #define GCPOINT(x) ((int)((x)*0.9))
13 /* This define takes in how full the heap is initially and returns a new heap size to use */
14 #define HEAPSIZE(x,y) (((int)((x)/0.6))+y)
17 extern struct Queue * activetasks;
18 extern struct parameterwrapper * objectqueues[NUMCLASSES];
19 extern struct genhashtable * failedtasks;
20 extern struct RuntimeHash *forward;
21 extern struct RuntimeHash *reverse;
22 extern struct RuntimeHash *fdtoobject;
27 struct pointerblock *next;
30 struct pointerblock *head=NULL;
32 struct pointerblock *tail=NULL;
34 struct pointerblock *spare=NULL;
37 void enqueue(void *ptr) {
38 if (headindex==NUMPTRS) {
39 struct pointerblock * tmp;
44 tmp=malloc(sizeof(struct pointerblock));
49 head->ptrs[headindex++]=ptr;
53 if (tailindex==NUMPTRS) {
54 struct pointerblock *tmp=tail;
62 return tail->ptrs[tailindex++];
66 if ((head==tail)&&(tailindex==headindex))
71 void collect(struct garbagelist * stackptr) {
75 head=tail=malloc(sizeof(struct pointerblock));
77 /* Check current stack */
78 while(stackptr!=NULL) {
80 for(i=0;i<stackptr->size;i++) {
81 void * orig=stackptr->array[i];
83 if (gc_createcopy(orig,©))
85 stackptr->array[i]=copy;
87 stackptr=stackptr->next;
92 /* Update objectsets */
94 for(i=0;i<NUMCLASSES;i++) {
95 struct parameterwrapper * p=objectqueues[i];
97 struct RuntimeHash * set=p->objectset;
98 struct RuntimeNode * ptr=set->listhead;
100 void *orig=(void *)ptr->key;
102 if (gc_createcopy(orig, ©))
108 RuntimeHashrehash(set); /* Rehash the table */
115 struct RuntimeNode * ptr=forward->listhead;
117 void * orig=(void *)ptr->key;
119 if (gc_createcopy(orig, ©))
125 RuntimeHashrehash(forward); /* Rehash the table */
129 struct RuntimeNode * ptr=reverse->listhead;
131 void *orig=(void *)ptr->data;
133 if (gc_createcopy(orig, ©))
142 struct RuntimeNode * ptr=fdtoobject->listhead;
144 void *orig=(void *)ptr->data;
146 if (gc_createcopy(orig, ©))
156 /* Update active tasks */
157 struct QueueItem * ptr=activetasks->head;
159 struct taskparamdescriptor *tpd=ptr->objectptr;
161 for(i=0;i<tpd->numParameters;i++) {
162 void *orig=tpd->parameterArray[i];
164 if (gc_createcopy(orig, ©))
166 tpd->parameterArray[i]=copy;
171 /* Update failed tasks */
173 struct genpointerlist * ptr=failedtasks->list;
177 if (gc_createcopy(orig, ©))
183 genrehash(failedtasks);
188 void * ptr=dequeue();
189 void *cpy=((void **)ptr)[1];
190 int type=((int *)cpy)[0];
191 int * pointer=pointerarray[type];
193 /* Array of primitives */
195 } else if (((int)pointer)==1) {
196 /* Array of pointers */
197 struct ArrayObject *ao=(struct ArrayObject *) ptr;
198 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
199 int length=ao->___length___;
201 for(i=0;i<length;i++) {
202 void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
204 if (gc_createcopy(objptr, ©))
206 ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
211 for(i=1;i<=size;i++) {
212 int offset=pointer[i];
213 void * objptr=*((void **)(((int)ptr)+offset));
215 if (gc_createcopy(objptr, ©))
217 *((void **) (((int)cpy)+offset))=copy;
223 void * curr_heapbase=0;
224 void * curr_heapptr=0;
225 void * curr_heapgcpoint=0;
226 void * curr_heaptop=0;
228 void * to_heapbase=0;
233 void * tomalloc(int size) {
234 void * ptr=to_heapptr;
241 void * mygcmalloc(struct garbagelist * stackptr, int size) {
242 void *ptr=curr_heapptr;
246 if (curr_heapptr>curr_heapgcpoint) {
247 if (curr_heapbase==0) {
248 /* Need to allocate base heap */
249 curr_heapbase=malloc(INITIALHEAPSIZE);
250 bzero(curr_heapbase, INITIALHEAPSIZE);
251 curr_heaptop=curr_heapbase+INITIALHEAPSIZE;
252 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(INITIALHEAPSIZE);
253 curr_heapptr=curr_heapbase+size;
255 to_heapbase=malloc(INITIALHEAPSIZE);
256 to_heaptop=to_heapbase+INITIALHEAPSIZE;
257 to_heapptr=to_heapbase;
258 return curr_heapbase;
261 /* Grow the to heap if necessary */
263 int curr_heapsize=curr_heaptop-curr_heapbase;
264 int to_heapsize=to_heaptop-to_heapbase;
267 last_heapsize=HEAPSIZE(lastgcsize, size);
268 if ((last_heapsize%4)!=0)
269 last_heapsize+=(4-(last_heapsize%4));
271 if (curr_heapsize>last_heapsize)
272 last_heapsize=curr_heapsize;
273 if (last_heapsize>to_heapsize) {
275 to_heapbase=malloc(last_heapsize);
276 to_heaptop=to_heapbase+last_heapsize;
277 to_heapptr=to_heapbase;
281 /* Do our collection */
284 /* Update stat on previous gc size */
285 lastgcsize=(to_heapptr-to_heapbase)+size;
287 /* Flip to/curr heaps */
289 void * tmp=to_heapbase;
290 to_heapbase=curr_heapbase;
294 to_heaptop=curr_heaptop;
298 curr_heapptr=to_heapptr+size;
299 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
300 to_heapptr=to_heapbase;
302 /* Not enough room :(, redo gc */
303 if (curr_heapptr>curr_heapgcpoint)
304 return mygcmalloc(stackptr, size);
306 bzero(tmp, curr_heaptop-tmp);
314 int gc_createcopy(void * orig, void ** copy_ptr) {
319 int type=((int *)orig)[0];
321 *copy_ptr=((void **)orig)[1];
323 } if (type<NUMCLASSES) {
324 /* We have a normal object */
325 int size=classsize[type];
326 void *newobj=tomalloc(size);
327 memcpy(newobj, orig, size);
329 ((void **)orig)[1]=newobj;
333 /* We have an array */
334 struct ArrayObject *ao=(struct ArrayObject *)orig;
335 int elementsize=classsize[type];
336 int length=ao->___length___;
337 int size=sizeof(struct ArrayObject)+length*elementsize;
338 void *newobj=tomalloc(size);
339 memcpy(newobj, orig, size);
341 ((void **)orig)[1]=newobj;