2 #include "multicoregcflush.h"
3 #include "multicoreruntime.h"
4 #include "ObjectHash.h"
5 #include "GenericHashtable.h"
7 /* Task specific includes */
10 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
11 extern int numqueues[][NUMCLASSES];
12 extern struct genhashtable * activetasks;
13 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
14 extern struct taskparamdescriptor *currtpd;
15 extern struct LockValue runtime_locks[MAXTASKPARAMS];
16 extern int runtime_locklen;
19 extern struct global_defs_t * global_defs_p;
22 extern struct lockvector bamboo_threadlocks;
25 // NOTE: the objptr should not be NULL and should not be non shared ptr
26 #define FLUSHOBJ(obj, tt) {void *flushtmpptr=obj; if (flushtmpptr!=NULL) obj=flushObj(flushtmpptr);}
27 #define FLUSHOBJNONNULL(obj, tt) {void *flushtmpptr=obj; obj=flushObj(flushtmpptr);}
29 INLINE void * flushObj(void * objptr) {
30 return gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)];
33 INLINE void updategarbagelist(struct garbagelist *listptr) {
34 for(;listptr!=NULL; listptr=listptr->next) {
35 for(int i=0; i<listptr->size; i++) {
36 FLUSHOBJ(listptr->array[i], i);
41 INLINE void flushRuntimeObj(struct garbagelist * stackptr) {
42 // flush current stack
43 updategarbagelist(stackptr);
45 // flush static pointers global_defs_p
46 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
47 updategarbagelist((struct garbagelist *)global_defs_p);
52 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
53 for(int i=0; i<NUMCLASSES; i++) {
54 struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
55 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
56 for(int j = 0; j < length; ++j) {
57 struct parameterwrapper * parameter = queues[j];
58 struct ObjectHash * set=parameter->objectset;
59 for(struct ObjectNode * ptr=set->listhead;ptr!=NULL;ptr=ptr->lnext) {
60 FLUSHOBJNONNULL(ptr->key, 0);
62 ObjectHashrehash(set);
67 // flush current task descriptor
69 for(int i=0; i<currtpd->numParameters; i++) {
70 // the parameter can not be NULL
71 FLUSHOBJNONNULL(currtpd->parameterArray[i], i);
76 if(activetasks != NULL) {
77 for(struct genpointerlist * ptr=activetasks->list;ptr!=NULL;ptr=ptr->inext) {
78 struct taskparamdescriptor *tpd=ptr->src;
79 for(int i=0; i<tpd->numParameters; i++) {
80 // the parameter can not be NULL
81 FLUSHOBJNONNULL(tpd->parameterArray[i], i);
84 genrehash(activetasks);
87 // flush cached transferred obj
88 for(struct QueueItem * tmpobjptr = getHead(&objqueue);tmpobjptr != NULL;tmpobjptr = getNextQueueItem(tmpobjptr)) {
89 struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
90 // the obj can not be NULL
91 FLUSHOBJNONNULL(objInfo->objptr, 0);
94 // flush cached objs to be transferred
95 for(struct QueueItem * item = getHead(totransobjqueue);item != NULL;item = getNextQueueItem(item);) {
96 struct transObjInfo * totransobj = (struct transObjInfo *)(item->objectptr);
97 // the obj can not be NULL
98 FLUSHOBJNONNULL(totransobj->objptr, 0);
101 // enqueue lock related info
102 for(int i = 0; i < runtime_locklen; ++i) {
103 FLUSHOBJ(runtime_locks[i].redirectlock, i);
104 FLUSHOBJ(runtime_locks[i].value, i);
109 // flush the bamboo_threadlocks
110 for(int i = 0; i < bamboo_threadlocks.index; i++) {
111 // the locked obj can not be NULL
112 FLUSHOBJNONNULL(bamboo_threadlocks.locks[i].object, i);
115 // flush the bamboo_current_thread
116 FLUSHOBJ(bamboo_current_thread, 0);
118 // flush global thread queue
119 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
120 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
121 if(thread_counter > 0) {
122 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
123 for(int i = thread_counter; i > 0; i--) {
124 // the thread obj can not be NULL
125 FLUSHOBJNONNULL(bamboo_thread_queue[4+start], 0);
126 start = (start+1)&bamboo_max_thread_num_mask;
134 INLINE void flushPtrsInObj(void * ptr) {
135 int type = ((int *)(ptr))[0];
136 // scan all pointers in ptr
137 unsigned int * pointer=pointerarray[type];
139 /* Array of primitives */
140 #ifdef OBJECTHASPOINTERS
141 //handle object class
142 pointer=pointerarray[OBJECTTYPE];
143 unsigned int size=pointer[0];
144 for(int i=1; i<=size; i++) {
145 unsigned int offset=pointer[i];
146 FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
149 } else if (((unsigned int)pointer)==1) {
150 /* Array of pointers */
151 struct ArrayObject *ao=(struct ArrayObject *) ptr;
152 int length=ao->___length___;
153 for(int j=0; j<length; j++) {
154 FLUSHOBJ(((void **)(((char *)&ao->___length___)+sizeof(int)))[j], j);
156 #ifdef OBJECTHASPOINTERS
157 pointer=pointerarray[OBJECTTYPE];
158 //handle object class
159 unsigned int size=pointer[0];
161 for(int i=1; i<=size; i++) {
162 unsigned int offset=pointer[i];
163 FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
167 unsigned int size=pointer[0];
169 for(int i=1; i<=size; i++) {
170 unsigned int offset=pointer[i];
171 FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
176 void flush(struct garbagelist * stackptr) {
179 flushRuntimeObj(stackptr);
181 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
182 if(!gc_moreItems_I()) {
183 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
187 unsigned int ptr = gc_dequeue_I();
188 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
189 // should be a local shared obj and should have mapping info
190 FLUSHOBJNONNULL(ptr, 0);
191 BAMBOO_ASSERT(ptr != NULL, 0xb02a);
193 if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
194 flushPtrsInObj((void *)ptr);
195 // restore the mark field, indicating that this obj has been flushed
196 ((struct ___Object___ *)ptr)->marked = INIT;
200 // TODO bug here: the startup core contains all lobjs' info, thus all the
201 // lobjs are flushed in sequence.
203 while(gc_lobjmoreItems_I()) {
204 unsigned int ptr = gc_lobjdequeue_I(NULL, NULL);
206 BAMBOO_ASSERT(ptr!=NULL, 0xb02d);
208 if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
209 flushPtrsInObj((void *)ptr);
210 // restore the mark field, indicating that this obj has been flushed
211 ((struct ___Object___ *)ptr)->marked = INIT;
215 // send flush finish message to core coordinator
216 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
217 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
219 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
223 #endif // MULTICORE_GC