Make SPECjbb compile again
[IRC.git] / Robust / src / Runtime / bamboo / multicoregcflush.c
1 #ifdef MULTICORE_GC
2 #include "multicoregcflush.h"
3 #include "multicoreruntime.h"
4 #include "ObjectHash.h"
5 #include "GenericHashtable.h"
6 #include "gcqueue.h"
7 #ifdef MGC
8 #include "runtime_arch.h"
9
10 extern int corenum;
11 #endif
12
13 /* Task specific includes */
14
15 #ifdef TASK
16 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
17 extern int numqueues[][NUMCLASSES];
18 extern struct genhashtable * activetasks;
19 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
20 extern struct taskparamdescriptor *currtpd;
21 extern struct LockValue runtime_locks[MAXTASKPARAMS];
22 extern int runtime_locklen;
23 #endif
24
25 extern struct global_defs_t * global_defs_p;
26
27 #ifdef MGC
28 extern struct lockvector bamboo_threadlocks;
29 #endif
30
31 // NOTE: the objptr should not be NULL and should not be non shared ptr
32 #define FLUSHOBJ(obj, tt) {void *flushtmpptr=obj; if (flushtmpptr!=NULL) obj=flushObj(flushtmpptr);}
33 #define FLUSHOBJNONNULL(obj, tt) {void *flushtmpptr=obj; obj=flushObj(flushtmpptr);}
34
35 INLINE void * flushObj(void * objptr) {
36   return gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)];
37 }
38
39 INLINE void updategarbagelist(struct garbagelist *listptr) {
40   for(;listptr!=NULL; listptr=listptr->next) {
41     for(int i=0; i<listptr->size; i++) {
42       FLUSHOBJ(listptr->array[i], i);
43     }
44   }
45 }
46
47 INLINE void flushRuntimeObj(struct garbagelist * stackptr) {
48   // flush current stack
49   updategarbagelist(stackptr);
50
51   // flush static pointers global_defs_p
52   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
53     updategarbagelist((struct garbagelist *)global_defs_p);
54   }
55
56 #ifdef TASK
57   // flush 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           FLUSHOBJNONNULL(ptr->key, 0);
67         }
68         ObjectHashrehash(set);
69       }
70     }
71   }
72
73   // flush current task descriptor
74   if(currtpd != NULL) {
75     for(int i=0; i<currtpd->numParameters; i++) {
76       // the parameter can not be NULL
77       FLUSHOBJNONNULL(currtpd->parameterArray[i], i);
78     }
79   }
80
81   // flush 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         FLUSHOBJNONNULL(tpd->parameterArray[i], i);
88       }
89     }
90     genrehash(activetasks);
91   }
92
93   // flush 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     FLUSHOBJNONNULL(objInfo->objptr, 0);
98   }
99
100   // flush 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     FLUSHOBJNONNULL(totransobj->objptr, 0);
105   }  
106
107   // enqueue lock related info
108   for(int i = 0; i < runtime_locklen; ++i) {
109     FLUSHOBJ(runtime_locks[i].redirectlock, i);
110     FLUSHOBJ(runtime_locks[i].value, i);
111   }
112 #endif
113
114 #ifdef MGC
115   // flush the bamboo_threadlocks
116   for(int i = 0; i < bamboo_threadlocks.index; i++) {
117     // the locked obj can not be NULL
118     FLUSHOBJNONNULL(bamboo_threadlocks.locks[i].object, i);
119   }
120
121   // flush the bamboo_current_thread
122   FLUSHOBJ(bamboo_current_thread, 0);
123
124   // flush 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         FLUSHOBJNONNULL(bamboo_thread_queue[4+start], 0);
132         start = (start+1)&bamboo_max_thread_num_mask;
133       }
134     }
135     unlockthreadqueue();
136   }
137 #endif
138 }
139
140 INLINE void flushPtrsInObj(void * ptr) {
141   int type = ((int *)(ptr))[0];
142   // scan all pointers in ptr
143   unsigned int * pointer=pointerarray[type];
144   if (pointer==0) {
145     /* Array of primitives */
146 #ifdef OBJECTHASPOINTERS
147     //handle object class
148     pointer=pointerarray[OBJECTTYPE];
149     unsigned int size=pointer[0];
150     for(int i=1; i<=size; i++) {
151       unsigned int offset=pointer[i];
152       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
153     }
154 #endif
155   } else if (((unsigned int)pointer)==1) {
156     /* Array of pointers */
157     struct ArrayObject *ao=(struct ArrayObject *) ptr;
158     int length=ao->___length___;
159     for(int j=0; j<length; j++) {
160       FLUSHOBJ(((void **)(((char *)&ao->___length___)+sizeof(int)))[j], j);
161     }
162 #ifdef OBJECTHASPOINTERS
163     pointer=pointerarray[OBJECTTYPE];
164     //handle object class
165     unsigned int size=pointer[0];
166     
167     for(int i=1; i<=size; i++) {
168       unsigned int offset=pointer[i];     
169       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
170     }
171 #endif
172   } else {
173     unsigned int size=pointer[0];
174     
175     for(int i=1; i<=size; i++) {
176       unsigned int offset=pointer[i];
177       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
178     }
179   }  
180 }
181
182 void flush(struct garbagelist * stackptr) {
183   BAMBOO_CACHE_MF();
184
185   flushRuntimeObj(stackptr);
186   while(gc_moreItems()) {
187     unsigned int ptr = gc_dequeue();
188     // should be a local shared obj and should have mapping info
189     FLUSHOBJNONNULL(ptr, 0);
190     BAMBOO_ASSERT(ptr != NULL);
191
192     if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
193       flushPtrsInObj((void *)ptr);
194       // restore the mark field, indicating that this obj has been flushed
195       ((struct ___Object___ *)ptr)->marked = INIT;
196     }
197   } 
198
199   // TODO bug here: the startup core contains all lobjs' info, thus all the
200   // lobjs are flushed in sequence.
201   // flush lobjs
202   while(gc_lobjmoreItems_I()) {
203     unsigned int ptr = gc_lobjdequeue_I(NULL, NULL);
204     FLUSHOBJ(ptr, 0);
205     BAMBOO_ASSERT(ptr!=NULL);
206
207     if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
208       flushPtrsInObj((void *)ptr);
209       // restore the mark field, indicating that this obj has been flushed
210       ((struct ___Object___ *)ptr)->marked = INIT;
211     }     
212   } 
213
214   // send flush finish message to core coordinator
215   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
216     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
217   } else {
218     send_msg_2(STARTUPCORE,GCFINISHFLUSH,BAMBOO_NUM_OF_CORE);
219   }
220
221
222 #endif // MULTICORE_GC