3 #include "structdefs.h"
5 #include "SimpleHash.h"
7 #include "GenericHashtable.h"
9 #if defined(THREADS) || defined(DSTM) || defined(STM)
13 #include "workschedule.h"
14 extern struct QI * headqi;
15 extern struct QI * tailqi;
23 #include <DSTM/interface_recovery/dstm.h>
25 #include <DSTM/interface/dstm.h>
32 #include "delaycomp.h"
38 #define INITIALHEAPSIZE 256*1024*1024L
39 #define GCPOINT(x) ((INTPTR)((x)*0.99))
40 /* This define takes in how full the heap is initially and returns a new heap size to use */
41 #define HEAPSIZE(x,y) ((INTPTR)(x+y))*2
44 extern struct genhashtable * activetasks;
46 extern struct parameterwrapper * objectqueues[NUMCLASSES];
48 extern struct genhashtable * failedtasks;
49 extern struct taskparamdescriptor *currtpd;
50 extern struct ctable *forward;
51 extern struct ctable *reverse;
52 extern struct RuntimeHash *fdtoobject;
57 long garbagearray[MAXSTATS];
60 #if defined(THREADS) || defined(DSTM) || defined(STM)||defined(MLP)
62 struct listitem * list=NULL;
65 __thread struct listitem litem;
70 __thread SESEcommon* seseCommon;
73 //Need to check if pointers are transaction pointers
74 //this also catches the special flag value of 1 for local copies
76 #define ENQUEUE(orig, dst) \
77 if ((!(((unsigned int)orig)&0x1))) { \
78 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
80 if (gc_createcopy(orig,©)) \
86 #define ENQUEUE(orig, dst) \
87 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
89 if (gc_createcopy(orig,©)) \
93 #define SENQUEUE(orig, dst) \
96 if (gc_createcopy(orig,©)) \
100 #elif defined(FASTCHECK)
101 #define ENQUEUE(orig, dst) \
102 if (((unsigned int)orig)!=1) { \
104 if (gc_createcopy(orig,©)) \
108 #define ENQUEUE(orig, dst) \
109 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
111 if (gc_createcopy(orig,©)) \
118 struct pointerblock {
119 void * ptrs[NUMPTRS];
120 struct pointerblock *next;
123 void * curr_heapbase=0;
124 void * curr_heapptr=0;
125 void * curr_heapgcpoint=0;
126 void * curr_heaptop=0;
128 void * to_heapbase=0;
134 struct pointerblock *head=NULL;
136 struct pointerblock *tail=NULL;
138 struct pointerblock *spare=NULL;
140 void enqueue(void *ptr) {
141 if (headindex==NUMPTRS) {
142 struct pointerblock * tmp;
146 } else tmp=malloc(sizeof(struct pointerblock));
151 head->ptrs[headindex++]=ptr;
155 if (tailindex==NUMPTRS) {
156 struct pointerblock *tmp=tail;
164 return tail->ptrs[tailindex++];
168 void fixobjlist(struct objlist * ptr) {
171 for(i=0;i<ptr->offset;i++) {
172 SENQUEUE(ptr->objs[i], ptr->objs[i]);
178 void fixtable(chashlistnode_t ** tc_table, chashlistnode_t **tc_list, cliststruct_t **cstr, unsigned int tc_size) {
179 unsigned int mask=(tc_size<<4)-1;
180 chashlistnode_t *node=calloc(tc_size, sizeof(chashlistnode_t));
181 chashlistnode_t *ptr=*tc_table;
182 chashlistnode_t *curr;
186 chashlistnode_t *newlist=NULL;
187 for(i=0;i<tc_size;i++) {
190 do { //Inner loop to go through linked lists
192 chashlistnode_t *tmp,*next;
194 if ((key=(void *)curr->key) == 0) { //Exit inner loop if there the first element is 0
195 break; //key = val =0 for element if not present within the hash table
198 if (curr->val>=curr_heapbase&&curr->val<curr_heaptop) {
199 SENQUEUE(curr->val, curr->val);
201 //rewrite transaction cache entry
202 void *vptr=curr->val;
203 int type=((int *)vptr)[0];
204 unsigned INTPTR *pointer=pointerarray[type];
206 //array of primitives - do nothing
207 struct ArrayObject *ao=(struct ArrayObject *) vptr;
208 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao->___objlocation___));
209 } else if (((INTPTR)pointer)==1) {
211 struct ArrayObject *ao=(struct ArrayObject *) vptr;
212 int length=ao->___length___;
214 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao->___objlocation___));
216 int lowindex=ao->lowindex;
217 int highindex=ao->highindex;
219 for(j=lowindex; j<=highindex; j++) {
220 unsigned int lockval;
221 GETLOCKVAL(lockval, ao, j);
222 if (lockval!=STMNONE) {
223 int lowi=(j<<INDEXSHIFT)/sizeof(void *);
224 int highi=lowi+(INDEXLENGTH/sizeof(void *));
225 for(i=lowi; i<highi;i++) {
227 for(i=0; i<length; i++) {
229 void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
230 SENQUEUE(objptr, ((void **)(((char *)&ao->___length___)+sizeof(int)))[i]);
237 INTPTR size=pointer[0];
239 for(i=1; i<=size; i++) {
240 unsigned int offset=pointer[i];
241 void * objptr=*((void **)(((char *)vptr)+offset));
242 SENQUEUE(objptr, *((void **)(((char *)vptr)+offset)));
248 index = (((unsigned INTPTR)key) & mask) >>4;
252 // Insert into the new table
254 tmp->key = curr->key;
255 tmp->val = curr->val;
258 } else if (isfirst) {
259 chashlistnode_t *newnode;
260 if ((*cstr)->num<NUMCLIST) {
261 newnode=&(*cstr)->array[(*cstr)->num];
265 cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
268 newnode=&tcl->array[0];
271 newnode->key = curr->key;
272 newnode->val = curr->val;
273 newnode->next = tmp->next;
274 newnode->lnext=newlist;
280 curr->next=tmp->next;
294 if ((head==tail)&&(tailindex==headindex))
300 struct pointerblock *taghead=NULL;
303 void enqueuetag(struct ___TagDescriptor___ *ptr) {
304 if (tagindex==NUMPTRS) {
305 struct pointerblock * tmp=malloc(sizeof(struct pointerblock));
310 taghead->ptrs[tagindex++]=ptr;
314 #if defined(STM)||defined(THREADS)||defined(MLP)
315 __thread char * memorybase=NULL;
316 __thread char * memorytop=NULL;
320 void collect(struct garbagelist * stackptr) {
321 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
323 pthread_mutex_lock(&gclistlock);
325 if ((listcount+1)==threadcount) {
326 break; /* Have all other threads stopped */
328 pthread_cond_wait(&gccond, &gclistlock);
332 ptrstack.prev=stackptr;
333 stackptr=(struct garbagelist *) &ptrstack;
334 #if defined(STMARRAY)&&!defined(DUALVIEW)
335 arraystack.prev=stackptr;
336 stackptr=(struct garbagelist *) &arraystack;
343 for(i=0;i<MAXSTATS;i++)
351 head=tail=malloc(sizeof(struct pointerblock));
357 taghead=malloc(sizeof(struct pointerblock));
364 fixtable(&c_table, &c_list, &c_structs, c_size);
367 fixobjlist(lockedobjs);
371 #if defined(STM)||defined(THREADS)||defined(MLP)
375 /* Check current stack */
376 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
378 struct listitem *listptr=list;
382 while(stackptr!=NULL) {
384 for(i=0; i<stackptr->size; i++) {
385 void * orig=stackptr->array[i];
386 ENQUEUE(orig, stackptr->array[i]);
388 stackptr=stackptr->next;
390 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
391 /* Go to next thread */
394 if (listptr==&litem) {
396 // update forward list & memory queue for the current SESE
397 updateForwardList(((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
398 updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
400 listptr=listptr->next;
404 struct listitem *litem=pthread_getspecific(litemkey);
405 if (listptr==litem) {
406 listptr=listptr->next;
413 void * orig=listptr->locklist;
414 ENQUEUE(orig, listptr->locklist);
417 if ((*listptr->tc_table)!=NULL) {
418 fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_structs, listptr->tc_size);
419 fixobjlist(listptr->objlist);
421 fixobjlist(listptr->lockedlist);
425 #if defined(STM)||defined(THREADS)||defined(MLP)
426 *(listptr->base)=NULL;
429 // update forward list & memory queue for all running SESEs.
430 updateForwardList(((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
431 updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
433 stackptr=listptr->stackptr;
434 listptr=listptr->next;
442 ENQUEUE(___fcrevert___, ___fcrevert___);
447 /* Update objectsets */
449 for(i=0; i<NUMCLASSES; i++) {
450 #if !defined(MULTICORE)
451 struct parameterwrapper * p=objectqueues[i];
453 struct ObjectHash * set=p->objectset;
454 struct ObjectNode * ptr=set->listhead;
456 void *orig=(void *)ptr->key;
457 ENQUEUE(orig, *((void **)(&ptr->key)));
460 ObjectHashrehash(set); /* Rehash the table */
469 struct cnode * ptr=forward->listhead;
471 void * orig=(void *)ptr->key;
472 ENQUEUE(orig, *((void **)(&ptr->key)));
475 crehash(forward); /* Rehash the table */
479 struct cnode * ptr=reverse->listhead;
481 void *orig=(void *)ptr->val;
482 ENQUEUE(orig, *((void**)(&ptr->val)));
489 struct RuntimeNode * ptr=fdtoobject->listhead;
491 void *orig=(void *)ptr->data;
492 ENQUEUE(orig, *((void**)(&ptr->data)));
498 /* Update current task descriptor */
500 for(i=0; i<currtpd->numParameters; i++) {
501 void *orig=currtpd->parameterArray[i];
502 ENQUEUE(orig, currtpd->parameterArray[i]);
507 /* Update active tasks */
509 struct genpointerlist * ptr=activetasks->list;
511 struct taskparamdescriptor *tpd=ptr->src;
513 for(i=0; i<tpd->numParameters; i++) {
514 void * orig=tpd->parameterArray[i];
515 ENQUEUE(orig, tpd->parameterArray[i]);
519 genrehash(activetasks);
522 /* Update failed tasks */
524 struct genpointerlist * ptr=failedtasks->list;
526 struct taskparamdescriptor *tpd=ptr->src;
528 for(i=0; i<tpd->numParameters; i++) {
529 void * orig=tpd->parameterArray[i];
530 ENQUEUE(orig, tpd->parameterArray[i]);
534 genrehash(failedtasks);
540 // goes over ready-to-run SESEs
541 struct QI * qitem = headqi;
543 SESEcommon* common=(SESEcommon*)qitem->value;
544 if(common==seseCommon){
545 // skip the current running SESE
549 SESEcommon* seseRec = (SESEcommon*)(qitem->value);
550 struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]);
551 struct garbagelist * glroot=gl;
552 // update its ascendant SESEs
553 updateAscendantSESE(seseRec);
557 for(i=0; i<gl->size; i++) {
558 void * orig=gl->array[i];
559 ENQUEUE(orig, gl->array[i]);
570 void * ptr=dequeue();
572 int type=((int *)cpy)[0];
573 unsigned INTPTR * pointer;
577 /* Nothing is inside */
582 pointer=pointerarray[type];
584 /* Array of primitives */
586 #if defined(DSTM)||defined(FASTCHECK)
587 struct ArrayObject *ao=(struct ArrayObject *) ptr;
588 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
589 ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
590 ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
593 struct ArrayObject *ao=(struct ArrayObject *) ptr;
594 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
595 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao_cpy->___objlocation___));
597 } else if (((INTPTR)pointer)==1) {
598 /* Array of pointers */
599 struct ArrayObject *ao=(struct ArrayObject *) ptr;
600 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
601 #if (defined(DSTM)||defined(FASTCHECK))
602 ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
603 ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
606 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao_cpy->___objlocation___));
608 int length=ao->___length___;
610 for(i=0; i<length; i++) {
611 void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
612 ENQUEUE(objptr, ((void **)(((char *)&ao_cpy->___length___)+sizeof(int)))[i]);
615 INTPTR size=pointer[0];
617 for(i=1; i<=size; i++) {
618 unsigned int offset=pointer[i];
619 void * objptr=*((void **)(((char *)ptr)+offset));
620 ENQUEUE(objptr, *((void **)(((char *)cpy)+offset)));
630 //rehash memory queues of current running SESEs
631 struct listitem *listptr=list;
632 while(listptr!=NULL){
633 rehashMemoryQueue((SESEcommon*)(listptr->seseCommon));
634 listptr=listptr->next;
639 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
641 pthread_mutex_unlock(&gclistlock);
646 /* Fix up the references from tags. This can't be done earlier,
647 because we don't want tags to keep objects alive */
649 while(taghead!=NULL) {
651 struct pointerblock *tmp=taghead->next;
652 for(i=0; i<tagindex; i++) {
653 struct ___TagDescriptor___ *tagd=taghead->ptrs[i];
654 struct ___Object___ *obj=tagd->flagptr;
655 struct ___TagDescriptor___ *copy=((struct ___TagDescriptor___**)tagd)[1];
657 /* Zero object case */
658 } else if (obj->type==-1) {
659 /* Single object case */
660 copy->flagptr=((struct ___Object___**)obj)[1];
661 } else if (obj->type==OBJECTARRAYTYPE) {
663 struct ArrayObject *ao=(struct ArrayObject *) obj;
667 struct ArrayObject *aonew;
669 /* Count live objects */
670 for(j=0; j<ao->___cachedCode___; j++) {
671 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
676 livecount=((livecount-1)/OBJECTARRAYINTERVAL+1)*OBJECTARRAYINTERVAL;
677 aonew=(struct ArrayObject *) tomalloc(sizeof(struct ArrayObject)+sizeof(struct ___Object___*)*livecount);
678 memcpy(aonew, ao, sizeof(struct ArrayObject));
679 aonew->type=OBJECTARRAYTYPE;
680 aonew->___length___=livecount;
682 for(j=0; j<ao->___cachedCode___; j++) {
683 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
684 if (tobj->type==-1) {
685 struct ___Object___ * tobjcpy=((struct ___Object___**)tobj)[1];
686 ARRAYSET(aonew, struct ___Object___*, k++,tobjcpy);
689 aonew->___cachedCode___=k;
690 for(; k<livecount; k++) {
691 ARRAYSET(aonew, struct ___Object___*, k, NULL);
694 /* No object live anymore */
705 void * tomalloc(int size) {
706 void * ptr=to_heapptr;
713 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
714 void checkcollect(void * ptr) {
715 stopforgc((struct garbagelist *)ptr);
720 void checkcollect2(void * ptr) {
721 int ptrarray[]={1, (int)ptr, (int) revertlist};
722 stopforgc((struct garbagelist *)ptrarray);
724 revertlist=(struct ___Object___*)ptrarray[2];
728 void stopforgc(struct garbagelist * ptr) {
730 //just append us to the list
732 ptr=(struct garbagelist *) &ptrstack;
733 #if defined(STMARRAY)&&!defined(DUALVIEW)
735 ptr=(struct garbagelist *) &arraystack;
741 litem.locklist=pthread_getspecific(threadlocks);
743 #if defined(STM)||defined(THREADS)||defined(MLP)
744 litem.base=&memorybase;
747 litem.tc_size=c_size;
748 litem.tc_table=&c_table;
749 litem.tc_list=&c_list;
750 litem.tc_structs=&c_structs;
751 litem.objlist=newobjs;
753 litem.lockedlist=lockedobjs;
758 struct listitem *litem=pthread_getspecific(litemkey);
761 litem->locklist=pthread_getspecific(threadlocks);
764 pthread_mutex_lock(&gclistlock);
766 if ((listcount+1)==threadcount) {
767 //only do wakeup if we are ready to GC
768 pthread_cond_signal(&gccond);
770 pthread_mutex_unlock(&gclistlock);
773 void restartaftergc() {
775 pthread_mutex_lock(&gclock); // Wait for GC
776 pthread_mutex_unlock(&gclock);
778 pthread_mutex_lock(&gclistlock);
780 pthread_mutex_unlock(&gclistlock);
784 #if defined(STM)||defined(THREADS)||defined(MLP)
785 #define MEMORYBLOCK 65536
786 void * helper(struct garbagelist *, int);
787 void * mygcmalloc(struct garbagelist * stackptr, int size) {
790 if (memorybase==NULL||size>(memorytop-memorybase)) {
791 int toallocate=(size>MEMORYBLOCK)?size:MEMORYBLOCK;
792 memorybase=helper(stackptr, toallocate);
793 bzero(memorybase, toallocate);
794 memorytop=memorybase+toallocate;
796 char *retvalue=memorybase;
801 void * helper(struct garbagelist * stackptr, int size) {
803 void * mygcmalloc(struct garbagelist * stackptr, int size) {
806 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
807 while (pthread_mutex_trylock(&gclock)!=0) {
816 if (curr_heapptr>curr_heapgcpoint||curr_heapptr<curr_heapbase) {
817 if (curr_heapbase==0) {
818 /* Need to allocate base heap */
819 curr_heapbase=malloc(INITIALHEAPSIZE);
820 if (curr_heapbase==NULL) {
821 printf("malloc failed. Garbage colletcor couldn't get enough memory. Try changing heap size.\n");
824 #if defined(STM)||defined(THREADS)||defined(MLP)
826 bzero(curr_heapbase, INITIALHEAPSIZE);
828 curr_heaptop=curr_heapbase+INITIALHEAPSIZE;
829 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(INITIALHEAPSIZE);
830 curr_heapptr=curr_heapbase+size;
832 to_heapbase=malloc(INITIALHEAPSIZE);
833 if (to_heapbase==NULL) {
834 printf("malloc failed. Garbage collector couldn't get enough memory. Try changing heap size.\n");
838 to_heaptop=to_heapbase+INITIALHEAPSIZE;
839 to_heapptr=to_heapbase;
841 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
842 pthread_mutex_unlock(&gclock);
847 /* Grow the to heap if necessary */
849 INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
850 INTPTR to_heapsize=to_heaptop-to_heapbase;
851 INTPTR last_heapsize=0;
853 last_heapsize=HEAPSIZE(lastgcsize, size);
854 if ((last_heapsize&7)!=0)
855 last_heapsize+=(8-(last_heapsize%8));
857 if (curr_heapsize>last_heapsize)
858 last_heapsize=curr_heapsize;
859 if (last_heapsize>to_heapsize) {
861 to_heapbase=malloc(last_heapsize);
862 if (to_heapbase==NULL) {
863 printf("Error Allocating enough memory\n");
866 to_heaptop=to_heapbase+last_heapsize;
867 to_heapptr=to_heapbase;
871 /* Do our collection */
874 /* Update stat on previous gc size */
875 lastgcsize=(to_heapptr-to_heapbase)+size;
878 printf("Garbage collected: Old bytes: %u\n", curr_heapptr-curr_heapbase);
879 printf("New space: %u\n", to_heapptr-to_heapbase);
880 printf("Total space: %u\n", to_heaptop-to_heapbase);
883 for(i=0;i<MAXSTATS;i++) {
884 if (garbagearray[i]!=0)
885 printf("Type=%d Size=%u\n", i, garbagearray[i]);
889 /* Flip to/curr heaps */
891 void * tmp=to_heapbase;
892 to_heapbase=curr_heapbase;
896 to_heaptop=curr_heaptop;
900 curr_heapptr=to_heapptr+size;
901 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
902 to_heapptr=to_heapbase;
904 /* Not enough room :(, redo gc */
905 if (curr_heapptr>curr_heapgcpoint) {
906 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
907 pthread_mutex_unlock(&gclock);
909 return mygcmalloc(stackptr, size);
912 bzero(tmp, curr_heaptop-tmp);
913 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
914 pthread_mutex_unlock(&gclock);
919 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
920 pthread_mutex_unlock(&gclock);
926 int gc_createcopy(void * orig, void ** copy_ptr) {
931 int type=((int *)orig)[0];
933 *copy_ptr=((void **)orig)[1];
936 if (type<NUMCLASSES) {
937 /* We have a normal object */
939 int size=classsize[type]+sizeof(objheader_t);
940 void *newobj=tomalloc(size);
941 memcpy(newobj,((char *) orig)-sizeof(objheader_t), size);
942 newobj=((char *)newobj)+sizeof(objheader_t);
944 int size=classsize[type];
945 void *newobj=tomalloc(size);
946 memcpy(newobj, orig, size);
949 garbagearray[type]+=size;
952 ((void **)orig)[1]=newobj;
956 /* We have an array */
957 struct ArrayObject *ao=(struct ArrayObject *)orig;
958 int elementsize=classsize[type];
959 int length=ao->___length___;
962 int basesize=length*elementsize;
963 basesize=(basesize+LOWMASK)&HIGHMASK;
964 int versionspace=sizeof(int)*2*(basesize>>INDEXSHIFT);
965 int size=sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+versionspace;
966 void *newobj=tomalloc(size);
967 memcpy(newobj, ((char*)orig)-sizeof(objheader_t)-versionspace, size);
968 newobj=((char *)newobj)+sizeof(objheader_t)+versionspace;
970 int size=sizeof(struct ArrayObject)+length*elementsize+sizeof(objheader_t);
971 void *newobj=tomalloc(size);
972 memcpy(newobj, ((char*)orig)-sizeof(objheader_t), size);
973 newobj=((char *)newobj)+sizeof(objheader_t);
976 int size=sizeof(struct ArrayObject)+length*elementsize;
977 void *newobj=tomalloc(size);
978 memcpy(newobj, orig, size);
981 garbagearray[type]+=size;
984 ((void **)orig)[1]=newobj;
992 updateForwardList(struct Queue *forwardList, int prevUpdate){
994 struct QueueItem * fqItem=getHead(forwardList);
996 SESEcommon* seseRec = (SESEcommon*)(fqItem->objectptr);
997 struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]);
998 if(prevUpdate==TRUE){
999 updateAscendantSESE(seseRec);
1001 // do something here
1004 for(i=0; i<gl->size; i++) {
1005 void * orig=gl->array[i];
1006 ENQUEUE(orig, gl->array[i]);
1010 // iterate forwarding list of seseRec
1011 struct Queue* fList=seseRec->forwardList;
1012 updateForwardList(fList,prevUpdate);
1013 fqItem=getNextQueueItem(fqItem);
1018 updateMemoryQueue(SESEcommon_p seseParent){
1019 // update memory queue
1021 for(i=0; i<seseParent->numMemoryQueue; i++){
1022 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
1023 MemoryQueueItem *memoryItem=memoryQueue->head;
1024 while(memoryItem!=NULL){
1025 if(memoryItem->type==HASHTABLE){
1026 Hashtable *ht=(Hashtable*)memoryItem;
1027 for(binidx=0; binidx<NUMBINS; binidx++){
1028 BinElement *bin=ht->array[binidx];
1029 BinItem *binItem=bin->head;
1030 while(binItem!=NULL){
1031 if(binItem->type==READBIN){
1032 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1034 for(ridx=0; ridx<readBinItem->index; ridx++){
1035 REntry *rentry=readBinItem->array[ridx];
1036 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1037 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1038 updateAscendantSESE(seseRec);
1041 for(i=0; i<gl->size; i++) {
1042 void * orig=gl->array[i];
1043 ENQUEUE(orig, gl->array[i]);
1049 REntry *rentry=((WriteBinItem*)binItem)->val;
1050 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1051 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1052 updateAscendantSESE(seseRec);
1055 for(i=0; i<gl->size; i++) {
1056 void * orig=gl->array[i];
1057 ENQUEUE(orig, gl->array[i]);
1062 binItem=binItem->next;
1065 }else if(memoryItem->type==VECTOR){
1066 Vector *vt=(Vector*)memoryItem;
1068 for(idx=0; idx<vt->index; idx++){
1069 REntry *rentry=vt->array[idx];
1071 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1072 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1073 updateAscendantSESE(seseRec);
1076 for(i=0; i<gl->size; i++) {
1077 void * orig=gl->array[i];
1078 ENQUEUE(orig, gl->array[i]);
1084 }else if(memoryItem->type==SINGLEITEM){
1085 SCC *scc=(SCC*)memoryItem;
1086 REntry *rentry=scc->val;
1088 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1089 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1090 updateAscendantSESE(seseRec);
1093 for(i=0; i<gl->size; i++) {
1094 void * orig=gl->array[i];
1095 ENQUEUE(orig, gl->array[i]);
1101 memoryItem=memoryItem->next;
1106 updateAscendantSESE(SESEcommon* seseRec){
1108 for(prevIdx=0; prevIdx<(seseRec->numDependentSESErecords); prevIdx++){
1109 SESEcommon* prevSESE = (SESEcommon*)
1112 seseRec->offsetToDepSESErecords +
1113 (sizeof(INTPTR)*prevIdx)
1117 struct garbagelist * prevgl=(struct garbagelist *)&(((SESEcommon*)(prevSESE))[1]);
1118 while(prevgl!=NULL) {
1120 for(i=0; i<prevgl->size; i++) {
1121 void * orig=prevgl->array[i];
1122 ENQUEUE(orig, prevgl->array[i]);
1124 prevgl=prevgl->next;
1132 int within(void *ptr){ //debug function
1133 if(ptr>curr_heapptr || ptr<curr_heapbase){
1134 __asm__ __volatile__ ("int $3"); // breakpoint