7bc9baa260e8dee875514bd495699842d2cb96ab
[IRC.git] / Robust / src / Runtime / bamboo / pmc_refupdate.c
1 #include <stdlib.h>
2 #include "structdefs.h"
3 #include "bambooalign.h"
4 #include "runtime_arch.h"
5 #include "pmc_forward.h"
6 #include "pmc_refupdate.h"
7 #include "multicoremgc.h"
8 #include "runtime.h"
9 #include "thread.h"
10
11
12 #define pmcupdateObj(objptr) ((void *)((struct ___Object___ *)objptr)->marked)
13
14 #define PMCUPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) {obj=pmcupdateObj(updatetmpptr);if (obj==NULL) {tprintf("BAD REF UPDATE %x->%x in %u\n",updatetmpptr,obj,__LINE__);}}}
15
16 #define PMCUPDATEOBJNONNULL(obj) {void *updatetmpptr=obj; obj=pmcupdateObj(updatetmpptr);if (obj==NULL) {tprintf("BAD REF UPDATE in %x->%x %u\n",updatetmpptr,obj,__LINE__);}}
17
18 void pmc_updatePtrs(void *ptr, int type) {
19   unsigned int * pointer=pointerarray[type];
20   if (pointer==0) {
21     /* Array of primitives */
22   } else if (((unsigned int)pointer)==1) {
23     /* Array of pointers */
24     struct ArrayObject *ao=(struct ArrayObject *) ptr;
25     int length=ao->___length___;
26     for(int j=0; j<length; j++) {
27       PMCUPDATEOBJ(((void **)(((char *)&ao->___length___)+sizeof(int)))[j]);
28     }
29   } else {
30     unsigned int size=pointer[0];
31     
32     for(int i=1; i<=size; i++) {
33       unsigned int offset=pointer[i];
34       PMCUPDATEOBJ(*((void **)(((char *)ptr)+offset)));
35     }
36   }  
37 }
38
39 void pmc_updategarbagelist(struct garbagelist *listptr) {
40   for(;listptr!=NULL; listptr=listptr->next) {
41     for(int i=0; i<listptr->size; i++) {
42       PMCUPDATEOBJ(listptr->array[i]);
43     }
44   }
45 }
46
47 void pmc_updateRuntimePtrs(struct garbagelist * stackptr) {
48   // update current stack
49   pmc_updategarbagelist(stackptr);
50
51   // update static pointers global_defs_p
52   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
53     pmc_updategarbagelist((struct garbagelist *)global_defs_p);
54   }
55
56 #ifdef TASK
57   // update objectsets
58   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
59     for(int i=0; i<NUMCLASSES; i++) {
60       struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
61       int length = numqueues[BAMBOO_NUM_OF_CORE][i];
62       for(int j = 0; j < length; ++j) {
63         struct parameterwrapper * parameter = queues[j];
64         struct ObjectHash * set=parameter->objectset;
65         for(struct ObjectNode * ptr=set->listhead;ptr!=NULL;ptr=ptr->lnext) {
66           PMCUPDATEOBJNONNULL(ptr->key);
67         }
68         ObjectHashrehash(set);
69       }
70     }
71   }
72
73   // update current task descriptor
74   if(currtpd != NULL) {
75     for(int i=0; i<currtpd->numParameters; i++) {
76       // the parameter can not be NULL
77       PMCUPDATEOBJNONNULL(currtpd->parameterArray[i]);
78     }
79   }
80
81   // update active tasks
82   if(activetasks != NULL) {
83     for(struct genpointerlist * ptr=activetasks->list;ptr!=NULL;ptr=ptr->inext){
84       struct taskparamdescriptor *tpd=ptr->src;
85       for(int i=0; i<tpd->numParameters; i++) {
86         // the parameter can not be NULL
87         PMCUPDATEOBJNONNULL(tpd->parameterArray[i]);
88       }
89     }
90     genrehash(activetasks);
91   }
92
93   // update cached transferred obj
94   for(struct QueueItem * tmpobjptr =  getHead(&objqueue);tmpobjptr != NULL;tmpobjptr = getNextQueueItem(tmpobjptr)) {
95     struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
96     // the obj can not be NULL
97     PMCUPDATEOBJNONNULL(objInfo->objptr);
98   }
99
100   // update cached objs to be transferred
101   for(struct QueueItem * item = getHead(totransobjqueue);item != NULL;item = getNextQueueItem(item)) {
102     struct transObjInfo * totransobj = (struct transObjInfo *)(item->objectptr);
103     // the obj can not be NULL
104     PMCUPDATEOBJNONNULL(totransobj->objptr);
105   }  
106
107   // enqueue lock related info
108   for(int i = 0; i < runtime_locklen; ++i) {
109     PMCUPDATEOBJ(runtime_locks[i].redirectlock);
110     PMCUPDATEOBJ(runtime_locks[i].value);
111   }
112 #endif
113
114 #ifdef MGC
115   // update the bamboo_threadlocks
116   for(int i = 0; i < bamboo_threadlocks.index; i++) {
117     // the locked obj can not be NULL
118     PMCUPDATEOBJNONNULL(bamboo_threadlocks.locks[i].object);
119   }
120
121   // update the bamboo_current_thread
122   PMCUPDATEOBJ(bamboo_current_thread);
123
124   // update global thread queue
125   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
126     unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
127     if(thread_counter > 0) {
128       unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
129       for(int i = thread_counter; i > 0; i--) {
130         // the thread obj can not be NULL
131         PMCUPDATEOBJNONNULL(*((void **)&bamboo_thread_queue[4+start]));
132         start = (start+1)&bamboo_max_thread_num_mask;
133       }
134     }
135     unlockthreadqueue();
136   }
137 #endif
138 }
139
140
141 void pmc_doreferenceupdate(struct garbagelist *stackptr) {
142   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
143   pmc_updateRuntimePtrs(stackptr);
144   pmc_referenceupdate(region->startptr, region->endptr);
145 }
146
147 void pmc_referenceupdate(void *bottomptr, void *topptr) {
148   void *tmpptr=bottomptr;
149   tprintf("%x -- %x\n", bottomptr, topptr);
150   while(tmpptr<topptr) {
151     unsigned int type;
152     unsigned int size;
153     gettype_size(tmpptr, &type, &size);
154     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
155     if (!type) {
156       tmpptr+=ALIGNMENTSIZE;
157       continue;
158     }
159     //if marked we update the pointers
160     if (((struct ___Object___ *) tmpptr)->marked) {
161       pmc_updatePtrs(tmpptr, type);
162     }
163     tmpptr+=size;
164   }
165 }
166
167 void pmc_docompact() {
168   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
169   pmc_compact(region, !(BAMBOO_NUM_OF_CORE&1), region->startptr, region->endptr);
170 }
171
172
173 void pmc_compact(struct pmc_region * region, int forward, void *bottomptr, void *topptr) {
174   if (forward) {
175     void *tmpptr=bottomptr;
176     while(tmpptr<topptr) {
177       unsigned int type;
178       unsigned int size;
179       gettype_size(tmpptr, &type, &size);
180       size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
181       if (!type) {
182         tmpptr+=ALIGNMENTSIZE;
183         continue;
184       }
185       //if marked we update the pointers
186       void *forwardptr=(void *)((struct ___Object___ *) tmpptr)->marked;
187       ((struct ___Object___ *) tmpptr)->marked=NULL;
188       if (forwardptr) {
189         memmove(forwardptr, tmpptr, size);
190       }
191       tmpptr+=size;
192     }
193   } else {
194     struct ___Object___ *backward=((struct ___Object___ *) region)->backward;
195     struct ___Object___ *lastobj=NULL;
196     while(backward) {
197       lastobj=backward;
198       backward=backward->backward;
199       unsigned int type;
200       unsigned int size;
201       gettype_size(lastobj, &type, &size);
202       size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
203       void *forwardptr=(void *)((struct ___Object___ *) lastobj)->marked;
204       ((struct ___Object___ *) lastobj)->marked=NULL;
205       if (forwardptr) {
206         memmove(forwardptr, lastobj, size);
207       }
208     }
209   }
210 }