3 #include "multicoregarbage.h"
4 #include "multicoreruntime.h"
5 #include "runtime_arch.h"
6 #include "SimpleHash.h"
7 #include "GenericHashtable.h"
8 #include "ObjectHash.h"
9 #include "GCSharedHash.h"
11 // TODO for profiling the flush phase
13 int num_mapinforequest;
15 unsigned long long marktime;
19 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
20 extern int numqueues[][NUMCLASSES];
22 extern struct genhashtable * activetasks;
23 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
24 extern struct taskparamdescriptor *currtpd;
26 extern struct LockValue runtime_locks[MAXTASKPARAMS];
27 extern int runtime_locklen;
31 struct pointerblock *next;
34 struct pointerblock *gchead=NULL;
36 struct pointerblock *gctail=NULL;
38 struct pointerblock *gctail2=NULL;
40 struct pointerblock *gcspare=NULL;
42 #define NUMLOBJPTRS 20
44 struct lobjpointerblock {
45 void * lobjs[NUMLOBJPTRS];
46 //void * dsts[NUMLOBJPTRS];
47 int lengths[NUMLOBJPTRS];
48 //void * origs[NUMLOBJPTRS];
49 int hosts[NUMLOBJPTRS];
50 struct lobjpointerblock *next;
51 struct lobjpointerblock *prev;
54 struct lobjpointerblock *gclobjhead=NULL;
55 int gclobjheadindex=0;
56 struct lobjpointerblock *gclobjtail=NULL;
57 int gclobjtailindex=0;
58 struct lobjpointerblock *gclobjtail2=NULL;
59 int gclobjtailindex2=0;
60 struct lobjpointerblock *gclobjspare=NULL;
63 // dump whole mem in blocks
64 inline void dumpSMem() {
72 printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
74 // reserved blocks for sblocktbl
75 printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
77 for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
78 printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
79 udn_tile_coord_x(), udn_tile_coord_y(),
80 *((int *)(i)), *((int *)(i + 4)),
81 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
82 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
83 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
84 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
85 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
86 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
87 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
89 sblock = gcreservedsb;
90 bool advanceblock = false;
92 for(i=gcbaseva; i<BAMBOO_BASE_VA+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
94 // computing sblock # and block #, core coordinate (x,y) also
95 if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
97 if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
98 if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
110 coren = gc_block2core[block%(NUMCORES4GC*2)];
112 // compute core coordinate
113 BAMBOO_COORDS(coren, &x, &y);
114 printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
115 udn_tile_coord_x(), udn_tile_coord_y(),
116 block, sblock++, x, y,
117 (sblock-1)*(BAMBOO_SMEM_SIZE)+BAMBOO_BASE_VA);
120 printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
121 udn_tile_coord_x(), udn_tile_coord_y(),
122 *((int *)(i)), *((int *)(i + 4)),
123 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
124 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
125 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
126 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
127 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
128 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
129 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
131 printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
135 // should be invoked with interruption closed
136 inline void gc_enqueue_I(void *ptr) {
138 BAMBOO_DEBUGPRINT(0xe601);
139 BAMBOO_DEBUGPRINT_REG(ptr);
141 if (gcheadindex==NUMPTRS) {
142 struct pointerblock * tmp;
147 tmp=RUNMALLOC_I(sizeof(struct pointerblock));
148 } // if (gcspare!=NULL)
152 } // if (gcheadindex==NUMPTRS)
153 gchead->ptrs[gcheadindex++]=ptr;
155 BAMBOO_DEBUGPRINT(0xe602);
157 } // void gc_enqueue_I(void *ptr)
159 // dequeue and destroy the queue
160 inline void * gc_dequeue_I() {
161 if (gctailindex==NUMPTRS) {
162 struct pointerblock *tmp=gctail;
169 } // if (gcspare!=NULL)
170 } // if (gctailindex==NUMPTRS)
171 return gctail->ptrs[gctailindex++];
172 } // void * gc_dequeue()
174 // dequeue and do not destroy the queue
175 inline void * gc_dequeue2_I() {
176 if (gctailindex2==NUMPTRS) {
177 struct pointerblock *tmp=gctail2;
178 gctail2=gctail2->next;
180 } // if (gctailindex2==NUMPTRS)
181 return gctail2->ptrs[gctailindex2++];
182 } // void * gc_dequeue2()
184 inline int gc_moreItems_I() {
185 if ((gchead==gctail)&&(gctailindex==gcheadindex))
188 } // int gc_moreItems()
190 inline int gc_moreItems2_I() {
191 if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
194 } // int gc_moreItems2()
196 // should be invoked with interruption closed
197 // enqueue a large obj: start addr & length
198 inline void gc_lobjenqueue_I(void *ptr,
202 BAMBOO_DEBUGPRINT(0xe901);
204 if (gclobjheadindex==NUMLOBJPTRS) {
205 struct lobjpointerblock * tmp;
206 if (gclobjspare!=NULL) {
210 tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
211 } // if (gclobjspare!=NULL)
212 gclobjhead->next=tmp;
213 tmp->prev = gclobjhead;
216 } // if (gclobjheadindex==NUMLOBJPTRS)
217 gclobjhead->lobjs[gclobjheadindex]=ptr;
218 gclobjhead->lengths[gclobjheadindex]=length;
219 gclobjhead->hosts[gclobjheadindex++]=host;
221 BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
222 BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
223 BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
225 } // void gc_lobjenqueue_I(void *ptr...)
227 // dequeue and destroy the queue
228 inline void * gc_lobjdequeue_I(int * length,
230 if (gclobjtailindex==NUMLOBJPTRS) {
231 struct lobjpointerblock *tmp=gclobjtail;
232 gclobjtail=gclobjtail->next;
234 gclobjtail->prev = NULL;
235 if (gclobjspare!=NULL) {
241 } // if (gclobjspare!=NULL)
242 } // if (gclobjtailindex==NUMLOBJPTRS)
244 *length = gclobjtail->lengths[gclobjtailindex];
247 *host = (int)(gclobjtail->hosts[gclobjtailindex]);
249 return gclobjtail->lobjs[gclobjtailindex++];
250 } // void * gc_lobjdequeue()
252 inline int gc_lobjmoreItems_I() {
253 if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
256 } // int gc_lobjmoreItems()
258 // dequeue and don't destroy the queue
259 inline void gc_lobjdequeue2_I() {
260 if (gclobjtailindex2==NUMLOBJPTRS) {
261 gclobjtail2=gclobjtail2->next;
265 } // if (gclobjtailindex2==NUMLOBJPTRS)
266 } // void * gc_lobjdequeue2()
268 inline int gc_lobjmoreItems2_I() {
269 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
272 } // int gc_lobjmoreItems2()
274 // 'reversly' dequeue and don't destroy the queue
275 inline void gc_lobjdequeue3_I() {
276 if (gclobjtailindex2==0) {
277 gclobjtail2=gclobjtail2->prev;
278 gclobjtailindex2=NUMLOBJPTRS-1;
281 } // if (gclobjtailindex2==NUMLOBJPTRS)
282 } // void * gc_lobjdequeue3()
284 inline int gc_lobjmoreItems3_I() {
285 if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
288 } // int gc_lobjmoreItems3()
290 inline void gc_lobjqueueinit4_I() {
291 gclobjtail2 = gclobjtail;
292 gclobjtailindex2 = gclobjtailindex;
293 } // void gc_lobjqueueinit2()
295 inline void * gc_lobjdequeue4_I(int * length,
297 if (gclobjtailindex2==NUMLOBJPTRS) {
298 gclobjtail2=gclobjtail2->next;
300 } // if (gclobjtailindex==NUMLOBJPTRS)
302 *length = gclobjtail2->lengths[gclobjtailindex2];
305 *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
307 return gclobjtail2->lobjs[gclobjtailindex2++];
308 } // void * gc_lobjdequeue()
310 inline int gc_lobjmoreItems4_I() {
311 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
314 } // int gc_lobjmoreItems(
316 INTPTR gccurr_heapbound = 0;
318 inline void gettype_size(void * ptr,
321 int type = ((int *)ptr)[0];
323 if(type < NUMCLASSES) {
325 size = classsize[type];
328 struct ArrayObject *ao=(struct ArrayObject *)ptr;
329 int elementsize=classsize[type];
330 int length=ao->___length___;
331 size=sizeof(struct ArrayObject)+length*elementsize;
332 } // if(type < NUMCLASSES)
337 inline bool isLarge(void * ptr,
341 BAMBOO_DEBUGPRINT(0xe701);
342 BAMBOO_DEBUGPRINT_REG(ptr);
344 // check if a pointer is referring to a large object
345 gettype_size(ptr, ttype, tsize);
347 BAMBOO_DEBUGPRINT(*tsize);
349 int bound = (BAMBOO_SMEM_SIZE);
350 if(((int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
351 bound = (BAMBOO_SMEM_SIZE_L);
353 if((((int)ptr-gcbaseva)%(bound))==0) {
354 // ptr is a start of a block
356 BAMBOO_DEBUGPRINT(0xe702);
357 BAMBOO_DEBUGPRINT(1);
361 if((bound-(((int)ptr-gcbaseva)%bound)) < (*tsize)) {
362 // it acrosses the boundary of current block
364 BAMBOO_DEBUGPRINT(0xe703);
365 BAMBOO_DEBUGPRINT(1);
370 BAMBOO_DEBUGPRINT(0);
373 } // bool isLarge(void * ptr, int * ttype, int * tsize)
375 inline int hostcore(void * ptr) {
376 // check the host core of ptr
378 RESIDECORE(ptr, &host);
380 BAMBOO_DEBUGPRINT(0xedd0);
381 BAMBOO_DEBUGPRINT_REG(ptr);
382 BAMBOO_DEBUGPRINT_REG(host);
385 } // int hostcore(void * ptr)
387 inline bool isLocal(void * ptr) {
388 // check if a pointer is in shared heap on this core
389 return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
390 } // bool isLocal(void * ptr)
392 inline bool gc_checkCoreStatus_I() {
393 bool allStall = true;
394 for(int i = 0; i < NUMCORES4GC; ++i) {
395 if(gccorestatus[i] != 0) {
398 } // if(gccorestatus[i] != 0)
399 } // for(i = 0; i < NUMCORES4GC; ++i)
403 inline bool gc_checkAllCoreStatus_I() {
404 bool allStall = true;
405 for(int i = 0; i < NUMCORESACTIVE; ++i) {
406 if(gccorestatus[i] != 0) {
409 } // if(gccorestatus[i] != 0)
410 } // for(i = 0; i < NUMCORESACTIVE; ++i)
414 inline void checkMarkStatue() {
416 BAMBOO_DEBUGPRINT(0xee01);
420 (waitconfirm && (numconfirm == 0))) {
422 BAMBOO_DEBUGPRINT(0xee02);
424 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
425 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
426 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
427 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
428 // check the status of all cores
429 bool allStall = gc_checkAllCoreStatus_I();
431 BAMBOO_DEBUGPRINT(0xee03);
435 BAMBOO_DEBUGPRINT(0xee04);
440 BAMBOO_DEBUGPRINT(0xee05);
442 // the first time found all cores stall
443 // send out status confirm msg to all other cores
444 // reset the corestatus array too
445 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
447 numconfirm = NUMCORESACTIVE - 1;
448 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
449 for(i = 1; i < NUMCORESACTIVE; ++i) {
451 // send mark phase finish confirm request msg to core i
452 send_msg_1(i, GCMARKCONFIRM, false);
453 } // for(i = 1; i < NUMCORESACTIVE; ++i)
455 // check if the sum of send objs and receive obj are the same
456 // yes->check if the info is the latest; no->go on executing
458 for(i = 0; i < NUMCORESACTIVE; ++i) {
459 sumsendobj += gcnumsendobjs[i];
460 } // for(i = 0; i < NUMCORESACTIVE; ++i)
462 BAMBOO_DEBUGPRINT(0xee06);
463 BAMBOO_DEBUGPRINT_REG(sumsendobj);
465 for(i = 0; i < NUMCORESACTIVE; ++i) {
466 sumsendobj -= gcnumreceiveobjs[i];
467 } // for(i = 0; i < NUMCORESACTIVE; ++i)
469 BAMBOO_DEBUGPRINT(0xee07);
470 BAMBOO_DEBUGPRINT_REG(sumsendobj);
472 if(0 == sumsendobj) {
474 BAMBOO_DEBUGPRINT(0xee08);
476 // all the core status info are the latest
478 gcphase = COMPACTPHASE;
479 // restore the gcstatus for all cores
480 for(i = 0; i < NUMCORESACTIVE; ++i) {
482 } // for(i = 0; i < NUMCORESACTIVE; ++i)
484 // wait for a while and ask for confirm again
489 } // if(0 == sumsendobj) else ...
490 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
491 } // if(!gcwaitconfirm) else()
493 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
495 } // if((!waitconfirm)...
497 BAMBOO_DEBUGPRINT(0xee0a);
499 } // void checkMarkStatue()
501 inline bool preGC() {
502 // preparation for gc
503 // make sure to clear all incoming msgs espacially transfer obj msgs
505 BAMBOO_DEBUGPRINT(0xec01);
509 (waitconfirm && (numconfirm == 0))) {
510 // send out status confirm msgs to all cores to check if there are
511 // transfer obj msgs on-the-fly
513 numconfirm = NUMCORESACTIVE - 1;
514 for(i = 1; i < NUMCORESACTIVE; ++i) {
516 // send status confirm msg to core i
517 send_msg_1(i, STATUSCONFIRM, false);
518 } // for(i = 1; i < NUMCORESACTIVE; ++i)
521 BAMBOO_DEBUGPRINT(0xec02);
524 if(numconfirm == 0) {
527 } // wait for confirmations
531 BAMBOO_DEBUGPRINT(0xec03);
533 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
534 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
537 BAMBOO_DEBUGPRINT(0xec04);
539 for(i = 0; i < NUMCORESACTIVE; ++i) {
540 sumsendobj += numsendobjs[i];
542 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
544 } // for(i = 1; i < NUMCORESACTIVE; ++i)
546 BAMBOO_DEBUGPRINT(0xec05);
547 BAMBOO_DEBUGPRINT_REG(sumsendobj);
549 for(i = 0; i < NUMCORESACTIVE; ++i) {
550 sumsendobj -= numreceiveobjs[i];
552 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
554 } // for(i = 1; i < NUMCORESACTIVE; ++i)
556 BAMBOO_DEBUGPRINT(0xec06);
557 BAMBOO_DEBUGPRINT_REG(sumsendobj);
559 if(0 == sumsendobj) {
562 // still have some transfer obj msgs on-the-fly, can not start gc
564 } // if(0 == sumsendobj)
567 BAMBOO_DEBUGPRINT(0xec07);
569 // previously asked for status confirmation and do not have all the
570 // confirmations yet, can not start gc
572 } // if((!waitconfirm) ||
575 inline void initGC() {
577 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
578 for(i = 0; i < NUMCORES4GC; ++i) {
580 gcnumsendobjs[i] = 0;
581 gcnumreceiveobjs[i] = 0;
583 gcrequiredmems[i] = 0;
584 gcfilledblocks[i] = 0;
586 } // for(i = 0; i < NUMCORES4GC; ++i)
587 for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
589 gcnumsendobjs[i] = 0;
590 gcnumreceiveobjs[i] = 0;
595 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
596 gcself_numsendobjs = 0;
597 gcself_numreceiveobjs = 0;
598 gcmarkedptrbound = 0;
601 //gcismapped = false;
612 gcheadindex=gctailindex=gctailindex2 = 0;
613 gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
615 gctailindex = gctailindex2 = gcheadindex;
616 gctail = gctail2 = gchead;
619 // initialize the large obj queues
620 if (gclobjhead==NULL) {
623 gclobjtailindex2 = 0;
624 gclobjhead=gclobjtail=gclobjtail2=
625 RUNMALLOC(sizeof(struct lobjpointerblock));
627 gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
628 gclobjtail = gclobjtail2 = gclobjhead;
630 gclobjhead->next = gclobjhead->prev = NULL;
632 freeRuntimeHash(gcpointertbl);
633 gcpointertbl = allocateRuntimeHash(20);
634 //gcpointertbl = allocateMGCHash(20);
637 freeMGCHash(gcforwardobjtbl);
638 gcforwardobjtbl = allocateMGCHash(20, 3);
640 // initialize the mapping info related structures
641 if((BAMBOO_NUM_OF_CORE < NUMCORES4GC) && (gcsharedptbl != NULL)) {
642 // Never free the shared hash table, just reset it
643 /*freeGCSharedHash(gcsharedptbl);
644 gcsharedptbl = allocateGCSharedHash(20);*/
645 mgcsharedhashReset(gcsharedptbl);
647 // the shared hash tables are never changed
648 //BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(struct RuntimeHash *)*NUMCORES4GC);
651 num_mapinforequest = 0;
652 num_mapinforequest_i = 0;
654 flushstalltime_i = 0;
660 // compute load balance for all cores
661 inline int loadbalance(int * heaptop) {
662 // compute load balance
665 // get the total loads
666 int tloads = gcloads[STARTUPCORE];
667 for(i = 1; i < NUMCORES4GC; i++) {
668 tloads += gcloads[i];
670 *heaptop = gcbaseva + tloads;
672 BAMBOO_DEBUGPRINT(0xdddd);
673 BAMBOO_DEBUGPRINT_REG(tloads);
674 BAMBOO_DEBUGPRINT_REG(*heaptop);
677 BLOCKINDEX(*heaptop, &b);
678 int numbpc = b / NUMCORES4GC; // num of blocks per core
680 BAMBOO_DEBUGPRINT_REG(b);
681 BAMBOO_DEBUGPRINT_REG(numbpc);
684 RESIDECORE(heaptop, &gctopcore);
686 BAMBOO_DEBUGPRINT_REG(gctopcore);
689 } // void loadbalance(int * heaptop)
691 inline bool cacheLObjs() {
692 // check the total mem size need for large objs
696 BAMBOO_DEBUGPRINT(0xe801);
698 gclobjtail2 = gclobjtail;
699 gclobjtailindex2 = gclobjtailindex;
703 // compute total mem size required and sort the lobjs in ascending order
704 while(gc_lobjmoreItems2_I()) {
706 tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
707 tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
708 tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
711 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
712 BAMBOO_DEBUGPRINT_REG(tmp_len);
713 BAMBOO_DEBUGPRINT_REG(sumsize);
715 int i = gclobjtailindex2-1;
716 struct lobjpointerblock * tmp_block = gclobjtail2;
717 // find the place to insert
720 if(tmp_block->prev == NULL) {
723 if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
724 tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
725 tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
726 tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
727 tmp_block = tmp_block->prev;
731 } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
733 if(tmp_block->lobjs[i-1] > tmp_lobj) {
734 tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
735 tmp_block->lengths[i] = tmp_block->lengths[i-1];
736 tmp_block->hosts[i] = tmp_block->hosts[i-1];
740 } // if(tmp_block->lobjs[i-1] < tmp_lobj)
741 } // if(i ==0 ) else {}
744 if(i != gclobjtailindex2 - 1) {
745 tmp_block->lobjs[i] = tmp_lobj;
746 tmp_block->lengths[i] = tmp_len;
747 tmp_block->hosts[i] = tmp_host;
749 } // while(gc_lobjmoreItems2())
751 // check if there are enough space to cache these large objs
752 INTPTR dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
753 if(gcheaptop > dst) {
754 // do not have enough room to cache large objs
756 BAMBOO_DEBUGPRINT(0xe802);
757 BAMBOO_DEBUGPRINT_REG(dst);
758 BAMBOO_DEBUGPRINT_REG(gcheaptop);
763 BAMBOO_DEBUGPRINT(0xe803);
764 BAMBOO_DEBUGPRINT_REG(dst);
765 BAMBOO_DEBUGPRINT_REG(gcheaptop);
768 gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
769 // cache the largeObjs to the top of the shared heap
770 //gclobjtail2 = gclobjtail;
771 //gclobjtailindex2 = gclobjtailindex;
772 dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
773 while(gc_lobjmoreItems3_I()) {
775 size = gclobjtail2->lengths[gclobjtailindex2];
776 // set the mark field to , indicating that this obj has been moved
777 // and need to be flushed
778 ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[6] = COMPACTED;
780 if((int)dst < (int)(gclobjtail2->lobjs[gclobjtailindex2])+size) {
781 memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
783 //BAMBOO_WRITE_HINT_CACHE(dst, size);
784 memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
787 BAMBOO_DEBUGPRINT(0x804);
788 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
789 BAMBOO_DEBUGPRINT(dst);
790 BAMBOO_DEBUGPRINT_REG(size);
791 BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
792 BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
796 } // void cacheLObjs()
798 // NOTE: the free mem chunks should be maintained in an ordered linklist
799 // the listtop param always specify current list tail
801 // update the bmmboo_smemtbl to record current shared mem usage
802 void updateSmemTbl(int coren,
805 int bound = BAMBOO_SMEM_SIZE_L;
806 BLOCKINDEX(localtop, <opcore);
807 if(localtop >= (gcbaseva+(BAMBOO_LARGE_SMEM_BOUND))) {
808 bound = BAMBOO_SMEM_SIZE;
810 int load = (localtop-gcbaseva)%bound;
815 toset = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
816 if(toset < ltopcore) {
817 bamboo_smemtbl[toset]=
818 (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
819 } else if(toset == ltopcore) {
820 bamboo_smemtbl[toset] = load;
831 } // void updateSmemTbl(int, int)
833 inline void moveLObjs() {
835 BAMBOO_DEBUGPRINT(0xea01);
837 // zero out the smemtbl
838 BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
839 // find current heap top
840 // flush all gcloads to indicate the real heap top on one core
841 // previous it represents the next available ptr on a core
842 if((gcloads[0] > (gcbaseva+(BAMBOO_SMEM_SIZE_L)))
843 && ((gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
844 // edge of a block, check if this is exactly the heaptop
845 BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
846 gcloads[0]+=(gcfilledblocks[0]>1 ?
847 (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
849 updateSmemTbl(0, gcloads[0]);
851 BAMBOO_DEBUGPRINT(0xea02);
852 BAMBOO_DEBUGPRINT_REG(gcloads[0]);
853 BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
855 for(int i = 1; i < NUMCORES4GC; i++) {
858 BAMBOO_DEBUGPRINT(0xf000+i);
859 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
860 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
862 if((gcfilledblocks[i] > 0)
863 && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
864 // edge of a block, check if this is exactly the heaptop
865 BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
867 +=(gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
870 updateSmemTbl(i, gcloads[i]);
872 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
874 } // for(int i = 1; i < NUMCORES4GC; i++) {
876 // find current heap top
878 // a bug here: when using local allocation, directly move large objects
879 // to the highest free chunk might not be memory efficient
884 for(i = gcnumblock-1; i >= 0; i--) {
885 if(bamboo_smemtbl[i] > 0) {
890 tmpheaptop = gcbaseva;
892 tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
893 (BAMBOO_SMEM_SIZE_L*i) :
894 (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
897 // move large objs from gcheaptop to tmpheaptop
898 // write the header first
899 int tomove = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -gcheaptop;
901 BAMBOO_DEBUGPRINT(0xea03);
902 BAMBOO_DEBUGPRINT_REG(tomove);
903 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
904 BAMBOO_DEBUGPRINT_REG(gcheaptop);
906 // flush the sbstartbl
907 BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
908 (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-gcreservedsb)*sizeof(INTPTR));
910 gcheaptop = tmpheaptop;
912 // check how many blocks it acrosses
913 int remain = tmpheaptop-gcbaseva;
914 int sb = remain/(BAMBOO_SMEM_SIZE) + gcreservedsb; //number of the sblock
915 int b = 0; // number of the block
916 BLOCKINDEX(tmpheaptop, &b);
917 // check the remaining space in this block
918 bound = (BAMBOO_SMEM_SIZE);
919 if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
920 bound = (BAMBOO_SMEM_SIZE_L);
922 remain = bound - remain%bound;
925 BAMBOO_DEBUGPRINT(0xea04);
931 int base = tmpheaptop;
933 remain -= BAMBOO_CACHE_LINE_SIZE;
934 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
935 gc_lobjqueueinit4_I();
936 while(gc_lobjmoreItems4_I()) {
937 ptr = (int)(gc_lobjdequeue4_I(&size, &host));
938 ALIGNSIZE(size, &isize);
940 // this object acrosses blocks
942 // close current block, fill its header
943 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
944 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
945 bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE; // add the size of the header
949 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
950 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
952 remain -= BAMBOO_CACHE_LINE_SIZE;
953 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
954 BLOCKINDEX(tmpheaptop, &b);
955 sb = (tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE) + gcreservedsb;
958 // move the large obj
959 if((int)gcheaptop < (int)(tmpheaptop)+size) {
960 memmove(tmpheaptop, gcheaptop, size);
962 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
963 memcpy(tmpheaptop, gcheaptop, size);
965 // fill the remaining space with -2 padding
966 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
967 // zero out original mem caching the lobj
968 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
970 BAMBOO_DEBUGPRINT(0xea05);
971 BAMBOO_DEBUGPRINT_REG(gcheaptop);
972 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
973 BAMBOO_DEBUGPRINT_REG(size);
974 BAMBOO_DEBUGPRINT_REG(isize);
975 BAMBOO_DEBUGPRINT_REG(base);
978 // cache the mapping info anyway
979 //if(ptr != tmpheaptop) {
980 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
981 //mgchashInsert_I(ptr, tmpheaptop);
982 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
983 //struct nodemappinginfo * nodeinfo = NULL;
984 //RuntimeHashget(gcpointertbl, ptr, &nodeinfo);
985 //nodeinfo->ptr = tmpheaptop;
986 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
987 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
990 BAMBOO_DEBUGPRINT(0xcdca);
991 BAMBOO_DEBUGPRINT_REG(ptr);
992 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
994 if(host != BAMBOO_NUM_OF_CORE) {
995 // send the original host core with the mapping info
996 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
998 BAMBOO_DEBUGPRINT(0xcdcb);
999 BAMBOO_DEBUGPRINT_REG(ptr);
1000 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1002 } // if(host != BAMBOO_NUM_OF_CORE)
1003 tmpheaptop += isize;
1005 // set the gcsbstarttbl and bamboo_smemtbl
1006 int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
1007 for(int k = 1; k < tmpsbs; k++) {
1008 gcsbstarttbl[sb+k] = (INTPTR)(-1);
1011 bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1012 BLOCKINDEX(tmpheaptop-1, &tmpsbs);
1013 for(; b < tmpsbs; b++) {
1014 bamboo_smemtbl[b] = bound;
1015 if(b==NUMCORES4GC-1) {
1016 bound = BAMBOO_SMEM_SIZE;
1019 if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
1020 gcsbstarttbl[sb] = (INTPTR)(-1);
1021 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
1022 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1023 bamboo_smemtbl[b] = bound;
1025 gcsbstarttbl[sb] = (INTPTR)(tmpheaptop);
1026 remain = tmpheaptop-gcbaseva;
1027 bamboo_smemtbl[b] = remain%bound;
1028 remain = bound - bamboo_smemtbl[b];
1029 } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
1031 // close current block and fill the header
1032 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1033 *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
1036 if(remain == BAMBOO_CACHE_LINE_SIZE) {
1037 // fill with 0 in case
1038 BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
1040 remain -= BAMBOO_CACHE_LINE_SIZE;
1041 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
1044 // move the large obj
1045 if((int)gcheaptop < (int)(tmpheaptop)+size) {
1046 memmove(tmpheaptop, gcheaptop, size);
1048 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
1049 memcpy(tmpheaptop, gcheaptop, size);
1051 // fill the remaining space with -2 padding
1052 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
1053 // zero out original mem caching the lobj
1054 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
1056 BAMBOO_DEBUGPRINT(0xea06);
1057 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1058 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1059 BAMBOO_DEBUGPRINT_REG(size);
1060 BAMBOO_DEBUGPRINT_REG(isize);
1065 // cache the mapping info anyway
1066 //if(ptr != tmpheaptop) {
1067 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1068 //mgchashInsert_I(ptr, tmpheaptop);
1069 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
1070 //struct nodemappinginfo * nodeinfo = NULL;
1071 //RuntimeHashget(gcpointertbl, ptr, &nodeinfo);
1072 //nodeinfo->ptr = tmpheaptop;
1073 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
1074 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1077 BAMBOO_DEBUGPRINT(0xcdcc);
1078 BAMBOO_DEBUGPRINT_REG(ptr);
1079 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1080 BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
1082 if(host != BAMBOO_NUM_OF_CORE) {
1083 // send the original host core with the mapping info
1084 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
1086 BAMBOO_DEBUGPRINT(0xcdcd);
1087 BAMBOO_DEBUGPRINT_REG(ptr);
1088 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1090 } // if(host != BAMBOO_NUM_OF_CORE)
1091 tmpheaptop += isize;
1093 // update bamboo_smemtbl
1094 bamboo_smemtbl[b] += isize;
1095 } // if(remain < isize) else ...
1096 } // while(gc_lobjmoreItems())
1098 // close current block, fill the header
1099 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1100 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
1101 bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE; // add the size of the header
1103 tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
1105 gcheaptop = tmpheaptop;
1107 } // if(tomove == 0)
1110 BAMBOO_DEBUGPRINT(0xea07);
1111 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1114 bamboo_free_block = 0;
1117 tbound = (bamboo_free_block<NUMCORES4GC) ?
1118 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1119 if(bamboo_smemtbl[bamboo_free_block] == tbound) {
1120 bamboo_free_block++;
1122 // the first non-full partition
1127 BAMBOO_DEBUGPRINT(0xea08);
1128 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1130 } // void moveLObjs()
1132 inline void markObj(void * objptr) {
1133 if(objptr == NULL) {
1136 if(ISSHAREDOBJ(objptr)) {
1137 int host = hostcore(objptr);
1138 if(BAMBOO_NUM_OF_CORE == host) {
1140 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1141 if(((int *)objptr)[6] == INIT) {
1142 // this is the first time that this object is discovered,
1143 // set the flag as DISCOVERED
1144 ((int *)objptr)[6] |= DISCOVERED;
1145 gc_enqueue_I(objptr);
1147 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1150 BAMBOO_DEBUGPRINT(0xbbbb);
1151 BAMBOO_DEBUGPRINT_REG(host);
1152 BAMBOO_DEBUGPRINT_REG(objptr);
1154 // check if this obj has been forwarded
1155 if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
1157 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
1159 // send a msg to host informing that objptr is active
1160 send_msg_2(host, GCMARKEDOBJ, objptr, /*BAMBOO_NUM_OF_CORE,*/ false);
1164 marktime += BAMBOO_GET_EXE_TIME() - ttime;
1165 num_markrequest++;*/
1167 gcself_numsendobjs++;
1168 MGCHashadd(gcforwardobjtbl, (int)objptr);
1172 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1173 gc_enqueue_I(objptr);
1174 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1175 } // if(ISSHAREDOBJ(objptr))
1176 } // void markObj(void * objptr)
1178 // enqueue root objs
1179 inline void tomark(struct garbagelist * stackptr) {
1180 if(MARKPHASE != gcphase) {
1182 BAMBOO_DEBUGPRINT_REG(gcphase);
1184 BAMBOO_EXIT(0xb101);
1186 gcbusystatus = true;
1190 // enqueue current stack
1191 while(stackptr!=NULL) {
1193 BAMBOO_DEBUGPRINT(0xe501);
1194 BAMBOO_DEBUGPRINT_REG(stackptr->size);
1195 BAMBOO_DEBUGPRINT_REG(stackptr->next);
1196 BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
1198 for(i=0; i<stackptr->size; i++) {
1199 if(stackptr->array[i] != NULL) {
1200 markObj(stackptr->array[i]);
1203 stackptr=stackptr->next;
1207 BAMBOO_DEBUGPRINT(0xe503);
1209 // enqueue objectsets
1210 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1211 for(i=0; i<NUMCLASSES; i++) {
1212 struct parameterwrapper ** queues =
1213 objectqueues[BAMBOO_NUM_OF_CORE][i];
1214 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
1215 for(j = 0; j < length; ++j) {
1216 struct parameterwrapper * parameter = queues[j];
1217 struct ObjectHash * set=parameter->objectset;
1218 struct ObjectNode * ptr=set->listhead;
1220 markObj((void *)ptr->key);
1227 // euqueue current task descriptor
1228 if(currtpd != NULL) {
1230 BAMBOO_DEBUGPRINT(0xe504);
1232 for(i=0; i<currtpd->numParameters; i++) {
1233 markObj(currtpd->parameterArray[i]);
1238 BAMBOO_DEBUGPRINT(0xe505);
1240 // euqueue active tasks
1241 if(activetasks != NULL) {
1242 struct genpointerlist * ptr=activetasks->list;
1244 struct taskparamdescriptor *tpd=ptr->src;
1246 for(i=0; i<tpd->numParameters; i++) {
1247 markObj(tpd->parameterArray[i]);
1254 BAMBOO_DEBUGPRINT(0xe506);
1256 // enqueue cached transferred obj
1257 struct QueueItem * tmpobjptr = getHead(&objqueue);
1258 while(tmpobjptr != NULL) {
1259 struct transObjInfo * objInfo =
1260 (struct transObjInfo *)(tmpobjptr->objectptr);
1261 markObj(objInfo->objptr);
1262 tmpobjptr = getNextQueueItem(tmpobjptr);
1266 BAMBOO_DEBUGPRINT(0xe507);
1268 // enqueue cached objs to be transferred
1269 struct QueueItem * item = getHead(totransobjqueue);
1270 while(item != NULL) {
1271 struct transObjInfo * totransobj =
1272 (struct transObjInfo *)(item->objectptr);
1273 markObj(totransobj->objptr);
1274 item = getNextQueueItem(item);
1275 } // while(item != NULL)
1278 BAMBOO_DEBUGPRINT(0xe508);
1280 // enqueue lock related info
1281 for(i = 0; i < runtime_locklen; ++i) {
1282 markObj((void *)(runtime_locks[i].redirectlock));
1283 if(runtime_locks[i].value != NULL) {
1284 markObj((void *)(runtime_locks[i].value));
1288 } // void tomark(struct garbagelist * stackptr)
1290 inline void mark(bool isfirst,
1291 struct garbagelist * stackptr) {
1293 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed01);
1297 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed02);
1299 // enqueue root objs
1301 gccurr_heaptop = 0; // record the size of all active objs in this core
1302 // aligned but does not consider block boundaries
1303 gcmarkedptrbound = 0;
1306 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed03);
1309 bool checkfield = true;
1310 bool sendStall = false;
1312 while(MARKPHASE == gcphase) {
1314 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed04);
1317 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1318 bool hasItems = gc_moreItems2_I();
1319 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1321 BAMBOO_DEBUGPRINT(0xed05);
1327 gcbusystatus = true;
1329 void * ptr = gc_dequeue2_I();
1332 BAMBOO_DEBUGPRINT_REG(ptr);
1337 // check if it is a shared obj
1338 if(ISSHAREDOBJ(ptr)) {
1339 // a shared obj, check if it is a local obj on this core
1340 int host = hostcore(ptr);
1341 bool islocal = (host == BAMBOO_NUM_OF_CORE);
1343 bool isnotmarked = ((((int *)ptr)[6] & DISCOVERED) != 0);
1344 if(isLarge(ptr, &type, &size) && isnotmarked) {
1345 // ptr is a large object and not marked or enqueued
1347 BAMBOO_DEBUGPRINT(0xecec);
1348 BAMBOO_DEBUGPRINT_REG(ptr);
1349 BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
1351 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1352 gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
1354 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1356 ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
1357 } else if(isnotmarked) {
1358 // ptr is an unmarked active object on this core
1359 ALIGNSIZE(size, &isize);
1360 gccurr_heaptop += isize;
1362 BAMBOO_DEBUGPRINT(0xaaaa);
1363 BAMBOO_DEBUGPRINT_REG(ptr);
1364 BAMBOO_DEBUGPRINT_REG(isize);
1365 BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
1368 ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
1370 if(ptr + size > gcmarkedptrbound) {
1371 gcmarkedptrbound = ptr + size;
1372 } // if(ptr + size > gcmarkedptrbound)
1374 // ptr is not an active obj or has been marked
1376 } // if(isLarge(ptr, &type, &size)) else ...
1377 } /* can never reach here
1380 if(BAMBOO_NUM_OF_CORE == 0) {
1381 BAMBOO_DEBUGPRINT(0xbbbb);
1382 BAMBOO_DEBUGPRINT_REG(host);
1383 BAMBOO_DEBUGPRINT_REG(ptr);
1386 // check if this obj has been forwarded
1387 if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
1388 // send a msg to host informing that ptr is active
1389 send_msg_2(host, GCMARKEDOBJ, ptr, false);
1390 gcself_numsendobjs++;
1391 MGCHashadd(gcforwardobjtbl, (int)ptr);
1394 }// if(isLocal(ptr)) else ...*/
1395 } // if(ISSHAREDOBJ(ptr))
1397 BAMBOO_DEBUGPRINT(0xed06);
1401 // scan all pointers in ptr
1402 unsigned INTPTR * pointer;
1403 pointer=pointerarray[type];
1405 /* Array of primitives */
1407 } else if (((INTPTR)pointer)==1) {
1408 /* Array of pointers */
1409 struct ArrayObject *ao=(struct ArrayObject *) ptr;
1410 int length=ao->___length___;
1412 for(j=0; j<length; j++) {
1414 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
1418 INTPTR size=pointer[0];
1420 for(i=1; i<=size; i++) {
1421 unsigned int offset=pointer[i];
1422 void * objptr=*((void **)(((char *)ptr)+offset));
1425 } // if (pointer==0) else if ... else ...
1427 } // while(gc_moreItems2())
1429 BAMBOO_DEBUGPRINT(0xed07);
1431 gcbusystatus = false;
1432 // send mark finish msg to core coordinator
1433 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1435 BAMBOO_DEBUGPRINT(0xed08);
1437 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
1438 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
1439 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
1440 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
1444 BAMBOO_DEBUGPRINT(0xed09);
1446 send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
1447 gcself_numsendobjs, gcself_numreceiveobjs, false);
1450 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
1452 BAMBOO_DEBUGPRINT(0xed0a);
1455 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1457 BAMBOO_DEBUGPRINT(0xed0b);
1461 } // while(MARKPHASE == gcphase)
1464 inline void compact2Heaptophelper_I(int coren,
1469 int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
1470 if(STARTUPCORE == coren) {
1472 gcmovestartaddr = *p;
1473 gcdstcore = gctopcore;
1474 gcblock2fill = *numblocks + 1;
1476 send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
1479 BAMBOO_DEBUGPRINT_REG(coren);
1480 BAMBOO_DEBUGPRINT_REG(gctopcore);
1481 BAMBOO_DEBUGPRINT_REG(*p);
1482 BAMBOO_DEBUGPRINT_REG(*numblocks+1);
1484 if(memneed < *remain) {
1486 BAMBOO_DEBUGPRINT(0xd104);
1489 gcrequiredmems[coren] = 0;
1490 gcloads[gctopcore] += memneed;
1491 *remain = *remain - memneed;
1494 BAMBOO_DEBUGPRINT(0xd105);
1496 // next available block
1498 gcfilledblocks[gctopcore] += 1;
1500 BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
1501 gcloads[gctopcore] = newbase;
1502 gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
1503 gcstopblock[gctopcore]++;
1504 gctopcore = NEXTTOPCORE(gctopblock);
1506 *numblocks = gcstopblock[gctopcore];
1507 *p = gcloads[gctopcore];
1509 *remain=(b<NUMCORES4GC) ?
1510 ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
1511 : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
1513 BAMBOO_DEBUGPRINT(0xd106);
1514 BAMBOO_DEBUGPRINT_REG(gctopcore);
1515 BAMBOO_DEBUGPRINT_REG(*p);
1516 BAMBOO_DEBUGPRINT_REG(b);
1517 BAMBOO_DEBUGPRINT_REG(*remain);
1519 } // if(memneed < remain)
1521 } // void compact2Heaptophelper_I(int, int*, int*, int*)
1523 inline void compact2Heaptop() {
1524 // no cores with spare mem and some cores are blocked with pending move
1525 // find the current heap top and make them move to the heap top
1527 int numblocks = gcfilledblocks[gctopcore];
1528 //BASEPTR(gctopcore, numblocks, &p);
1529 p = gcloads[gctopcore];
1532 int remain = (b<NUMCORES4GC) ?
1533 ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
1534 : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
1535 // check if the top core finishes
1536 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1537 if(gccorestatus[gctopcore] != 0) {
1539 BAMBOO_DEBUGPRINT(0xd101);
1540 BAMBOO_DEBUGPRINT_REG(gctopcore);
1542 // let the top core finishes its own work first
1543 compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
1544 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1547 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1550 BAMBOO_DEBUGPRINT(0xd102);
1551 BAMBOO_DEBUGPRINT_REG(gctopcore);
1552 BAMBOO_DEBUGPRINT_REG(p);
1553 BAMBOO_DEBUGPRINT_REG(b);
1554 BAMBOO_DEBUGPRINT_REG(remain);
1556 for(int i = 0; i < NUMCORES4GC; i++) {
1557 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1558 if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
1560 BAMBOO_DEBUGPRINT(0xd103);
1562 compact2Heaptophelper_I(i, &p, &numblocks, &remain);
1563 if(gccorestatus[gctopcore] != 0) {
1565 BAMBOO_DEBUGPRINT(0xd101);
1566 BAMBOO_DEBUGPRINT_REG(gctopcore);
1568 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1569 // the top core is not free now
1572 } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
1573 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1574 } // for(i = 0; i < NUMCORES4GC; i++)
1576 BAMBOO_DEBUGPRINT(0xd106);
1578 } // void compact2Heaptop()
1580 inline void resolvePendingMoveRequest() {
1582 BAMBOO_DEBUGPRINT(0xeb01);
1585 BAMBOO_DEBUGPRINT(0xeeee);
1586 for(int k = 0; k < NUMCORES4GC; k++) {
1587 BAMBOO_DEBUGPRINT(0xf000+k);
1588 BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
1589 BAMBOO_DEBUGPRINT_REG(gcloads[k]);
1590 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
1591 BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
1593 BAMBOO_DEBUGPRINT(0xffff);
1597 bool nosparemem = true;
1598 bool haspending = false;
1599 bool hasrunning = false;
1600 bool noblock = false;
1601 int dstcore = 0; // the core who need spare mem
1602 int sourcecore = 0; // the core who has spare mem
1603 for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
1605 // check if there are cores with spare mem
1606 if(gccorestatus[i] == 0) {
1607 // finished working, check if it still have spare mem
1608 if(gcfilledblocks[i] < gcstopblock[i]) {
1609 // still have spare mem
1612 } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
1617 if(gccorestatus[j] != 0) {
1618 // not finished, check if it has pending move requests
1619 if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
1624 } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
1625 } // if(gccorestatus[i] == 0) else ...
1627 } // if(!haspending)
1628 if(!nosparemem && haspending) {
1632 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1633 gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
1634 gcrequiredmems[dstcore],
1637 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1639 BAMBOO_DEBUGPRINT(0xeb02);
1640 BAMBOO_DEBUGPRINT_REG(sourcecore);
1641 BAMBOO_DEBUGPRINT_REG(dstcore);
1642 BAMBOO_DEBUGPRINT_REG(startaddr);
1643 BAMBOO_DEBUGPRINT_REG(tomove);
1645 if(STARTUPCORE == dstcore) {
1647 BAMBOO_DEBUGPRINT(0xeb03);
1649 gcdstcore = sourcecore;
1651 gcmovestartaddr = startaddr;
1652 gcblock2fill = tomove;
1655 BAMBOO_DEBUGPRINT(0xeb04);
1657 send_msg_4(dstcore, GCMOVESTART, sourcecore,
1658 startaddr, tomove, false);
1665 } // for(i = 0; i < NUMCORES4GC; i++)
1667 BAMBOO_DEBUGPRINT(0xcccc);
1668 BAMBOO_DEBUGPRINT_REG(hasrunning);
1669 BAMBOO_DEBUGPRINT_REG(haspending);
1670 BAMBOO_DEBUGPRINT_REG(noblock);
1673 if(!hasrunning && !noblock) {
1674 gcphase = SUBTLECOMPACTPHASE;
1678 } // void resovePendingMoveRequest()
1681 int numblocks; // block num for heap
1682 INTPTR base; // base virtual address of current heap block
1683 INTPTR ptr; // virtual address of current heap top
1684 int offset; // offset in current heap block
1685 int blockbase; // virtual address of current small block to check
1686 int blockbound; // bound virtual address of current small blcok
1687 int sblockindex; // index of the small blocks
1688 int top; // real size of current heap block to check
1689 int bound; // bound size of current heap block to check
1690 }; // struct moveHelper
1692 // if out of boundary of valid shared memory, return false, else return true
1693 inline bool nextSBlock(struct moveHelper * orig) {
1694 orig->blockbase = orig->blockbound;
1695 bool sbchanged = false;
1697 BAMBOO_DEBUGPRINT(0xecc0);
1698 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1699 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1700 BAMBOO_DEBUGPRINT_REG(orig->bound);
1701 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1704 // check if across a big block
1705 if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)
1706 || ((orig->ptr != NULL) && (*((int*)orig->ptr))==0)
1707 || ((*((int*)orig->blockbase))==0)) {
1709 // end of current heap block, jump to next one
1712 BAMBOO_DEBUGPRINT(0xecc1);
1713 BAMBOO_DEBUGPRINT_REG(orig->numblocks);
1715 BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
1717 BAMBOO_DEBUGPRINT(orig->base);
1719 if(orig->base >= BAMBOO_BASE_VA + BAMBOO_SHARED_MEM_SIZE) {
1721 orig->ptr = orig->base; // set current ptr to out of boundary too
1724 orig->bound = orig->base + BAMBOO_SMEM_SIZE;
1725 orig->blockbase = orig->base;
1726 orig->sblockindex = (orig->blockbase-BAMBOO_BASE_VA)/BAMBOO_SMEM_SIZE;
1729 BLOCKINDEX(orig->base, &blocknum);
1730 if(bamboo_smemtbl[blocknum] == 0) {
1732 goto innernextSBlock;
1734 } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
1735 orig->sblockindex += 1;
1737 } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
1739 // check if this sblock should be skipped or have special start point
1740 if(gcsbstarttbl[orig->sblockindex] == -1) {
1743 BAMBOO_DEBUGPRINT(0xecc2);
1745 orig->sblockindex += 1;
1746 orig->blockbase += BAMBOO_SMEM_SIZE;
1747 goto outernextSBlock;
1748 } else if((gcsbstarttbl[orig->sblockindex] != 0)
1750 // the first time to access this SBlock
1752 BAMBOO_DEBUGPRINT(0xecc3);
1754 // not start from the very beginning
1755 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1756 } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
1758 // setup information for this sblock
1759 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1760 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1761 orig->ptr = orig->blockbase + orig->offset;
1763 BAMBOO_DEBUGPRINT(0xecc4);
1764 BAMBOO_DEBUGPRINT_REG(orig->base);
1765 BAMBOO_DEBUGPRINT_REG(orig->bound);
1766 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1767 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1768 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1769 BAMBOO_DEBUGPRINT_REG(orig->offset);
1771 if(orig->ptr >= orig->bound) {
1772 // met a lobj, move to next block
1773 goto innernextSBlock;
1777 } // bool nextSBlock(struct moveHelper * orig)
1779 // return false if there are no available data to compact
1780 inline bool initOrig_Dst(struct moveHelper * orig,
1781 struct moveHelper * to) {
1784 to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
1785 to->bound = BAMBOO_SMEM_SIZE_L;
1786 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1789 BAMBOO_DEBUGPRINT(0xef01);
1790 BAMBOO_DEBUGPRINT_REG(to->base);
1792 to->ptr = to->base + to->offset;
1794 // init the orig ptr
1795 orig->numblocks = 0;
1796 orig->base = to->base;
1797 orig->bound = to->base + BAMBOO_SMEM_SIZE_L;
1798 orig->blockbase = orig->base;
1799 orig->sblockindex = (orig->base - BAMBOO_BASE_VA) / BAMBOO_SMEM_SIZE;
1801 BAMBOO_DEBUGPRINT(0xef02);
1802 BAMBOO_DEBUGPRINT_REG(orig->base);
1803 BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
1804 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
1805 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
1808 if(gcsbstarttbl[orig->sblockindex] == -1) {
1810 BAMBOO_DEBUGPRINT(0xef03);
1814 BAMBOO_BASE_VA+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
1815 return nextSBlock(orig);
1816 } else if(gcsbstarttbl[orig->sblockindex] != 0) {
1818 BAMBOO_DEBUGPRINT(0xef04);
1820 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1823 BAMBOO_DEBUGPRINT(0xef05);
1825 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1826 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1827 orig->ptr = orig->blockbase + orig->offset;
1829 BAMBOO_DEBUGPRINT(0xef06);
1830 BAMBOO_DEBUGPRINT_REG(orig->base);
1833 } // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
1835 inline void nextBlock(struct moveHelper * to) {
1836 to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
1837 to->bound += BAMBOO_SMEM_SIZE;
1839 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1840 to->offset = BAMBOO_CACHE_LINE_SIZE;
1841 to->ptr = to->base + to->offset;
1842 } // void nextBlock(struct moveHelper * to)
1844 // endaddr does not contain spaces for headers
1845 inline bool moveobj(struct moveHelper * orig,
1846 struct moveHelper * to,
1848 if(stopblock == 0) {
1853 BAMBOO_DEBUGPRINT(0xe201);
1854 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1855 BAMBOO_DEBUGPRINT_REG(to->ptr);
1863 while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
1864 orig->ptr = (int*)(orig->ptr) + 1;
1866 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
1867 if(!nextSBlock(orig)) {
1868 // finished, no more data
1874 BAMBOO_DEBUGPRINT(0xe202);
1875 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1876 BAMBOO_DEBUGPRINT(((int *)(orig->ptr))[0]);
1878 // check the obj's type, size and mark flag
1879 type = ((int *)(orig->ptr))[0];
1882 // end of this block, go to next one
1883 if(!nextSBlock(orig)) {
1884 // finished, no more data
1888 } else if(type < NUMCLASSES) {
1890 size = classsize[type];
1893 struct ArrayObject *ao=(struct ArrayObject *)(orig->ptr);
1894 int elementsize=classsize[type];
1895 int length=ao->___length___;
1896 size=sizeof(struct ArrayObject)+length*elementsize;
1898 mark = ((int *)(orig->ptr))[6];
1899 bool isremote = ((((int *)(orig->ptr))[6] & REMOTEM) != 0);
1901 BAMBOO_DEBUGPRINT(0xe203);
1902 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1903 BAMBOO_DEBUGPRINT_REG(size);
1905 ALIGNSIZE(size, &isize); // no matter is the obj marked or not
1906 // should be able to across it
1907 if((mark & MARKED) != 0) {
1909 BAMBOO_DEBUGPRINT(0xe204);
1911 // marked obj, copy it to current heap top
1912 // check to see if remaining space is enough
1913 if(to->top + isize > to->bound) {
1914 // fill 0 indicating the end of this block
1915 BAMBOO_MEMSET_WH(to->ptr, '\0', to->bound - to->top);
1916 // fill the header of this block and then go to next block
1917 to->offset += to->bound - to->top;
1918 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1919 (*((int*)(to->base))) = to->offset;
1921 if(stopblock == to->numblocks) {
1922 // already fulfilled the block
1924 } // if(stopblock == to->numblocks)
1925 } // if(to->top + isize > to->bound)
1926 // set the mark field to 2, indicating that this obj has been moved
1927 // and need to be flushed
1928 ((int *)(orig->ptr))[6] = COMPACTED;
1929 if(to->ptr != orig->ptr) {
1930 if((int)(orig->ptr) < (int)(to->ptr)+size) {
1931 memmove(to->ptr, orig->ptr, size);
1933 //BAMBOO_WRITE_HINT_CACHE(to->ptr, size);
1934 memcpy(to->ptr, orig->ptr, size);
1936 // fill the remaining space with -2
1937 BAMBOO_MEMSET_WH(to->ptr+size, -2, isize-size);
1939 // store mapping info
1940 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1941 //mgchashInsert_I(orig->ptr, to->ptr);
1942 RuntimeHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1945 //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
1947 // add to the sharedptbl
1948 if(gcsharedptbl != NULL) {
1949 //GCSharedHashadd_I(gcsharedptbl, orig->ptr, to->ptr);
1950 mgcsharedhashInsert_I(gcsharedptbl, orig->ptr, to->ptr);
1951 //num_mapinforequest++; // TODO
1954 //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
1957 //MGCHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1958 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1961 BAMBOO_DEBUGPRINT(0xcdce);
1962 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1963 BAMBOO_DEBUGPRINT_REG(to->ptr);
1965 gccurr_heaptop -= isize;
1967 to->offset += isize;
1969 if(to->top == to->bound) {
1970 // fill the header of this block and then go to next block
1971 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1972 (*((int*)(to->base))) = to->offset;
1977 BAMBOO_DEBUGPRINT(0xe205);
1983 BAMBOO_DEBUGPRINT_REG(isize);
1984 BAMBOO_DEBUGPRINT_REG(size);
1985 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1986 BAMBOO_DEBUGPRINT_REG(orig->bound);
1988 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
1990 BAMBOO_DEBUGPRINT(0xe206);
1992 if(!nextSBlock(orig)) {
1993 // finished, no more data
1998 BAMBOO_DEBUGPRINT(0xe207);
1999 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2002 } //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
2004 // should be invoked with interrupt closed
2005 inline int assignSpareMem_I(int sourcecore,
2010 BLOCKINDEX(gcloads[sourcecore], &b);
2011 int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
2012 : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
2013 int remain = boundptr - gcloads[sourcecore];
2014 int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
2015 *startaddr = gcloads[sourcecore];
2016 *tomove = gcfilledblocks[sourcecore] + 1;
2017 if(memneed < remain) {
2018 gcloads[sourcecore] += memneed;
2021 // next available block
2022 gcfilledblocks[sourcecore] += 1;
2024 BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
2025 gcloads[sourcecore] = newbase;
2026 return requiredmem-remain;
2028 } // int assignSpareMem_I(int ,int * , int * , int * )
2030 // should be invoked with interrupt closed
2031 inline bool gcfindSpareMem_I(int * startaddr,
2036 for(int k = 0; k < NUMCORES4GC; k++) {
2037 if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
2038 // check if this stopped core has enough mem
2039 assignSpareMem_I(k, requiredmem, tomove, startaddr);
2044 // if can not find spare mem right now, hold the request
2045 gcrequiredmems[requiredcore] = requiredmem;
2048 } //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
2050 inline bool compacthelper(struct moveHelper * orig,
2051 struct moveHelper * to,
2054 bool * localcompact) {
2055 // scan over all objs in this block, compact the marked objs
2056 // loop stop when finishing either scanning all active objs or
2057 // fulfilled the gcstopblock
2059 BAMBOO_DEBUGPRINT(0xe101);
2060 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2061 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2064 while(orig->ptr < gcmarkedptrbound) {
2065 bool stop = moveobj(orig, to, gcblock2fill);
2070 // if no objs have been compact, do nothing,
2071 // otherwise, fill the header of this block
2072 if(to->offset > BAMBOO_CACHE_LINE_SIZE) {
2073 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2074 (*((int*)(to->base))) = to->offset;
2078 to->top -= BAMBOO_CACHE_LINE_SIZE;
2079 } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
2081 *heaptopptr = to->ptr;
2082 *filledblocks = to->numblocks;
2085 BAMBOO_DEBUGPRINT(0xe102);
2086 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2087 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2088 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2089 BAMBOO_DEBUGPRINT_REG(*filledblocks);
2090 BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
2093 // send msgs to core coordinator indicating that the compact is finishing
2094 // send compact finish message to core coordinator
2095 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2096 gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
2097 gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
2098 if(orig->ptr < gcmarkedptrbound) {
2100 BAMBOO_DEBUGPRINT(0xe103);
2104 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2105 if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
2106 gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
2108 BAMBOO_DEBUGPRINT(0xe104);
2112 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2114 BAMBOO_DEBUGPRINT(0xe105);
2118 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2121 BAMBOO_DEBUGPRINT(0xe106);
2123 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2128 if(orig->ptr < gcmarkedptrbound) {
2130 BAMBOO_DEBUGPRINT(0xe107);
2134 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2135 *filledblocks, *heaptopptr, gccurr_heaptop, false);
2138 BAMBOO_DEBUGPRINT(0xe108);
2139 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2141 // finish compacting
2142 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2143 *filledblocks, *heaptopptr, 0, false);
2145 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
2147 if(orig->ptr < gcmarkedptrbound) {
2149 BAMBOO_DEBUGPRINT(0xe109);
2151 // still have unpacked obj
2160 BAMBOO_DEBUGPRINT(0xe10a);
2163 to->ptr = gcmovestartaddr;
2164 to->numblocks = gcblock2fill - 1;
2165 to->bound = (to->numblocks==0) ?
2166 BAMBOO_SMEM_SIZE_L :
2167 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2168 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2169 to->offset = to->ptr - to->base;
2170 to->top = (to->numblocks==0) ?
2171 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2173 to->offset = BAMBOO_CACHE_LINE_SIZE;
2174 to->ptr += to->offset; // for header
2175 to->top += to->offset;
2176 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2177 *localcompact = true;
2179 *localcompact = false;
2184 BAMBOO_DEBUGPRINT(0xe10b);
2187 } // void compacthelper()
2189 inline void compact() {
2190 if(COMPACTPHASE != gcphase) {
2191 BAMBOO_EXIT(0xb102);
2194 // initialize pointers for comapcting
2195 struct moveHelper * orig =
2196 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2197 struct moveHelper * to =
2198 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2200 if(!initOrig_Dst(orig, to)) {
2201 // no available data to compact
2202 // send compact finish msg to STARTUP core
2204 BAMBOO_DEBUGPRINT(0xe001);
2205 BAMBOO_DEBUGPRINT_REG(to->base);
2207 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2208 0, to->base, 0, false);
2214 int filledblocks = 0;
2215 INTPTR heaptopptr = 0;
2216 bool localcompact = true;
2217 compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
2223 // if return NULL, means
2224 // 1. objptr is NULL
2225 // 2. objptr is not a shared obj
2226 // in these cases, remain the original value is OK
2227 inline void * flushObj(void * objptr) {
2229 BAMBOO_DEBUGPRINT(0xe401);
2231 if(objptr == NULL) {
2234 void * dstptr = NULL;
2235 if(ISSHAREDOBJ(objptr)) {
2237 BAMBOO_DEBUGPRINT(0xe402);
2238 BAMBOO_DEBUGPRINT_REG(objptr);
2240 // a shared obj ptr, change to new address
2241 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2243 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2245 //dstptr = mgchashSearch(objptr);
2246 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2248 flushstalltime += BAMBOO_GET_EXE_TIME()-ttime;
2250 //MGCHashget(gcpointertbl, objptr, &dstptr);
2251 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2253 BAMBOO_DEBUGPRINT_REG(dstptr);
2256 if(NULL == dstptr) {
2259 BAMBOO_DEBUGPRINT(0xe403);
2260 BAMBOO_DEBUGPRINT_REG(objptr);
2261 BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
2263 if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) {
2264 // error! the obj is right on this core, but cannot find it
2265 BAMBOO_DEBUGPRINT_REG(objptr);
2266 BAMBOO_EXIT(0xb103);
2267 // assume that the obj has not been moved, use the original address
2270 int hostc = hostcore(objptr);
2272 unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
2274 // check the corresponsing sharedptbl
2275 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2276 //struct GCSharedHash * sptbl = gcrpointertbls[hostcore(objptr)];
2277 mgcsharedhashtbl_t * sptbl = gcrpointertbls[hostc];
2279 //GCSharedHashget(sptbl, (int)objptr, &dstptr);
2280 dstptr = mgcsharedhashSearch(sptbl, (int)objptr);
2281 if(dstptr != NULL) {
2282 RuntimeHashadd_I(gcpointertbl, (int)objptr, (int)dstptr);
2285 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2287 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
2290 if(dstptr == NULL) {
2291 // still can not get the mapping info,
2292 // send msg to host core for the mapping info
2293 gcobj2map = (int)objptr;
2298 //num_mapinforequest++;
2299 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2302 //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
2304 // the first time require the mapping, send msg to the hostcore
2305 // for the mapping info
2306 send_msg_3(hostc, GCMAPREQUEST, (int)objptr,
2307 BAMBOO_NUM_OF_CORE, false);
2314 //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
2318 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2320 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2321 //dstptr = mgchashSearch(objptr);
2322 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2323 //MGCHashget(gcpointertbl, objptr, &dstptr);
2324 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2325 } // if(dstptr == NULL)
2326 } // if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) else ...
2328 BAMBOO_DEBUGPRINT_REG(dstptr);
2330 } // if(NULL == dstptr)
2331 } // if(ISSHAREDOBJ(objptr))
2332 // if not a shared obj, return NULL to indicate no need to flush
2334 BAMBOO_DEBUGPRINT(0xe404);
2337 } // void flushObj(void * objptr)
2339 inline void flushRuntimeObj(struct garbagelist * stackptr) {
2341 // flush current stack
2342 while(stackptr!=NULL) {
2343 for(i=0; i<stackptr->size; i++) {
2344 if(stackptr->array[i] != NULL) {
2345 void * dst = flushObj(stackptr->array[i]);
2347 stackptr->array[i] = dst;
2351 stackptr=stackptr->next;
2355 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
2356 for(i=0; i<NUMCLASSES; i++) {
2357 struct parameterwrapper ** queues =
2358 objectqueues[BAMBOO_NUM_OF_CORE][i];
2359 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
2360 for(j = 0; j < length; ++j) {
2361 struct parameterwrapper * parameter = queues[j];
2362 struct ObjectHash * set=parameter->objectset;
2363 struct ObjectNode * ptr=set->listhead;
2365 void * dst = flushObj((void *)ptr->key);
2371 ObjectHashrehash(set);
2376 // flush current task descriptor
2377 if(currtpd != NULL) {
2378 for(i=0; i<currtpd->numParameters; i++) {
2379 void * dst = flushObj(currtpd->parameterArray[i]);
2381 currtpd->parameterArray[i] = dst;
2386 // flush active tasks
2387 if(activetasks != NULL) {
2388 struct genpointerlist * ptr=activetasks->list;
2390 struct taskparamdescriptor *tpd=ptr->src;
2392 for(i=0; i<tpd->numParameters; i++) {
2393 void * dst = flushObj(tpd->parameterArray[i]);
2395 tpd->parameterArray[i] = dst;
2400 genrehash(activetasks);
2403 // flush cached transferred obj
2404 struct QueueItem * tmpobjptr = getHead(&objqueue);
2405 while(tmpobjptr != NULL) {
2406 struct transObjInfo * objInfo =
2407 (struct transObjInfo *)(tmpobjptr->objectptr);
2408 void * dst = flushObj(objInfo->objptr);
2410 objInfo->objptr = dst;
2412 tmpobjptr = getNextQueueItem(tmpobjptr);
2415 // flush cached objs to be transferred
2416 struct QueueItem * item = getHead(totransobjqueue);
2417 while(item != NULL) {
2418 struct transObjInfo * totransobj =
2419 (struct transObjInfo *)(item->objectptr);
2420 void * dst = flushObj(totransobj->objptr);
2422 totransobj->objptr = dst;
2424 item = getNextQueueItem(item);
2425 } // while(item != NULL)
2427 // enqueue lock related info
2428 for(i = 0; i < runtime_locklen; ++i) {
2429 void * dst = flushObj(runtime_locks[i].redirectlock);
2431 runtime_locks[i].redirectlock = (int)dst;
2433 if(runtime_locks[i].value != NULL) {
2434 void * dst=flushObj(runtime_locks[i].value);
2436 runtime_locks[i].value = (int)dst;
2441 } // void flushRuntimeObj(struct garbagelist * stackptr)
2443 inline void transmappinginfo() {
2444 // inform the other cores the mapping info they need
2445 /*struct RuntimeIterator* it_pointertbl =
2446 RuntimeHashcreateiterator(gcpointertbl);
2447 while(RunhasNext(it_pointertbl)) {
2448 int obj = Runkey(it_pointertbl);
2449 struct nodemappinginfo * info =
2450 (struct nodemappinginfo *)Runnext(it_pointertbl);
2451 int newptr = (int)info->ptr;
2452 struct requestcoreinfo * coreinfo = info->cores;
2454 // send the mapping info to all requested cores
2455 while(coreinfo != NULL) {
2456 struct requestcoreinfo * tmp = coreinfo;
2457 coreinfo = coreinfo->next;
2458 send_msg_3(tmp->core, GCMAPINFO, obj, newptr, false);
2459 RUNFREE(tmp); // release the node
2462 /* int core = (BAMBOO_NUM_OF_CORE + 1) % NUMCORESACTIVE;
2463 for(int i = 0; i < NUMCORESACTIVE - 1; i++) {
2464 for(int j = 1; j < gcmappingtbl[core][0]+1; j++) {
2465 int obj = gcmappingtbl[core][j];
2467 RuntimeHashget(gcpointertbl, obj, &newptr);
2468 send_msg_3(core, GCMAPINFO, obj, newptr, false);
2470 //tprintf("send mapping %x -> %x, %x \n", (int)obj, (int)newptr, i);
2473 //tprintf("send mapping to core %d \n", core);
2474 core = (core + 1) % NUMCORESACTIVE;
2478 // broadcast the sharedptbl pointer
2479 for(int i = 0; i < NUMCORESACTIVE; i++) {
2480 if(i != BAMBOO_NUM_OF_CORE) {
2481 send_msg_3(i, GCMAPTBL, gcsharedptbl, BAMBOO_NUM_OF_CORE, false);
2486 //BAMBOO_DEBUGPRINT(0xeeee);
2488 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
2489 send_msg_2(STARTUPCORE, GCFINISHMAPINFO, BAMBOO_NUM_OF_CORE, false);
2493 inline void flush(struct garbagelist * stackptr) {
2495 /* TODO if(BAMBOO_NUM_OF_CORE == 0) {
2496 BAMBOO_DEBUGPRINT(0xcccc);
2497 BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2501 flushRuntimeObj(stackptr);
2503 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2507 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2508 bool hasItems = gc_moreItems_I();
2509 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2515 BAMBOO_DEBUGPRINT(0xe301);
2517 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2518 void * ptr = gc_dequeue_I();
2519 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2520 if(ISSHAREDOBJ(ptr)) {
2521 // should be a local shared obj and should have mapping info
2522 ptr = flushObj(ptr);
2524 BAMBOO_DEBUGPRINT(0xe302);
2525 BAMBOO_DEBUGPRINT_REG(ptr);
2526 BAMBOO_DEBUGPRINT_REG(tptr);
2527 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2530 BAMBOO_EXIT(0xb105);
2532 } // if(ISSHAREDOBJ(ptr))
2533 if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED)) {
2534 int type = ((int *)(ptr))[0];
2535 // scan all pointers in ptr
2536 unsigned INTPTR * pointer;
2537 pointer=pointerarray[type];
2539 BAMBOO_DEBUGPRINT(0xe303);
2540 BAMBOO_DEBUGPRINT_REG(pointer);
2543 /* Array of primitives */
2545 } else if (((INTPTR)pointer)==1) {
2547 BAMBOO_DEBUGPRINT(0xe304);
2549 /* Array of pointers */
2550 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2551 int length=ao->___length___;
2553 for(j=0; j<length; j++) {
2555 BAMBOO_DEBUGPRINT(0xe305);
2558 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2560 BAMBOO_DEBUGPRINT_REG(objptr);
2562 if(objptr != NULL) {
2563 void * dst = flushObj(objptr);
2565 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2571 BAMBOO_DEBUGPRINT(0xe306);
2573 INTPTR size=pointer[0];
2575 for(i=1; i<=size; i++) {
2577 BAMBOO_DEBUGPRINT(0xe307);
2579 unsigned int offset=pointer[i];
2580 void * objptr=*((void **)(((char *)ptr)+offset));
2582 BAMBOO_DEBUGPRINT_REG(objptr);
2584 if(objptr != NULL) {
2585 void * dst = flushObj(objptr);
2587 *((void **)(((char *)ptr)+offset)) = dst;
2590 } // for(i=1; i<=size; i++)
2591 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2592 // restore the mark field, indicating that this obj has been flushed
2593 if(ISSHAREDOBJ(ptr)) {
2594 ((int *)(ptr))[6] = INIT;
2596 } // if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED))
2597 } // while(gc_moreItems())
2599 BAMBOO_DEBUGPRINT(0xe308);
2602 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2605 // TODO bug here: the startup core contains all lobjs' info, thus all the
2606 // lobjs are flushed in sequence.
2608 while(gc_lobjmoreItems_I()) {
2610 BAMBOO_DEBUGPRINT(0xe309);
2612 void * ptr = gc_lobjdequeue_I(NULL, NULL);
2613 ptr = flushObj(ptr);
2615 BAMBOO_DEBUGPRINT(0xe30a);
2616 BAMBOO_DEBUGPRINT_REG(ptr);
2617 BAMBOO_DEBUGPRINT_REG(tptr);
2618 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2623 if(((int *)(ptr))[6] == COMPACTED) {
2624 int type = ((int *)(ptr))[0];
2625 // scan all pointers in ptr
2626 unsigned INTPTR * pointer;
2627 pointer=pointerarray[type];
2629 BAMBOO_DEBUGPRINT(0xe30b);
2630 BAMBOO_DEBUGPRINT_REG(pointer);
2633 /* Array of primitives */
2635 } else if (((INTPTR)pointer)==1) {
2637 BAMBOO_DEBUGPRINT(0xe30c);
2639 /* Array of pointers */
2640 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2641 int length=ao->___length___;
2643 for(j=0; j<length; j++) {
2645 BAMBOO_DEBUGPRINT(0xe30d);
2648 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2650 BAMBOO_DEBUGPRINT_REG(objptr);
2652 if(objptr != NULL) {
2653 void * dst = flushObj(objptr);
2655 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2661 BAMBOO_DEBUGPRINT(0xe30e);
2663 INTPTR size=pointer[0];
2665 for(i=1; i<=size; i++) {
2667 BAMBOO_DEBUGPRINT(0xe30f);
2669 unsigned int offset=pointer[i];
2670 void * objptr=*((void **)(((char *)ptr)+offset));
2673 BAMBOO_DEBUGPRINT_REG(objptr);
2675 if(objptr != NULL) {
2676 void * dst = flushObj(objptr);
2678 *((void **)(((char *)ptr)+offset)) = dst;
2681 } // for(i=1; i<=size; i++)
2682 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2683 // restore the mark field, indicating that this obj has been flushed
2684 ((int *)(ptr))[6] = INIT;
2685 } // if(((int *)(ptr))[6] == COMPACTED)
2686 } // while(gc_lobjmoreItems())
2688 BAMBOO_DEBUGPRINT(0xe310);
2691 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2694 // send flush finish message to core coordinator
2695 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2696 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2698 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
2702 //if(BAMBOO_NUM_OF_CORE == 0) {
2703 //BAMBOO_DEBUGPRINT(0xffff);
2704 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest);
2705 //BAMBOO_DEBUGPRINT_REG(flushstalltime);
2706 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest_i);
2707 //BAMBOO_DEBUGPRINT_REG(flushstalltime_i);
2709 //BAMBOO_DEBUGPRINT_REG(flushstalltime);
2712 BAMBOO_DEBUGPRINT(0xe311);
2716 inline void gc_collect(struct garbagelist * stackptr) {
2717 // core collector routine
2719 if(INITPHASE == gcphase) {
2723 #ifdef RAWPATH // TODO GC_DEBUG
2724 printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2727 //send init finish msg to core coordinator
2728 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2730 if(MARKPHASE == gcphase) {
2734 #ifdef RAWPATH // TODO GC_DEBUG
2735 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2736 udn_tile_coord_y());
2738 mark(true, stackptr);
2739 #ifdef RAWPATH // TODO GC_DEBUG
2740 printf("(%x,%x) Finish mark phase, start compact phase\n",
2741 udn_tile_coord_x(), udn_tile_coord_y());
2744 #ifdef RAWPATH // TODO GC_DEBUG
2745 printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
2746 udn_tile_coord_y());
2749 if(MAPPHASE == gcphase) {
2753 #ifdef RAWPATH // TODO GC_DEBUG
2754 printf("(%x,%x) Start map phase\n", udn_tile_coord_x(),
2755 udn_tile_coord_y());
2758 #ifdef RAWPATH // TODO GC_DEBUG
2759 printf("(%x,%x) Finish map phase\n", udn_tile_coord_x(),
2760 udn_tile_coord_y());
2763 if(FLUSHPHASE == gcphase) {
2767 #ifdef RAWPATH // TODO GC_DEBUG
2768 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2769 udn_tile_coord_y());
2772 #ifdef RAWPATH // TODO GC_DEBUG
2773 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2774 udn_tile_coord_y());
2778 if(FINISHPHASE == gcphase) {
2782 #ifdef RAWPATH // TODO GC_DEBUG
2783 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2785 } // void gc_collect(struct garbagelist * stackptr)
2787 inline void gc_nocollect(struct garbagelist * stackptr) {
2789 if(INITPHASE == gcphase) {
2793 #ifdef RAWPATH // TODO GC_DEBUG
2794 printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2797 //send init finish msg to core coordinator
2798 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2800 if(MARKPHASE == gcphase) {
2804 #ifdef RAWPATH // TODO GC_DEBUG
2805 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2806 udn_tile_coord_y());
2808 mark(true, stackptr);
2809 #ifdef RAWPATH // TODO GC_DEBUG
2810 printf("(%x,%x) Finish mark phase, wait for flush\n",
2811 udn_tile_coord_x(), udn_tile_coord_y());
2813 // non-gc core collector routine
2815 if(FLUSHPHASE == gcphase) {
2819 #ifdef RAWPATH // TODO GC_DEBUG
2820 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2821 udn_tile_coord_y());
2824 #ifdef RAWPATH // TODO GC_DEBUG
2825 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2826 udn_tile_coord_y());
2830 if(FINISHPHASE == gcphase) {
2834 #ifdef RAWPATH // TODO GC_DEBUG
2835 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2837 } // void gc_collect(struct garbagelist * stackptr)
2839 inline void gc(struct garbagelist * stackptr) {
2842 gcprocessing = false;
2846 // core coordinator routine
2847 if(0 == BAMBOO_NUM_OF_CORE) {
2849 printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
2850 udn_tile_coord_y());
2853 // not ready to do gc
2862 #ifdef RAWPATH // TODO GC_DEBUG
2863 printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
2866 gcprocessing = true;
2867 gcphase = INITPHASE;
2869 waitconfirm = false;
2873 // Note: all cores need to init gc including non-gc cores
2874 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
2875 // send GC init messages to all cores
2876 send_msg_1(i, GCSTARTINIT, false);
2878 bool isfirst = true;
2879 bool allStall = false;
2881 #ifdef RAWPATH // TODO GC_DEBUG
2882 printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
2883 udn_tile_coord_y());
2886 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2888 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2889 if(gc_checkAllCoreStatus_I()) {
2890 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2893 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2898 #ifdef RAWPATH // TODO GC_DEBUG
2899 printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
2900 udn_tile_coord_y());
2902 // all cores have finished compacting
2903 // restore the gcstatus of all cores
2904 // Note: all cores have to do mark including non-gc cores
2905 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
2906 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
2907 gccorestatus[i] = 1;
2908 // send GC start messages to all cores
2909 send_msg_1(i, GCSTART, false);
2912 gcphase = MARKPHASE;
2914 while(MARKPHASE == gcphase) {
2915 mark(isfirst, stackptr);
2922 } // while(MARKPHASE == gcphase)
2923 // send msgs to all cores requiring large objs info
2924 // Note: only need to ask gc cores, non-gc cores do not host any objs
2925 numconfirm = NUMCORES4GC - 1;
2926 for(i = 1; i < NUMCORES4GC; ++i) {
2927 send_msg_1(i, GCLOBJREQUEST, false);
2929 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
2934 } // wait for responses
2935 // check the heaptop
2936 if(gcheaptop < gcmarkedptrbound) {
2937 gcheaptop = gcmarkedptrbound;
2942 /*if(BAMBOO_NUM_OF_CORE == 0) {
2943 BAMBOO_DEBUGPRINT(0xeeee);
2944 BAMBOO_DEBUGPRINT_REG(num_markrequest);
2945 BAMBOO_DEBUGPRINT_REG(marktime);
2948 #ifdef RAWPATH // TODO GC_DEBUG
2949 printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
2950 udn_tile_coord_y());
2953 // cache all large objs
2955 // no enough space to cache large objs
2956 BAMBOO_EXIT(0xb107);
2958 // predict number of blocks to fill for each core
2960 int numpbc = loadbalance(&tmpheaptop);
2962 numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
2963 #ifdef RAWPATH // TODO GC_DEBUG
2964 printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
2965 udn_tile_coord_y());
2968 //int tmptopptr = 0;
2969 //BASEPTR(gctopcore, 0, &tmptopptr);
2971 //tmptopptr = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2972 tmpheaptop = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2974 BAMBOO_DEBUGPRINT(0xabab);
2975 BAMBOO_DEBUGPRINT_REG(tmptopptr);
2977 for(i = 0; i < NUMCORES4GC; ++i) {
2979 BASEPTR(i, numpbc, &tmpcoreptr);
2980 //send start compact messages to all cores
2981 //TODO bug here, do not know if the direction is positive or negtive?
2982 if (tmpcoreptr < tmpheaptop /*tmptopptr*/) {
2983 gcstopblock[i] = numpbc + 1;
2984 if(i != STARTUPCORE) {
2985 send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
2987 gcblock2fill = numpbc+1;
2988 } // if(i != STARTUPCORE)
2990 gcstopblock[i] = numpbc;
2991 if(i != STARTUPCORE) {
2992 send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
2994 gcblock2fill = numpbc;
2995 } // if(i != STARTUPCORE)
2998 BAMBOO_DEBUGPRINT(0xf000+i);
2999 BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
3000 BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
3002 // init some data strutures for compact phase
3004 gcfilledblocks[i] = 0;
3005 gcrequiredmems[i] = 0;
3013 bool finalcompact = false;
3014 // initialize pointers for comapcting
3015 struct moveHelper * orig =
3016 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3017 struct moveHelper * to =
3018 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3019 initOrig_Dst(orig, to);
3020 int filledblocks = 0;
3021 INTPTR heaptopptr = 0;
3022 bool finishcompact = false;
3023 bool iscontinue = true;
3024 bool localcompact = true;
3025 while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
3026 if((!finishcompact) && iscontinue) {
3028 BAMBOO_DEBUGPRINT(0xe001);
3029 BAMBOO_DEBUGPRINT_REG(numpbc);
3030 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3032 finishcompact = compacthelper(orig, to, &filledblocks,
3033 &heaptopptr, &localcompact);
3035 BAMBOO_DEBUGPRINT(0xe002);
3036 BAMBOO_DEBUGPRINT_REG(finishcompact);
3037 BAMBOO_DEBUGPRINT_REG(gctomove);
3038 BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
3039 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
3040 BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
3044 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3045 if(gc_checkCoreStatus_I()) {
3046 // all cores have finished compacting
3047 // restore the gcstatus of all cores
3048 for(i = 0; i < NUMCORES4GC; ++i) {
3049 gccorestatus[i] = 1;
3051 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3054 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3055 // check if there are spare mem for pending move requires
3056 if(COMPACTPHASE == gcphase) {
3058 BAMBOO_DEBUGPRINT(0xe003);
3060 resolvePendingMoveRequest();
3062 BAMBOO_DEBUGPRINT_REG(gctomove);
3066 BAMBOO_DEBUGPRINT(0xe004);
3070 } // if(gc_checkCoreStatus_I()) else ...
3074 BAMBOO_DEBUGPRINT(0xe005);
3075 BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
3076 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3077 BAMBOO_DEBUGPRINT_REG(gctomove);
3079 to->ptr = gcmovestartaddr;
3080 to->numblocks = gcblock2fill - 1;
3081 to->bound = (to->numblocks==0) ?
3082 BAMBOO_SMEM_SIZE_L :
3083 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
3084 BASEPTR(gcdstcore, to->numblocks, &(to->base));
3085 to->offset = to->ptr - to->base;
3086 to->top = (to->numblocks==0) ?
3087 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
3089 to->offset = BAMBOO_CACHE_LINE_SIZE;
3090 to->ptr += to->offset; // for header
3091 to->top += to->offset;
3092 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
3093 localcompact = true;
3095 localcompact = false;
3099 } else if(!finishcompact) {
3104 } // while(COMPACTPHASE == gcphase)
3108 #ifdef RAWPATH // TODO GC_DEBUG
3109 printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
3110 udn_tile_coord_y());
3115 #ifdef RAWPATH // TODO GC_DEBUG
3116 printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
3117 udn_tile_coord_y());
3125 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3126 // Note: all cores should flush their runtime data including non-gc
3128 for(i = 1; i < NUMCORES4GC; ++i) {
3129 // send start flush messages to all cores
3130 gccorestatus[i] = 1;
3131 send_msg_1(i, GCSTARTMAPINFO, false);
3136 #ifdef RAWPATH // TODO GC_DEBUG
3137 printf("(%x,%x) Start map phase \n", udn_tile_coord_x(),
3138 udn_tile_coord_y());
3142 #ifdef RAWPATH // TODO GC_DEBUG
3143 printf("(%x,%x) Finish map phase \n", udn_tile_coord_x(),
3144 udn_tile_coord_y());
3146 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3147 while(MAPPHASE == gcphase) {
3148 // check the status of all cores
3149 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3150 if(gc_checkCoreStatus_I()) {
3151 // all cores have finished sending mapping info
3152 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3155 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3156 } // while(MAPPHASE == gcphase)
3158 gcphase = FLUSHPHASE;
3159 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3160 // Note: all cores should flush their runtime data including non-gc
3162 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3163 // send start flush messages to all cores
3164 gccorestatus[i] = 1;
3165 send_msg_1(i, GCSTARTFLUSH, false);
3170 #ifdef RAWPATH // TODO GC_DEBUG
3171 printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
3172 udn_tile_coord_y());
3176 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3177 while(FLUSHPHASE == gcphase) {
3178 // check the status of all cores
3179 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3180 if(gc_checkAllCoreStatus_I()) {
3181 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3184 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3185 } // while(FLUSHPHASE == gcphase)
3186 gcphase = FINISHPHASE;
3188 // invalidate all shared mem pointers
3189 // put it here as it takes time to inform all the other cores to
3190 // finish gc and it might cause problem when some core resumes
3191 // mutator earlier than the other cores
3192 bamboo_cur_msp = NULL;
3193 bamboo_smem_size = 0;
3195 gcprocessing = false;
3200 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3201 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3202 // send gc finish messages to all cores
3203 send_msg_1(i, GCFINISH, false);
3204 gccorestatus[i] = 1;
3206 #ifdef RAWPATH // TODO GC_DEBUG
3207 printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
3208 udn_tile_coord_y());
3212 /*extern int gc_num_search;
3213 extern int gc_num_collision;
3214 tprintf("Average collision: %d \n", gc_num_collision/gc_num_search);*/
3215 } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
3216 gcprocessing = true;
3217 gc_collect(stackptr);
3219 // invalidate all shared mem pointers
3220 bamboo_cur_msp = NULL;
3221 bamboo_smem_size = 0;
3224 gcprocessing = false;
3226 // not a gc core, should wait for gcfinish msg
3227 gcprocessing = true;
3228 gc_nocollect(stackptr);
3230 // invalidate all shared mem pointers
3231 bamboo_cur_msp = NULL;
3232 bamboo_smem_size = 0;
3235 gcprocessing = false;
3237 } // void gc(struct garbagelist * stackptr)
3240 inline void gc_profileStart(void) {
3241 if(!gc_infoOverflow) {
3242 GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
3243 gc_infoArray[gc_infoIndex] = gcInfo;
3245 gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
3249 inline void gc_profileItem(void) {
3250 if(!gc_infoOverflow) {
3251 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3252 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3256 inline void gc_profileEnd(void) {
3257 if(!gc_infoOverflow) {
3258 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3259 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3261 if(gc_infoIndex == GCINFOLENGTH) {
3262 gc_infoOverflow = true;
3263 //taskInfoIndex = 0;
3268 // output the profiling data
3269 void gc_outputProfileData() {
3272 unsigned long long totalgc = 0;
3274 //printf("Start Time, End Time, Duration\n");
3275 // output task related info
3276 for(i = 0; i < gc_infoIndex; i++) {
3277 GCInfo * gcInfo = gc_infoArray[i];
3278 unsigned long long tmp = 0;
3279 for(j = 0; j < gcInfo->index; j++) {
3280 printf("%lld(%lld), ", gcInfo->time[j], (gcInfo->time[j]-tmp));
3281 tmp = gcInfo->time[j];
3283 tmp = (tmp-gcInfo->time[0]);
3284 printf(" ++ %lld \n", tmp);
3288 if(gc_infoOverflow) {
3289 printf("Caution: gc info overflow!\n");
3292 printf("\n\n total gc time: %lld \n", totalgc);
3296 unsigned long long totalgc = 0;
3298 BAMBOO_DEBUGPRINT(0xdddd);
3299 // output task related info
3300 for(i= 0; i < gc_infoIndex; i++) {
3301 GCInfo * gcInfo = gc_infoArray[i];
3302 unsigned long long tmp = 0;
3303 BAMBOO_DEBUGPRINT(0xddda);
3304 for(j = 0; j < gcInfo->index; j++) {
3305 BAMBOO_DEBUGPRINT(gcInfo->time[j]);
3306 BAMBOO_DEBUGPRINT(gcInfo->time[j]-tmp);
3307 BAMBOO_DEBUGPRINT(0xdddb);
3308 tmp = gcInfo->time[j];
3310 tmp = (tmp-gcInfo->time[0]);
3311 BAMBOO_DEBUGPRINT_REG(tmp);
3312 BAMBOO_DEBUGPRINT(0xdddc);
3315 BAMBOO_DEBUGPRINT(0xdddd);
3316 BAMBOO_DEBUGPRINT_REG(totalgc);
3318 if(gc_infoOverflow) {
3319 BAMBOO_DEBUGPRINT(0xefee);
3322 BAMBOO_DEBUGPRINT(0xeeee);
3325 #endif // #ifdef GC_PROFILE