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 #ifndef INITIALHEAPSIZE_MB
39 #define INITIALHEAPSIZE_MB (256)
42 #define INITIALHEAPSIZE INITIALHEAPSIZE_MB*1024*1024L
43 #define GCPOINT(x) ((INTPTR)((x)*0.99))
44 /* This define takes in how full the heap is initially and returns a new heap size to use */
45 #define HEAPSIZE(x,y) ((INTPTR)(x+y))*2
48 extern struct genhashtable * activetasks;
50 extern struct parameterwrapper * objectqueues[NUMCLASSES];
52 extern struct genhashtable * failedtasks;
53 extern struct taskparamdescriptor *currtpd;
54 extern struct ctable *forward;
55 extern struct ctable *reverse;
56 extern struct RuntimeHash *fdtoobject;
61 long garbagearray[MAXSTATS];
64 #if defined(THREADS) || defined(DSTM) || defined(STM)||defined(MLP)
66 struct listitem * list=NULL;
69 __thread struct listitem litem;
74 __thread SESEcommon* seseCommon;
77 //Need to check if pointers are transaction pointers
78 //this also catches the special flag value of 1 for local copies
80 #define ENQUEUE(orig, dst) \
81 if ((!(((unsigned int)orig)&0x1))) { \
82 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
84 if (gc_createcopy(orig,©)) \
90 #define ENQUEUE(orig, dst) \
91 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
93 if (gc_createcopy(orig,©)) \
97 #define SENQUEUE(orig, dst) \
100 if (gc_createcopy(orig,©)) \
104 #elif defined(FASTCHECK)
105 #define ENQUEUE(orig, dst) \
106 if (((unsigned int)orig)!=1) { \
108 if (gc_createcopy(orig,©)) \
112 #define ENQUEUE(orig, dst) \
113 if (orig>=curr_heapbase&&orig<curr_heaptop) { \
115 if (gc_createcopy(orig,©)) \
122 struct pointerblock {
123 void * ptrs[NUMPTRS];
124 struct pointerblock *next;
127 void * curr_heapbase=0;
128 void * curr_heapptr=0;
129 void * curr_heapgcpoint=0;
130 void * curr_heaptop=0;
132 void * to_heapbase=0;
138 struct pointerblock *head=NULL;
140 struct pointerblock *tail=NULL;
142 struct pointerblock *spare=NULL;
144 void enqueue(void *ptr) {
145 if (headindex==NUMPTRS) {
146 struct pointerblock * tmp;
150 } else tmp=malloc(sizeof(struct pointerblock));
155 head->ptrs[headindex++]=ptr;
159 if (tailindex==NUMPTRS) {
160 struct pointerblock *tmp=tail;
168 return tail->ptrs[tailindex++];
172 void fixobjlist(struct objlist * ptr) {
175 for(i=0;i<ptr->offset;i++) {
176 SENQUEUE(ptr->objs[i], ptr->objs[i]);
182 void fixtable(chashlistnode_t ** tc_table, chashlistnode_t **tc_list, cliststruct_t **cstr, unsigned int tc_size) {
183 unsigned int mask=(tc_size<<4)-1;
184 chashlistnode_t *node=calloc(tc_size, sizeof(chashlistnode_t));
185 chashlistnode_t *ptr=*tc_table;
186 chashlistnode_t *curr;
190 chashlistnode_t *newlist=NULL;
191 for(i=0;i<tc_size;i++) {
194 do { //Inner loop to go through linked lists
196 chashlistnode_t *tmp,*next;
198 if ((key=(void *)curr->key) == 0) { //Exit inner loop if there the first element is 0
199 break; //key = val =0 for element if not present within the hash table
202 if (curr->val>=curr_heapbase&&curr->val<curr_heaptop) {
203 SENQUEUE(curr->val, curr->val);
205 //rewrite transaction cache entry
206 void *vptr=curr->val;
207 int type=((int *)vptr)[0];
208 unsigned INTPTR *pointer=pointerarray[type];
210 //array of primitives - do nothing
211 struct ArrayObject *ao=(struct ArrayObject *) vptr;
212 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao->___objlocation___));
213 } else if (((INTPTR)pointer)==1) {
215 struct ArrayObject *ao=(struct ArrayObject *) vptr;
216 int length=ao->___length___;
218 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao->___objlocation___));
220 int lowindex=ao->lowindex;
221 int highindex=ao->highindex;
223 for(j=lowindex; j<=highindex; j++) {
224 unsigned int lockval;
225 GETLOCKVAL(lockval, ao, j);
226 if (lockval!=STMNONE) {
227 int lowi=(j<<INDEXSHIFT)/sizeof(void *);
228 int highi=lowi+(INDEXLENGTH/sizeof(void *));
229 for(i=lowi; i<highi;i++) {
231 for(i=0; i<length; i++) {
233 void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
234 SENQUEUE(objptr, ((void **)(((char *)&ao->___length___)+sizeof(int)))[i]);
241 INTPTR size=pointer[0];
243 for(i=1; i<=size; i++) {
244 unsigned int offset=pointer[i];
245 void * objptr=*((void **)(((char *)vptr)+offset));
246 SENQUEUE(objptr, *((void **)(((char *)vptr)+offset)));
252 index = (((unsigned INTPTR)key) & mask) >>4;
256 // Insert into the new table
258 tmp->key = curr->key;
259 tmp->val = curr->val;
262 } else if (isfirst) {
263 chashlistnode_t *newnode;
264 if ((*cstr)->num<NUMCLIST) {
265 newnode=&(*cstr)->array[(*cstr)->num];
269 cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
272 newnode=&tcl->array[0];
275 newnode->key = curr->key;
276 newnode->val = curr->val;
277 newnode->next = tmp->next;
278 newnode->lnext=newlist;
284 curr->next=tmp->next;
298 if ((head==tail)&&(tailindex==headindex))
304 struct pointerblock *taghead=NULL;
307 void enqueuetag(struct ___TagDescriptor___ *ptr) {
308 if (tagindex==NUMPTRS) {
309 struct pointerblock * tmp=malloc(sizeof(struct pointerblock));
314 taghead->ptrs[tagindex++]=ptr;
318 #if defined(STM)||defined(THREADS)||defined(MLP)
319 __thread char * memorybase=NULL;
320 __thread char * memorytop=NULL;
324 void collect(struct garbagelist * stackptr) {
325 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
327 pthread_mutex_lock(&gclistlock);
329 if ((listcount+1)==threadcount) {
330 break; /* Have all other threads stopped */
332 pthread_cond_wait(&gccond, &gclistlock);
336 ptrstack.prev=stackptr;
337 stackptr=(struct garbagelist *) &ptrstack;
338 #if defined(STMARRAY)&&!defined(DUALVIEW)
339 arraystack.prev=stackptr;
340 stackptr=(struct garbagelist *) &arraystack;
347 for(i=0;i<MAXSTATS;i++)
355 head=tail=malloc(sizeof(struct pointerblock));
361 taghead=malloc(sizeof(struct pointerblock));
368 fixtable(&c_table, &c_list, &c_structs, c_size);
371 fixobjlist(lockedobjs);
375 #if defined(STM)||defined(THREADS)||defined(MLP)
379 /* Check current stack */
380 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
382 struct listitem *listptr=list;
386 while(stackptr!=NULL) {
388 for(i=0; i<stackptr->size; i++) {
389 void * orig=stackptr->array[i];
390 ENQUEUE(orig, stackptr->array[i]);
392 stackptr=stackptr->next;
394 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
395 /* Go to next thread */
398 if (listptr==&litem) {
400 // update forward list & memory queue for the current SESE
401 updateForwardList(((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
402 updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
404 listptr=listptr->next;
408 struct listitem *litem=pthread_getspecific(litemkey);
409 if (listptr==litem) {
410 listptr=listptr->next;
417 void * orig=listptr->locklist;
418 ENQUEUE(orig, listptr->locklist);
421 if ((*listptr->tc_table)!=NULL) {
422 fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_structs, listptr->tc_size);
423 fixobjlist(listptr->objlist);
425 fixobjlist(listptr->lockedlist);
429 #if defined(STM)||defined(THREADS)||defined(MLP)
430 *(listptr->base)=NULL;
433 // update forward list & memory queue for all running SESEs.
434 updateForwardList(((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
435 updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
437 stackptr=listptr->stackptr;
438 listptr=listptr->next;
446 ENQUEUE(___fcrevert___, ___fcrevert___);
451 /* Update objectsets */
453 for(i=0; i<NUMCLASSES; i++) {
454 #if !defined(MULTICORE)
455 struct parameterwrapper * p=objectqueues[i];
457 struct ObjectHash * set=p->objectset;
458 struct ObjectNode * ptr=set->listhead;
460 void *orig=(void *)ptr->key;
461 ENQUEUE(orig, *((void **)(&ptr->key)));
464 ObjectHashrehash(set); /* Rehash the table */
473 struct cnode * ptr=forward->listhead;
475 void * orig=(void *)ptr->key;
476 ENQUEUE(orig, *((void **)(&ptr->key)));
479 crehash(forward); /* Rehash the table */
483 struct cnode * ptr=reverse->listhead;
485 void *orig=(void *)ptr->val;
486 ENQUEUE(orig, *((void**)(&ptr->val)));
493 struct RuntimeNode * ptr=fdtoobject->listhead;
495 void *orig=(void *)ptr->data;
496 ENQUEUE(orig, *((void**)(&ptr->data)));
502 /* Update current task descriptor */
504 for(i=0; i<currtpd->numParameters; i++) {
505 void *orig=currtpd->parameterArray[i];
506 ENQUEUE(orig, currtpd->parameterArray[i]);
511 /* Update active tasks */
513 struct genpointerlist * ptr=activetasks->list;
515 struct taskparamdescriptor *tpd=ptr->src;
517 for(i=0; i<tpd->numParameters; i++) {
518 void * orig=tpd->parameterArray[i];
519 ENQUEUE(orig, tpd->parameterArray[i]);
523 genrehash(activetasks);
526 /* Update failed tasks */
528 struct genpointerlist * ptr=failedtasks->list;
530 struct taskparamdescriptor *tpd=ptr->src;
532 for(i=0; i<tpd->numParameters; i++) {
533 void * orig=tpd->parameterArray[i];
534 ENQUEUE(orig, tpd->parameterArray[i]);
538 genrehash(failedtasks);
544 // goes over ready-to-run SESEs
545 struct QI * qitem = headqi;
547 SESEcommon* common=(SESEcommon*)qitem->value;
548 if(common==seseCommon){
549 // skip the current running SESE
553 SESEcommon* seseRec = (SESEcommon*)(qitem->value);
554 struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]);
555 struct garbagelist * glroot=gl;
556 // update its ascendant SESEs
557 updateAscendantSESE(seseRec);
561 for(i=0; i<gl->size; i++) {
562 void * orig=gl->array[i];
563 ENQUEUE(orig, gl->array[i]);
574 void * ptr=dequeue();
576 int type=((int *)cpy)[0];
577 unsigned INTPTR * pointer;
581 /* Nothing is inside */
586 pointer=pointerarray[type];
588 /* Array of primitives */
590 #if defined(DSTM)||defined(FASTCHECK)
591 struct ArrayObject *ao=(struct ArrayObject *) ptr;
592 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
593 ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
594 ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
597 struct ArrayObject *ao=(struct ArrayObject *) ptr;
598 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
599 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao_cpy->___objlocation___));
601 } else if (((INTPTR)pointer)==1) {
602 /* Array of pointers */
603 struct ArrayObject *ao=(struct ArrayObject *) ptr;
604 struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
605 #if (defined(DSTM)||defined(FASTCHECK))
606 ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
607 ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
610 SENQUEUE((void *)ao->___objlocation___, *((void **)&ao_cpy->___objlocation___));
612 int length=ao->___length___;
614 for(i=0; i<length; i++) {
615 void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
616 ENQUEUE(objptr, ((void **)(((char *)&ao_cpy->___length___)+sizeof(int)))[i]);
619 INTPTR size=pointer[0];
621 for(i=1; i<=size; i++) {
622 unsigned int offset=pointer[i];
623 void * objptr=*((void **)(((char *)ptr)+offset));
624 ENQUEUE(objptr, *((void **)(((char *)cpy)+offset)));
634 //rehash memory queues of current running SESEs
635 struct listitem *listptr=list;
636 while(listptr!=NULL){
637 rehashMemoryQueue((SESEcommon*)(listptr->seseCommon));
638 listptr=listptr->next;
643 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
645 pthread_mutex_unlock(&gclistlock);
650 /* Fix up the references from tags. This can't be done earlier,
651 because we don't want tags to keep objects alive */
653 while(taghead!=NULL) {
655 struct pointerblock *tmp=taghead->next;
656 for(i=0; i<tagindex; i++) {
657 struct ___TagDescriptor___ *tagd=taghead->ptrs[i];
658 struct ___Object___ *obj=tagd->flagptr;
659 struct ___TagDescriptor___ *copy=((struct ___TagDescriptor___**)tagd)[1];
661 /* Zero object case */
662 } else if (obj->type==-1) {
663 /* Single object case */
664 copy->flagptr=((struct ___Object___**)obj)[1];
665 } else if (obj->type==OBJECTARRAYTYPE) {
667 struct ArrayObject *ao=(struct ArrayObject *) obj;
671 struct ArrayObject *aonew;
673 /* Count live objects */
674 for(j=0; j<ao->___cachedCode___; j++) {
675 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
680 livecount=((livecount-1)/OBJECTARRAYINTERVAL+1)*OBJECTARRAYINTERVAL;
681 aonew=(struct ArrayObject *) tomalloc(sizeof(struct ArrayObject)+sizeof(struct ___Object___*)*livecount);
682 memcpy(aonew, ao, sizeof(struct ArrayObject));
683 aonew->type=OBJECTARRAYTYPE;
684 aonew->___length___=livecount;
686 for(j=0; j<ao->___cachedCode___; j++) {
687 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
688 if (tobj->type==-1) {
689 struct ___Object___ * tobjcpy=((struct ___Object___**)tobj)[1];
690 ARRAYSET(aonew, struct ___Object___*, k++,tobjcpy);
693 aonew->___cachedCode___=k;
694 for(; k<livecount; k++) {
695 ARRAYSET(aonew, struct ___Object___*, k, NULL);
698 /* No object live anymore */
709 void * tomalloc(int size) {
710 void * ptr=to_heapptr;
717 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
718 void checkcollect(void * ptr) {
719 stopforgc((struct garbagelist *)ptr);
724 void checkcollect2(void * ptr) {
725 int ptrarray[]={1, (int)ptr, (int) revertlist};
726 stopforgc((struct garbagelist *)ptrarray);
728 revertlist=(struct ___Object___*)ptrarray[2];
732 void stopforgc(struct garbagelist * ptr) {
734 //just append us to the list
736 ptr=(struct garbagelist *) &ptrstack;
737 #if defined(STMARRAY)&&!defined(DUALVIEW)
739 ptr=(struct garbagelist *) &arraystack;
745 litem.locklist=pthread_getspecific(threadlocks);
747 #if defined(STM)||defined(THREADS)||defined(MLP)
748 litem.base=&memorybase;
751 litem.tc_size=c_size;
752 litem.tc_table=&c_table;
753 litem.tc_list=&c_list;
754 litem.tc_structs=&c_structs;
755 litem.objlist=newobjs;
757 litem.lockedlist=lockedobjs;
762 struct listitem *litem=pthread_getspecific(litemkey);
765 litem->locklist=pthread_getspecific(threadlocks);
768 pthread_mutex_lock(&gclistlock);
770 if ((listcount+1)==threadcount) {
771 //only do wakeup if we are ready to GC
772 pthread_cond_signal(&gccond);
774 pthread_mutex_unlock(&gclistlock);
777 void restartaftergc() {
779 pthread_mutex_lock(&gclock); // Wait for GC
780 pthread_mutex_unlock(&gclock);
782 pthread_mutex_lock(&gclistlock);
784 pthread_mutex_unlock(&gclistlock);
788 #if defined(STM)||defined(THREADS)||defined(MLP)
789 #define MEMORYBLOCK 65536
790 void * helper(struct garbagelist *, int);
791 void * mygcmalloc(struct garbagelist * stackptr, int size) {
794 if (memorybase==NULL||size>(memorytop-memorybase)) {
795 int toallocate=(size>MEMORYBLOCK)?size:MEMORYBLOCK;
796 memorybase=helper(stackptr, toallocate);
797 bzero(memorybase, toallocate);
798 memorytop=memorybase+toallocate;
800 char *retvalue=memorybase;
805 void * helper(struct garbagelist * stackptr, int size) {
807 void * mygcmalloc(struct garbagelist * stackptr, int size) {
810 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
811 while (pthread_mutex_trylock(&gclock)!=0) {
820 if (curr_heapptr>curr_heapgcpoint||curr_heapptr<curr_heapbase) {
821 if (curr_heapbase==0) {
822 /* Need to allocate base heap */
823 curr_heapbase=malloc(INITIALHEAPSIZE);
824 if (curr_heapbase==NULL) {
825 printf("malloc failed. Garbage colletcor couldn't get enough memory. Try changing heap size.\n");
828 #if defined(STM)||defined(THREADS)||defined(MLP)
830 bzero(curr_heapbase, INITIALHEAPSIZE);
832 curr_heaptop=curr_heapbase+INITIALHEAPSIZE;
833 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(INITIALHEAPSIZE);
834 curr_heapptr=curr_heapbase+size;
836 to_heapbase=malloc(INITIALHEAPSIZE);
837 if (to_heapbase==NULL) {
838 printf("malloc failed. Garbage collector couldn't get enough memory. Try changing heap size.\n");
842 to_heaptop=to_heapbase+INITIALHEAPSIZE;
843 to_heapptr=to_heapbase;
845 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
846 pthread_mutex_unlock(&gclock);
851 /* Grow the to heap if necessary */
853 INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
854 INTPTR to_heapsize=to_heaptop-to_heapbase;
855 INTPTR last_heapsize=0;
857 last_heapsize=HEAPSIZE(lastgcsize, size);
858 if ((last_heapsize&7)!=0)
859 last_heapsize+=(8-(last_heapsize%8));
861 if (curr_heapsize>last_heapsize)
862 last_heapsize=curr_heapsize;
863 if (last_heapsize>to_heapsize) {
865 to_heapbase=malloc(last_heapsize);
866 if (to_heapbase==NULL) {
867 printf("Error Allocating enough memory\n");
870 to_heaptop=to_heapbase+last_heapsize;
871 to_heapptr=to_heapbase;
875 /* Do our collection */
878 /* Update stat on previous gc size */
879 lastgcsize=(to_heapptr-to_heapbase)+size;
882 printf("Garbage collected: Old bytes: %u\n", curr_heapptr-curr_heapbase);
883 printf("New space: %u\n", to_heapptr-to_heapbase);
884 printf("Total space: %u\n", to_heaptop-to_heapbase);
887 for(i=0;i<MAXSTATS;i++) {
888 if (garbagearray[i]!=0)
889 printf("Type=%d Size=%u\n", i, garbagearray[i]);
893 /* Flip to/curr heaps */
895 void * tmp=to_heapbase;
896 to_heapbase=curr_heapbase;
900 to_heaptop=curr_heaptop;
904 curr_heapptr=to_heapptr+size;
905 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
906 to_heapptr=to_heapbase;
908 /* Not enough room :(, redo gc */
909 if (curr_heapptr>curr_heapgcpoint) {
910 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
911 pthread_mutex_unlock(&gclock);
913 return mygcmalloc(stackptr, size);
916 bzero(tmp, curr_heaptop-tmp);
917 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
918 pthread_mutex_unlock(&gclock);
923 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
924 pthread_mutex_unlock(&gclock);
930 int gc_createcopy(void * orig, void ** copy_ptr) {
935 int type=((int *)orig)[0];
937 *copy_ptr=((void **)orig)[1];
940 if (type<NUMCLASSES) {
941 /* We have a normal object */
943 int size=classsize[type]+sizeof(objheader_t);
944 void *newobj=tomalloc(size);
945 memcpy(newobj,((char *) orig)-sizeof(objheader_t), size);
946 newobj=((char *)newobj)+sizeof(objheader_t);
948 int size=classsize[type];
949 void *newobj=tomalloc(size);
950 memcpy(newobj, orig, size);
953 garbagearray[type]+=size;
956 ((void **)orig)[1]=newobj;
960 /* We have an array */
961 struct ArrayObject *ao=(struct ArrayObject *)orig;
962 int elementsize=classsize[type];
963 int length=ao->___length___;
966 int basesize=length*elementsize;
967 basesize=(basesize+LOWMASK)&HIGHMASK;
968 int versionspace=sizeof(int)*2*(basesize>>INDEXSHIFT);
969 int size=sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+versionspace;
970 void *newobj=tomalloc(size);
971 memcpy(newobj, ((char*)orig)-sizeof(objheader_t)-versionspace, size);
972 newobj=((char *)newobj)+sizeof(objheader_t)+versionspace;
974 int size=sizeof(struct ArrayObject)+length*elementsize+sizeof(objheader_t);
975 void *newobj=tomalloc(size);
976 memcpy(newobj, ((char*)orig)-sizeof(objheader_t), size);
977 newobj=((char *)newobj)+sizeof(objheader_t);
980 int size=sizeof(struct ArrayObject)+length*elementsize;
981 void *newobj=tomalloc(size);
982 memcpy(newobj, orig, size);
985 garbagearray[type]+=size;
988 ((void **)orig)[1]=newobj;
996 updateForwardList(struct Queue *forwardList, int prevUpdate){
998 struct QueueItem * fqItem=getHead(forwardList);
1000 SESEcommon* seseRec = (SESEcommon*)(fqItem->objectptr);
1001 struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]);
1002 if(prevUpdate==TRUE){
1003 updateAscendantSESE(seseRec);
1005 // do something here
1008 for(i=0; i<gl->size; i++) {
1009 void * orig=gl->array[i];
1010 ENQUEUE(orig, gl->array[i]);
1014 // iterate forwarding list of seseRec
1015 struct Queue* fList=seseRec->forwardList;
1016 updateForwardList(fList,prevUpdate);
1017 fqItem=getNextQueueItem(fqItem);
1022 updateMemoryQueue(SESEcommon* seseParent){
1023 // update memory queue
1025 for(i=0; i<seseParent->numMemoryQueue; i++){
1026 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
1027 MemoryQueueItem *memoryItem=memoryQueue->head;
1028 while(memoryItem!=NULL){
1029 if(memoryItem->type==HASHTABLE){
1030 Hashtable *ht=(Hashtable*)memoryItem;
1031 for(binidx=0; binidx<NUMBINS; binidx++){
1032 BinElement *bin=ht->array[binidx];
1033 BinItem *binItem=bin->head;
1034 while(binItem!=NULL){
1035 if(binItem->type==READBIN){
1036 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1038 for(ridx=0; ridx<readBinItem->index; ridx++){
1039 REntry *rentry=readBinItem->array[ridx];
1040 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1041 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1042 updateAscendantSESE(seseRec);
1045 for(i=0; i<gl->size; i++) {
1046 void * orig=gl->array[i];
1047 ENQUEUE(orig, gl->array[i]);
1053 REntry *rentry=((WriteBinItem*)binItem)->val;
1054 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1055 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1056 updateAscendantSESE(seseRec);
1059 for(i=0; i<gl->size; i++) {
1060 void * orig=gl->array[i];
1061 ENQUEUE(orig, gl->array[i]);
1066 binItem=binItem->next;
1069 }else if(memoryItem->type==VECTOR){
1070 Vector *vt=(Vector*)memoryItem;
1072 for(idx=0; idx<vt->index; idx++){
1073 REntry *rentry=vt->array[idx];
1075 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1076 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1077 updateAscendantSESE(seseRec);
1080 for(i=0; i<gl->size; i++) {
1081 void * orig=gl->array[i];
1082 ENQUEUE(orig, gl->array[i]);
1088 }else if(memoryItem->type==SINGLEITEM){
1089 SCC *scc=(SCC*)memoryItem;
1090 REntry *rentry=scc->val;
1092 SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec);
1093 struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]);
1094 updateAscendantSESE(seseRec);
1097 for(i=0; i<gl->size; i++) {
1098 void * orig=gl->array[i];
1099 ENQUEUE(orig, gl->array[i]);
1105 memoryItem=memoryItem->next;
1110 updateAscendantSESE(SESEcommon* seseRec){
1112 for(prevIdx=0; prevIdx<(seseRec->numDependentSESErecords); prevIdx++){
1113 SESEcommon* prevSESE = (SESEcommon*)
1116 seseRec->offsetToDepSESErecords +
1117 (sizeof(INTPTR)*prevIdx)
1121 struct garbagelist * prevgl=(struct garbagelist *)&(((SESEcommon*)(prevSESE))[1]);
1122 while(prevgl!=NULL) {
1124 for(i=0; i<prevgl->size; i++) {
1125 void * orig=prevgl->array[i];
1126 ENQUEUE(orig, prevgl->array[i]);
1128 prevgl=prevgl->next;
1136 int within(void *ptr){ //debug function
1137 if(ptr>curr_heapptr || ptr<curr_heapbase){
1138 __asm__ __volatile__ ("int $3"); // breakpoint