3 #include "multicoreruntime.h"
4 #include "GenericHashtable.h"
6 #include "multicoregcmark.h"
7 #include "multicoregarbage.h"
11 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
12 extern int numqueues[][NUMCLASSES];
13 extern struct genhashtable * activetasks;
14 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
15 extern struct taskparamdescriptor *currtpd;
16 extern struct LockValue runtime_locks[MAXTASKPARAMS];
17 extern int runtime_locklen;
20 extern struct global_defs_t * global_defs_p;
23 extern struct lockvector bamboo_threadlocks;
26 INLINE void gettype_size(void * ptr, int * ttype, unsigned int * tsize) {
27 int type = ((int *)ptr)[0];
28 if(type < NUMCLASSES) {
30 *tsize = classsize[type];
34 struct ArrayObject *ao=(struct ArrayObject *)ptr;
35 unsigned int elementsize=classsize[type];
36 unsigned int length=ao->___length___;
37 *tsize = sizeof(struct ArrayObject)+length*elementsize;
42 INLINE bool isLarge(void * ptr, int * ttype, unsigned int * tsize) {
43 // check if a pointer refers to a large object
44 gettype_size(ptr, ttype, tsize);
45 unsigned INTPTR blocksize = (((unsigned INTPTR)(ptr-gcbaseva)) < BAMBOO_LARGE_SMEM_BOUND)? BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
47 // ptr is a start of a block OR it crosses the boundary of current block
48 return (*tsize) > blocksize;
51 //push the null check into the mark macro
53 //#define MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {markObj(marktmpptr);if ((marktmpptr<gcbaseva)||(marktmpptr>(gcbaseva+BAMBOO_SHARED_MEM_SIZE))) tprintf("Bad pointer %x in line %u\n",marktmpptr, __LINE__); }}
55 #define MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {markObj(marktmpptr);}}
57 #define MARKOBJNONNULL(objptr) {markObj(objptr);}
59 // NOTE: the objptr should not be NULL and should be a shared obj
60 void markObj(void * objptr) {
61 unsigned int host = hostcore(objptr);
62 if(BAMBOO_NUM_OF_CORE == host) {
64 if(!checkAndCondSetMark(objptr)) {
65 // this is the first time that this object is discovered,
66 // set the flag as DISCOVERED
70 // check if this obj has been forwarded already
71 if(MGCHashadd(gcforwardobjtbl, (unsigned int)objptr)) {
72 // if not, send msg to host informing that objptr is active
73 send_msg_2(host,GCMARKEDOBJ,objptr);
74 GCPROFILE_RECORD_FORWARD_OBJ();
80 void markgarbagelist(struct garbagelist * listptr) {
81 for(;listptr!=NULL;listptr=listptr->next) {
82 int size=listptr->size;
83 for(int i=0; i<size; i++) {
84 MARKOBJ(listptr->array[i]);
90 void tomark(struct garbagelist * stackptr) {
91 BAMBOO_ASSERT(MARKPHASE == gc_status_info.gcphase);
93 gc_status_info.gcbusystatus = true;
95 // enqueue current stack
96 markgarbagelist(stackptr);
98 // enqueue static pointers global_defs_p
99 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
100 markgarbagelist((struct garbagelist *)global_defs_p);
103 // enqueue objectsets
104 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
105 for(int i=0; i<NUMCLASSES; i++) {
106 struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
107 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
108 for(int j = 0; j < length; ++j) {
109 struct parameterwrapper * parameter = queues[j];
110 struct ObjectHash * set=parameter->objectset;
111 struct ObjectNode * ptr=set->listhead;
112 for(;ptr!=NULL;ptr=ptr->lnext) {
113 MARKOBJNONNULL((void *)ptr->key);
119 // enqueue current task descriptor
120 if(currtpd != NULL) {
121 for(int i=0; i<currtpd->numParameters; i++) {
122 // currtpd->parameterArray[i] can not be NULL
123 MARKOBJNONNULL(currtpd->parameterArray[i]);
127 // enqueue active tasks
128 if(activetasks != NULL) {
129 struct genpointerlist * ptr=activetasks->list;
130 for(;ptr!=NULL;ptr=ptr->inext) {
131 struct taskparamdescriptor *tpd=ptr->src;
132 for(int i=0; i<tpd->numParameters; i++) {
133 // the tpd->parameterArray[i] can not be NULL
134 MARKOBJNONNULL(tpd->parameterArray[i]);
139 // enqueue cached transferred obj
140 struct QueueItem * tmpobjptr = getHead(&objqueue);
141 for(;tmpobjptr != NULL;tmpobjptr=getNextQueueItem(tmpobjptr)) {
142 struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
143 // the objptr can not be NULL
144 MARKOBJNONNULL(objInfo->objptr);
147 // enqueue cached objs to be transferred
148 struct QueueItem * item = getHead(totransobjqueue);
149 for(;item != NULL;item=getNextQueueItem(item)) {
150 struct transObjInfo * totransobj=(struct transObjInfo *)(item->objectptr);
151 // the objptr can not be NULL
152 MARKOBJNONNULL(totransobj->objptr);
155 // enqueue lock related info
156 for(int i = 0; i < runtime_locklen; i++) {
157 MARKOBJ((void *)(runtime_locks[i].redirectlock));
158 MARKOBJ((void *)(runtime_locks[i].value));
163 // enqueue global thread queue
164 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
166 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
167 if(thread_counter > 0) {
168 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
169 for(int i = thread_counter; i > 0; i--) {
170 // the thread obj can not be NULL
171 MARKOBJNONNULL((void *)bamboo_thread_queue[4+start]);
172 start = (start+1)&bamboo_max_thread_num_mask;
176 // enqueue the bamboo_threadlocks
177 for(int i = 0; i < bamboo_threadlocks.index; i++) {
178 // the locks can not be NULL
179 MARKOBJNONNULL((void *)(bamboo_threadlocks.locks[i].object));
181 // enqueue the bamboo_current_thread
182 MARKOBJ(bamboo_current_thread);
186 INLINE void scanPtrsInObj(void * ptr, int type) {
187 // scan all pointers in ptr
188 unsigned int * pointer = pointerarray[type];
190 /* Array of primitives */
191 #ifdef OBJECTHASPOINTERS
192 pointer=pointerarray[OBJECTTYPE];
193 //handle object class
195 for(int i=1; i<=size; i++) {
196 unsigned int offset=pointer[i];
197 void * objptr=*((void **)(((char *)ptr)+offset));
201 } else if (((unsigned int)pointer)==1) {
202 /* Array of pointers */
203 struct ArrayObject *ao=(struct ArrayObject *) ptr;
204 int length=ao->___length___;
205 for(int i=0; i<length; i++) {
206 void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
209 #ifdef OBJECTHASPOINTERS
210 pointer=pointerarray[OBJECTTYPE];
211 //handle object class
213 for(int i=1; i<=size; i++) {
214 unsigned int offset=pointer[i];
215 void * objptr=*((void **)(((char *)ptr)+offset));
222 for(int i=1; i<=size; i++) {
223 unsigned int offset=pointer[i];
224 void * objptr=*((void **)(((char *)ptr)+offset));
230 void mark(struct garbagelist * stackptr) {
234 unsigned int isize = 0;
235 bool sendStall = false;
237 while(MARKPHASE == gc_status_info.gcphase) {
239 while(gc_moreItems()) {
241 gc_status_info.gcbusystatus = true;
242 void * ptr = gc_dequeue();
243 unsigned int size = 0;
244 unsigned int type = 0;
245 bool islarge=isLarge(ptr, &type, &size);
246 unsigned int iunits = ALIGNUNITS(size);
248 //debugging for the next five lines
249 unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
250 unsigned INTPTR hibits=alignsize>>4;
251 unsigned INTPTR lobits=(alignsize&15)<<1;
252 unsigned INTPTR ohigh=gcmarktbl[hibits];
253 unsigned INTPTR olow=gcmarktbl[hibits+1];
254 setLengthMarked(ptr,iunits);
255 unsigned int unit=getMarkedLength(ptr);
257 tprintf("Bad mark on %x %u!=%u\n", ptr, unit, iunits);
258 tprintf("hibits=%x lobits=%x\n", hibits, lobits);
259 tprintf("ohigh=%x olow=%x", ohigh, olow);
260 unsigned INTPTR nhigh=gcmarktbl[hibits];
261 unsigned INTPTR nlow=gcmarktbl[hibits+1];
262 tprintf("nhigh=%x nlow=%x", nhigh, nlow);
266 // ptr is a large object and not marked or enqueued
267 printf("NEED TO SUPPORT LARGE OBJECTS!\n");
269 // ptr is an unmarked active object on this core
270 unsigned int isize=iunits<<ALIGNMENTSHIFT;
271 gccurr_heaptop += isize;
273 // scan the pointers in object
274 scanPtrsInObj(ptr, type);
277 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
278 //make sure the queue is still empty...now we have interrupts off, things can't change on us...
280 if (!gc_moreItems_I()) {
281 gc_status_info.gcbusystatus = false;
282 // send mark finish msg to core coordinator
283 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
284 int entry_index = waitconfirm ? (gcnumsrobjs_index==0) : gcnumsrobjs_index;
285 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
286 gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
287 gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numreceiveobjs;
288 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
292 send_msg_4(STARTUPCORE,GCFINISHMARK,BAMBOO_NUM_OF_CORE,gcself_numsendobjs,gcself_numreceiveobjs);
295 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
301 #endif // MULTICORE_GC