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"
10 // TODO for profiling the flush phase
12 int num_mapinforequest;
14 unsigned long long marktime;
18 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
19 extern int numqueues[][NUMCLASSES];
21 extern struct genhashtable * activetasks;
22 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
23 extern struct taskparamdescriptor *currtpd;
25 extern struct LockValue runtime_locks[MAXTASKPARAMS];
26 extern int runtime_locklen;
30 struct pointerblock *next;
33 struct pointerblock *gchead=NULL;
35 struct pointerblock *gctail=NULL;
37 struct pointerblock *gctail2=NULL;
39 struct pointerblock *gcspare=NULL;
41 #define NUMLOBJPTRS 20
43 struct lobjpointerblock {
44 void * lobjs[NUMLOBJPTRS];
45 //void * dsts[NUMLOBJPTRS];
46 int lengths[NUMLOBJPTRS];
47 //void * origs[NUMLOBJPTRS];
48 int hosts[NUMLOBJPTRS];
49 struct lobjpointerblock *next;
50 struct lobjpointerblock *prev;
53 struct lobjpointerblock *gclobjhead=NULL;
54 int gclobjheadindex=0;
55 struct lobjpointerblock *gclobjtail=NULL;
56 int gclobjtailindex=0;
57 struct lobjpointerblock *gclobjtail2=NULL;
58 int gclobjtailindex2=0;
59 struct lobjpointerblock *gclobjspare=NULL;
62 // dump whole mem in blocks
63 inline void dumpSMem() {
71 printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
73 // reserved blocks for sblocktbl
74 printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
76 for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
77 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",
78 udn_tile_coord_x(), udn_tile_coord_y(),
79 *((int *)(i)), *((int *)(i + 4)),
80 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
81 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
82 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
83 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
84 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
85 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
86 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
88 sblock = gcreservedsb;
89 bool advanceblock = false;
91 for(i=gcbaseva; i<BAMBOO_BASE_VA+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
93 // computing sblock # and block #, core coordinate (x,y) also
94 if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
96 if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
97 if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
109 coren = gc_block2core[block%(NUMCORES4GC*2)];
111 // compute core coordinate
112 BAMBOO_COORDS(coren, &x, &y);
113 printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
114 udn_tile_coord_x(), udn_tile_coord_y(),
115 block, sblock++, x, y,
116 (sblock-1)*(BAMBOO_SMEM_SIZE)+BAMBOO_BASE_VA);
119 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",
120 udn_tile_coord_x(), udn_tile_coord_y(),
121 *((int *)(i)), *((int *)(i + 4)),
122 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
123 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
124 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
125 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
126 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
127 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
128 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
130 printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
134 // should be invoked with interruption closed
135 inline void gc_enqueue_I(void *ptr) {
137 BAMBOO_DEBUGPRINT(0xe601);
138 BAMBOO_DEBUGPRINT_REG(ptr);
140 if (gcheadindex==NUMPTRS) {
141 struct pointerblock * tmp;
146 tmp=RUNMALLOC_I(sizeof(struct pointerblock));
147 } // if (gcspare!=NULL)
151 } // if (gcheadindex==NUMPTRS)
152 gchead->ptrs[gcheadindex++]=ptr;
154 BAMBOO_DEBUGPRINT(0xe602);
156 } // void gc_enqueue_I(void *ptr)
158 // dequeue and destroy the queue
159 inline void * gc_dequeue_I() {
160 if (gctailindex==NUMPTRS) {
161 struct pointerblock *tmp=gctail;
168 } // if (gcspare!=NULL)
169 } // if (gctailindex==NUMPTRS)
170 return gctail->ptrs[gctailindex++];
171 } // void * gc_dequeue()
173 // dequeue and do not destroy the queue
174 inline void * gc_dequeue2_I() {
175 if (gctailindex2==NUMPTRS) {
176 struct pointerblock *tmp=gctail2;
177 gctail2=gctail2->next;
179 } // if (gctailindex2==NUMPTRS)
180 return gctail2->ptrs[gctailindex2++];
181 } // void * gc_dequeue2()
183 inline int gc_moreItems_I() {
184 if ((gchead==gctail)&&(gctailindex==gcheadindex))
187 } // int gc_moreItems()
189 inline int gc_moreItems2_I() {
190 if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
193 } // int gc_moreItems2()
195 // should be invoked with interruption closed
196 // enqueue a large obj: start addr & length
197 inline void gc_lobjenqueue_I(void *ptr,
201 BAMBOO_DEBUGPRINT(0xe901);
203 if (gclobjheadindex==NUMLOBJPTRS) {
204 struct lobjpointerblock * tmp;
205 if (gclobjspare!=NULL) {
209 tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
210 } // if (gclobjspare!=NULL)
211 gclobjhead->next=tmp;
212 tmp->prev = gclobjhead;
215 } // if (gclobjheadindex==NUMLOBJPTRS)
216 gclobjhead->lobjs[gclobjheadindex]=ptr;
217 gclobjhead->lengths[gclobjheadindex]=length;
218 gclobjhead->hosts[gclobjheadindex++]=host;
220 BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
221 BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
222 BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
224 } // void gc_lobjenqueue_I(void *ptr...)
226 // dequeue and destroy the queue
227 inline void * gc_lobjdequeue_I(int * length,
229 if (gclobjtailindex==NUMLOBJPTRS) {
230 struct lobjpointerblock *tmp=gclobjtail;
231 gclobjtail=gclobjtail->next;
233 gclobjtail->prev = NULL;
234 if (gclobjspare!=NULL) {
240 } // if (gclobjspare!=NULL)
241 } // if (gclobjtailindex==NUMLOBJPTRS)
243 *length = gclobjtail->lengths[gclobjtailindex];
246 *host = (int)(gclobjtail->hosts[gclobjtailindex]);
248 return gclobjtail->lobjs[gclobjtailindex++];
249 } // void * gc_lobjdequeue()
251 inline int gc_lobjmoreItems_I() {
252 if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
255 } // int gc_lobjmoreItems()
257 // dequeue and don't destroy the queue
258 inline void gc_lobjdequeue2_I() {
259 if (gclobjtailindex2==NUMLOBJPTRS) {
260 gclobjtail2=gclobjtail2->next;
264 } // if (gclobjtailindex2==NUMLOBJPTRS)
265 } // void * gc_lobjdequeue2()
267 inline int gc_lobjmoreItems2_I() {
268 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
271 } // int gc_lobjmoreItems2()
273 // 'reversly' dequeue and don't destroy the queue
274 inline void gc_lobjdequeue3_I() {
275 if (gclobjtailindex2==0) {
276 gclobjtail2=gclobjtail2->prev;
277 gclobjtailindex2=NUMLOBJPTRS-1;
280 } // if (gclobjtailindex2==NUMLOBJPTRS)
281 } // void * gc_lobjdequeue3()
283 inline int gc_lobjmoreItems3_I() {
284 if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
287 } // int gc_lobjmoreItems3()
289 inline void gc_lobjqueueinit4_I() {
290 gclobjtail2 = gclobjtail;
291 gclobjtailindex2 = gclobjtailindex;
292 } // void gc_lobjqueueinit2()
294 inline void * gc_lobjdequeue4_I(int * length,
296 if (gclobjtailindex2==NUMLOBJPTRS) {
297 gclobjtail2=gclobjtail2->next;
299 } // if (gclobjtailindex==NUMLOBJPTRS)
301 *length = gclobjtail2->lengths[gclobjtailindex2];
304 *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
306 return gclobjtail2->lobjs[gclobjtailindex2++];
307 } // void * gc_lobjdequeue()
309 inline int gc_lobjmoreItems4_I() {
310 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
313 } // int gc_lobjmoreItems(
315 INTPTR gccurr_heapbound = 0;
317 inline void gettype_size(void * ptr,
320 int type = ((int *)ptr)[0];
322 if(type < NUMCLASSES) {
324 size = classsize[type];
327 struct ArrayObject *ao=(struct ArrayObject *)ptr;
328 int elementsize=classsize[type];
329 int length=ao->___length___;
330 size=sizeof(struct ArrayObject)+length*elementsize;
331 } // if(type < NUMCLASSES)
336 inline bool isLarge(void * ptr,
340 BAMBOO_DEBUGPRINT(0xe701);
341 BAMBOO_DEBUGPRINT_REG(ptr);
343 // check if a pointer is referring to a large object
344 gettype_size(ptr, ttype, tsize);
346 BAMBOO_DEBUGPRINT(*tsize);
348 int bound = (BAMBOO_SMEM_SIZE);
349 if(((int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
350 bound = (BAMBOO_SMEM_SIZE_L);
352 if((((int)ptr-gcbaseva)%(bound))==0) {
353 // ptr is a start of a block
355 BAMBOO_DEBUGPRINT(0xe702);
356 BAMBOO_DEBUGPRINT(1);
360 if((bound-(((int)ptr-gcbaseva)%bound)) < (*tsize)) {
361 // it acrosses the boundary of current block
363 BAMBOO_DEBUGPRINT(0xe703);
364 BAMBOO_DEBUGPRINT(1);
369 BAMBOO_DEBUGPRINT(0);
372 } // bool isLarge(void * ptr, int * ttype, int * tsize)
374 inline int hostcore(void * ptr) {
375 // check the host core of ptr
377 RESIDECORE(ptr, &host);
379 BAMBOO_DEBUGPRINT(0xedd0);
380 BAMBOO_DEBUGPRINT_REG(ptr);
381 BAMBOO_DEBUGPRINT_REG(host);
384 } // int hostcore(void * ptr)
386 inline bool isLocal(void * ptr) {
387 // check if a pointer is in shared heap on this core
388 return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
389 } // bool isLocal(void * ptr)
391 inline bool gc_checkCoreStatus_I() {
392 bool allStall = true;
393 for(int i = 0; i < NUMCORES4GC; ++i) {
394 if(gccorestatus[i] != 0) {
397 } // if(gccorestatus[i] != 0)
398 } // for(i = 0; i < NUMCORES4GC; ++i)
402 inline bool gc_checkAllCoreStatus_I() {
403 bool allStall = true;
404 for(int i = 0; i < NUMCORESACTIVE; ++i) {
405 if(gccorestatus[i] != 0) {
408 } // if(gccorestatus[i] != 0)
409 } // for(i = 0; i < NUMCORESACTIVE; ++i)
413 inline void checkMarkStatue() {
415 BAMBOO_DEBUGPRINT(0xee01);
419 (waitconfirm && (numconfirm == 0))) {
421 BAMBOO_DEBUGPRINT(0xee02);
423 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
424 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
425 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
426 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
427 // check the status of all cores
428 bool allStall = gc_checkAllCoreStatus_I();
430 BAMBOO_DEBUGPRINT(0xee03);
434 BAMBOO_DEBUGPRINT(0xee04);
439 BAMBOO_DEBUGPRINT(0xee05);
441 // the first time found all cores stall
442 // send out status confirm msg to all other cores
443 // reset the corestatus array too
444 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
446 numconfirm = NUMCORESACTIVE - 1;
447 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
448 for(i = 1; i < NUMCORESACTIVE; ++i) {
450 // send mark phase finish confirm request msg to core i
451 send_msg_1(i, GCMARKCONFIRM, false);
452 } // for(i = 1; i < NUMCORESACTIVE; ++i)
454 // check if the sum of send objs and receive obj are the same
455 // yes->check if the info is the latest; no->go on executing
457 for(i = 0; i < NUMCORESACTIVE; ++i) {
458 sumsendobj += gcnumsendobjs[i];
459 } // for(i = 0; i < NUMCORESACTIVE; ++i)
461 BAMBOO_DEBUGPRINT(0xee06);
462 BAMBOO_DEBUGPRINT_REG(sumsendobj);
464 for(i = 0; i < NUMCORESACTIVE; ++i) {
465 sumsendobj -= gcnumreceiveobjs[i];
466 } // for(i = 0; i < NUMCORESACTIVE; ++i)
468 BAMBOO_DEBUGPRINT(0xee07);
469 BAMBOO_DEBUGPRINT_REG(sumsendobj);
471 if(0 == sumsendobj) {
473 BAMBOO_DEBUGPRINT(0xee08);
475 // all the core status info are the latest
477 gcphase = COMPACTPHASE;
478 // restore the gcstatus for all cores
479 for(i = 0; i < NUMCORESACTIVE; ++i) {
481 } // for(i = 0; i < NUMCORESACTIVE; ++i)
483 // wait for a while and ask for confirm again
488 } // if(0 == sumsendobj) else ...
489 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
490 } // if(!gcwaitconfirm) else()
492 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
494 } // if((!waitconfirm)...
496 BAMBOO_DEBUGPRINT(0xee0a);
498 } // void checkMarkStatue()
500 inline bool preGC() {
501 // preparation for gc
502 // make sure to clear all incoming msgs espacially transfer obj msgs
504 BAMBOO_DEBUGPRINT(0xec01);
508 (waitconfirm && (numconfirm == 0))) {
509 // send out status confirm msgs to all cores to check if there are
510 // transfer obj msgs on-the-fly
512 numconfirm = NUMCORESACTIVE - 1;
513 for(i = 1; i < NUMCORESACTIVE; ++i) {
515 // send status confirm msg to core i
516 send_msg_1(i, STATUSCONFIRM, false);
517 } // for(i = 1; i < NUMCORESACTIVE; ++i)
520 BAMBOO_DEBUGPRINT(0xec02);
523 if(numconfirm == 0) {
526 } // wait for confirmations
530 BAMBOO_DEBUGPRINT(0xec03);
532 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
533 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
536 BAMBOO_DEBUGPRINT(0xec04);
538 for(i = 0; i < NUMCORESACTIVE; ++i) {
539 sumsendobj += numsendobjs[i];
541 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
543 } // for(i = 1; i < NUMCORESACTIVE; ++i)
545 BAMBOO_DEBUGPRINT(0xec05);
546 BAMBOO_DEBUGPRINT_REG(sumsendobj);
548 for(i = 0; i < NUMCORESACTIVE; ++i) {
549 sumsendobj -= numreceiveobjs[i];
551 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
553 } // for(i = 1; i < NUMCORESACTIVE; ++i)
555 BAMBOO_DEBUGPRINT(0xec06);
556 BAMBOO_DEBUGPRINT_REG(sumsendobj);
558 if(0 == sumsendobj) {
561 // still have some transfer obj msgs on-the-fly, can not start gc
563 } // if(0 == sumsendobj)
566 BAMBOO_DEBUGPRINT(0xec07);
568 // previously asked for status confirmation and do not have all the
569 // confirmations yet, can not start gc
571 } // if((!waitconfirm) ||
574 inline void initGC() {
576 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
577 for(i = 0; i < NUMCORES4GC; ++i) {
579 gcnumsendobjs[i] = 0;
580 gcnumreceiveobjs[i] = 0;
582 gcrequiredmems[i] = 0;
583 gcfilledblocks[i] = 0;
585 } // for(i = 0; i < NUMCORES4GC; ++i)
586 for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
588 gcnumsendobjs[i] = 0;
589 gcnumreceiveobjs[i] = 0;
594 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
595 gcself_numsendobjs = 0;
596 gcself_numreceiveobjs = 0;
597 gcmarkedptrbound = 0;
611 gcheadindex=gctailindex=gctailindex2 = 0;
612 gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
614 gctailindex = gctailindex2 = gcheadindex;
615 gctail = gctail2 = gchead;
618 // initialize the large obj queues
619 if (gclobjhead==NULL) {
622 gclobjtailindex2 = 0;
623 gclobjhead=gclobjtail=gclobjtail2=
624 RUNMALLOC(sizeof(struct lobjpointerblock));
626 gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
627 gclobjtail = gclobjtail2 = gclobjhead;
629 gclobjhead->next = gclobjhead->prev = NULL;
631 freeRuntimeHash(gcpointertbl);
632 gcpointertbl = allocateRuntimeHash(20);
633 //gcpointertbl = allocateMGCHash(20);
636 freeMGCHash(gcforwardobjtbl);
637 gcforwardobjtbl = allocateMGCHash(20, 3);
641 num_mapinforequest = 0;
642 num_mapinforequest_i = 0;
644 flushstalltime_i = 0;
650 // compute load balance for all cores
651 inline int loadbalance(int * heaptop) {
652 // compute load balance
655 // get the total loads
656 int tloads = gcloads[STARTUPCORE];
657 for(i = 1; i < NUMCORES4GC; i++) {
658 tloads += gcloads[i];
660 *heaptop = gcbaseva + tloads;
662 BAMBOO_DEBUGPRINT(0xdddd);
663 BAMBOO_DEBUGPRINT_REG(tloads);
664 BAMBOO_DEBUGPRINT_REG(*heaptop);
667 BLOCKINDEX(*heaptop, &b);
668 int numbpc = b / NUMCORES4GC; // num of blocks per core
670 BAMBOO_DEBUGPRINT_REG(b);
671 BAMBOO_DEBUGPRINT_REG(numbpc);
674 RESIDECORE(heaptop, &gctopcore);
676 BAMBOO_DEBUGPRINT_REG(gctopcore);
679 } // void loadbalance(int * heaptop)
681 inline bool cacheLObjs() {
682 // check the total mem size need for large objs
686 BAMBOO_DEBUGPRINT(0xe801);
688 gclobjtail2 = gclobjtail;
689 gclobjtailindex2 = gclobjtailindex;
693 // compute total mem size required and sort the lobjs in ascending order
694 while(gc_lobjmoreItems2_I()) {
696 tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
697 tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
698 tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
701 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
702 BAMBOO_DEBUGPRINT_REG(tmp_len);
703 BAMBOO_DEBUGPRINT_REG(sumsize);
705 int i = gclobjtailindex2-1;
706 struct lobjpointerblock * tmp_block = gclobjtail2;
707 // find the place to insert
710 if(tmp_block->prev == NULL) {
713 if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
714 tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
715 tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
716 tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
717 tmp_block = tmp_block->prev;
721 } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
723 if(tmp_block->lobjs[i-1] > tmp_lobj) {
724 tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
725 tmp_block->lengths[i] = tmp_block->lengths[i-1];
726 tmp_block->hosts[i] = tmp_block->hosts[i-1];
730 } // if(tmp_block->lobjs[i-1] < tmp_lobj)
731 } // if(i ==0 ) else {}
734 if(i != gclobjtailindex2 - 1) {
735 tmp_block->lobjs[i] = tmp_lobj;
736 tmp_block->lengths[i] = tmp_len;
737 tmp_block->hosts[i] = tmp_host;
739 } // while(gc_lobjmoreItems2())
741 // check if there are enough space to cache these large objs
742 INTPTR dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
743 if(gcheaptop > dst) {
744 // do not have enough room to cache large objs
746 BAMBOO_DEBUGPRINT(0xe802);
747 BAMBOO_DEBUGPRINT_REG(dst);
748 BAMBOO_DEBUGPRINT_REG(gcheaptop);
753 BAMBOO_DEBUGPRINT(0xe803);
754 BAMBOO_DEBUGPRINT_REG(dst);
755 BAMBOO_DEBUGPRINT_REG(gcheaptop);
758 gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
759 // cache the largeObjs to the top of the shared heap
760 //gclobjtail2 = gclobjtail;
761 //gclobjtailindex2 = gclobjtailindex;
762 dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
763 while(gc_lobjmoreItems3_I()) {
765 size = gclobjtail2->lengths[gclobjtailindex2];
766 // set the mark field to , indicating that this obj has been moved
767 // and need to be flushed
768 ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[6] = COMPACTED;
770 if((int)dst < (int)(gclobjtail2->lobjs[gclobjtailindex2])+size) {
771 memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
773 //BAMBOO_WRITE_HINT_CACHE(dst, size);
774 memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
777 BAMBOO_DEBUGPRINT(0x804);
778 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
779 BAMBOO_DEBUGPRINT(dst);
780 BAMBOO_DEBUGPRINT_REG(size);
781 BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
782 BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
786 } // void cacheLObjs()
788 // NOTE: the free mem chunks should be maintained in an ordered linklist
789 // the listtop param always specify current list tail
791 // update the bmmboo_smemtbl to record current shared mem usage
792 void updateSmemTbl(int coren,
795 int bound = BAMBOO_SMEM_SIZE_L;
796 BLOCKINDEX(localtop, <opcore);
797 if(localtop >= (gcbaseva+(BAMBOO_LARGE_SMEM_BOUND))) {
798 bound = BAMBOO_SMEM_SIZE;
800 int load = (localtop-gcbaseva)%bound;
805 toset = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
806 if(toset < ltopcore) {
807 bamboo_smemtbl[toset]=
808 (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
809 } else if(toset == ltopcore) {
810 bamboo_smemtbl[toset] = load;
821 } // void updateSmemTbl(int, int)
823 inline void moveLObjs() {
825 BAMBOO_DEBUGPRINT(0xea01);
827 // zero out the smemtbl
828 BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
829 // find current heap top
830 // flush all gcloads to indicate the real heap top on one core
831 // previous it represents the next available ptr on a core
832 if((gcloads[0] > (gcbaseva+(BAMBOO_SMEM_SIZE_L)))
833 && ((gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
834 // edge of a block, check if this is exactly the heaptop
835 BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
836 gcloads[0]+=(gcfilledblocks[0]>1 ?
837 (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
839 updateSmemTbl(0, gcloads[0]);
841 BAMBOO_DEBUGPRINT(0xea02);
842 BAMBOO_DEBUGPRINT_REG(gcloads[0]);
843 BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
845 for(int i = 1; i < NUMCORES4GC; i++) {
848 BAMBOO_DEBUGPRINT(0xf000+i);
849 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
850 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
852 if((gcfilledblocks[i] > 0)
853 && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
854 // edge of a block, check if this is exactly the heaptop
855 BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
857 +=(gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
860 updateSmemTbl(i, gcloads[i]);
862 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
864 } // for(int i = 1; i < NUMCORES4GC; i++) {
866 // find current heap top
868 // a bug here: when using local allocation, directly move large objects
869 // to the highest free chunk might not be memory efficient
874 for(i = gcnumblock-1; i >= 0; i--) {
875 if(bamboo_smemtbl[i] > 0) {
880 tmpheaptop = gcbaseva;
882 tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
883 (BAMBOO_SMEM_SIZE_L*i) :
884 (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
887 // move large objs from gcheaptop to tmpheaptop
888 // write the header first
889 int tomove = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -gcheaptop;
891 BAMBOO_DEBUGPRINT(0xea03);
892 BAMBOO_DEBUGPRINT_REG(tomove);
893 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
894 BAMBOO_DEBUGPRINT_REG(gcheaptop);
896 // flush the sbstartbl
897 BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
898 (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-gcreservedsb)*sizeof(INTPTR));
900 gcheaptop = tmpheaptop;
902 // check how many blocks it acrosses
903 int remain = tmpheaptop-gcbaseva;
904 int sb = remain/(BAMBOO_SMEM_SIZE) + gcreservedsb; //number of the sblock
905 int b = 0; // number of the block
906 BLOCKINDEX(tmpheaptop, &b);
907 // check the remaining space in this block
908 bound = (BAMBOO_SMEM_SIZE);
909 if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
910 bound = (BAMBOO_SMEM_SIZE_L);
912 remain = bound - remain%bound;
915 BAMBOO_DEBUGPRINT(0xea04);
921 int base = tmpheaptop;
923 remain -= BAMBOO_CACHE_LINE_SIZE;
924 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
925 gc_lobjqueueinit4_I();
926 while(gc_lobjmoreItems4_I()) {
927 ptr = (int)(gc_lobjdequeue4_I(&size, &host));
928 ALIGNSIZE(size, &isize);
930 // this object acrosses blocks
932 // close current block, fill its header
933 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
934 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
935 bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE; // add the size of the header
939 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
940 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
942 remain -= BAMBOO_CACHE_LINE_SIZE;
943 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
944 BLOCKINDEX(tmpheaptop, &b);
945 sb = (tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE) + gcreservedsb;
948 // move the large obj
949 if((int)gcheaptop < (int)(tmpheaptop)+size) {
950 memmove(tmpheaptop, gcheaptop, size);
952 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
953 memcpy(tmpheaptop, gcheaptop, size);
955 // fill the remaining space with -2 padding
956 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
957 // zero out original mem caching the lobj
958 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
960 BAMBOO_DEBUGPRINT(0xea05);
961 BAMBOO_DEBUGPRINT_REG(gcheaptop);
962 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
963 BAMBOO_DEBUGPRINT_REG(size);
964 BAMBOO_DEBUGPRINT_REG(isize);
965 BAMBOO_DEBUGPRINT_REG(base);
968 // cache the mapping info anyway
969 //if(ptr != tmpheaptop) {
970 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
971 //mgchashInsert_I(ptr, tmpheaptop);
972 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
973 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
974 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
977 BAMBOO_DEBUGPRINT(0xcdca);
978 BAMBOO_DEBUGPRINT_REG(ptr);
979 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
981 if(host != BAMBOO_NUM_OF_CORE) {
982 // send the original host core with the mapping info
983 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
985 BAMBOO_DEBUGPRINT(0xcdcb);
986 BAMBOO_DEBUGPRINT_REG(ptr);
987 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
989 } // if(host != BAMBOO_NUM_OF_CORE)
992 // set the gcsbstarttbl and bamboo_smemtbl
993 int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
994 for(int k = 1; k < tmpsbs; k++) {
995 gcsbstarttbl[sb+k] = (INTPTR)(-1);
998 bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
999 BLOCKINDEX(tmpheaptop-1, &tmpsbs);
1000 for(; b < tmpsbs; b++) {
1001 bamboo_smemtbl[b] = bound;
1002 if(b==NUMCORES4GC-1) {
1003 bound = BAMBOO_SMEM_SIZE;
1006 if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
1007 gcsbstarttbl[sb] = (INTPTR)(-1);
1008 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
1009 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1010 bamboo_smemtbl[b] = bound;
1012 gcsbstarttbl[sb] = (INTPTR)(tmpheaptop);
1013 remain = tmpheaptop-gcbaseva;
1014 bamboo_smemtbl[b] = remain%bound;
1015 remain = bound - bamboo_smemtbl[b];
1016 } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
1018 // close current block and fill the header
1019 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1020 *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
1023 if(remain == BAMBOO_CACHE_LINE_SIZE) {
1024 // fill with 0 in case
1025 BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
1027 remain -= BAMBOO_CACHE_LINE_SIZE;
1028 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
1031 // move the large obj
1032 if((int)gcheaptop < (int)(tmpheaptop)+size) {
1033 memmove(tmpheaptop, gcheaptop, size);
1035 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
1036 memcpy(tmpheaptop, gcheaptop, size);
1038 // fill the remaining space with -2 padding
1039 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
1040 // zero out original mem caching the lobj
1041 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
1043 BAMBOO_DEBUGPRINT(0xea06);
1044 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1045 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1046 BAMBOO_DEBUGPRINT_REG(size);
1047 BAMBOO_DEBUGPRINT_REG(isize);
1052 // cache the mapping info anyway
1053 //if(ptr != tmpheaptop) {
1054 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1055 //mgchashInsert_I(ptr, tmpheaptop);
1056 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
1057 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
1058 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1061 BAMBOO_DEBUGPRINT(0xcdcc);
1062 BAMBOO_DEBUGPRINT_REG(ptr);
1063 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1064 BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
1066 if(host != BAMBOO_NUM_OF_CORE) {
1067 // send the original host core with the mapping info
1068 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
1070 BAMBOO_DEBUGPRINT(0xcdcd);
1071 BAMBOO_DEBUGPRINT_REG(ptr);
1072 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1074 } // if(host != BAMBOO_NUM_OF_CORE)
1075 tmpheaptop += isize;
1077 // update bamboo_smemtbl
1078 bamboo_smemtbl[b] += isize;
1079 } // if(remain < isize) else ...
1080 } // while(gc_lobjmoreItems())
1082 // close current block, fill the header
1083 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1084 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
1085 bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE; // add the size of the header
1087 tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
1089 gcheaptop = tmpheaptop;
1091 } // if(tomove == 0)
1094 BAMBOO_DEBUGPRINT(0xea07);
1095 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1098 bamboo_free_block = 0;
1101 tbound = (bamboo_free_block<NUMCORES4GC) ?
1102 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1103 if(bamboo_smemtbl[bamboo_free_block] == tbound) {
1104 bamboo_free_block++;
1106 // the first non-full partition
1111 BAMBOO_DEBUGPRINT(0xea08);
1112 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1114 } // void moveLObjs()
1116 inline void markObj(void * objptr) {
1117 if(objptr == NULL) {
1120 if(ISSHAREDOBJ(objptr)) {
1121 int host = hostcore(objptr);
1122 if(BAMBOO_NUM_OF_CORE == host) {
1124 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1125 if(((int *)objptr)[6] == INIT) {
1126 // this is the first time that this object is discovered,
1127 // set the flag as DISCOVERED
1128 ((int *)objptr)[6] = DISCOVERED;
1129 gc_enqueue_I(objptr);
1131 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1134 BAMBOO_DEBUGPRINT(0xbbbb);
1135 BAMBOO_DEBUGPRINT_REG(host);
1136 BAMBOO_DEBUGPRINT_REG(objptr);
1138 // check if this obj has been forwarded
1139 if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
1141 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
1143 // send a msg to host informing that objptr is active
1144 send_msg_2(host, GCMARKEDOBJ, objptr, false);
1146 marktime += BAMBOO_GET_EXE_TIME() - ttime;
1149 gcself_numsendobjs++;
1150 MGCHashadd(gcforwardobjtbl, (int)objptr);
1154 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1155 gc_enqueue_I(objptr);
1156 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1157 } // if(ISSHAREDOBJ(objptr))
1158 } // void markObj(void * objptr)
1160 // enqueue root objs
1161 inline void tomark(struct garbagelist * stackptr) {
1162 if(MARKPHASE != gcphase) {
1164 BAMBOO_DEBUGPRINT_REG(gcphase);
1166 BAMBOO_EXIT(0xb101);
1168 gcbusystatus = true;
1172 // enqueue current stack
1173 while(stackptr!=NULL) {
1175 BAMBOO_DEBUGPRINT(0xe501);
1176 BAMBOO_DEBUGPRINT_REG(stackptr->size);
1177 BAMBOO_DEBUGPRINT_REG(stackptr->next);
1178 BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
1180 for(i=0; i<stackptr->size; i++) {
1181 if(stackptr->array[i] != NULL) {
1182 markObj(stackptr->array[i]);
1185 stackptr=stackptr->next;
1189 BAMBOO_DEBUGPRINT(0xe503);
1191 // enqueue objectsets
1192 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1193 for(i=0; i<NUMCLASSES; i++) {
1194 struct parameterwrapper ** queues =
1195 objectqueues[BAMBOO_NUM_OF_CORE][i];
1196 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
1197 for(j = 0; j < length; ++j) {
1198 struct parameterwrapper * parameter = queues[j];
1199 struct ObjectHash * set=parameter->objectset;
1200 struct ObjectNode * ptr=set->listhead;
1202 markObj((void *)ptr->key);
1209 // euqueue current task descriptor
1210 if(currtpd != NULL) {
1212 BAMBOO_DEBUGPRINT(0xe504);
1214 for(i=0; i<currtpd->numParameters; i++) {
1215 markObj(currtpd->parameterArray[i]);
1220 BAMBOO_DEBUGPRINT(0xe505);
1222 // euqueue active tasks
1223 if(activetasks != NULL) {
1224 struct genpointerlist * ptr=activetasks->list;
1226 struct taskparamdescriptor *tpd=ptr->src;
1228 for(i=0; i<tpd->numParameters; i++) {
1229 markObj(tpd->parameterArray[i]);
1236 BAMBOO_DEBUGPRINT(0xe506);
1238 // enqueue cached transferred obj
1239 struct QueueItem * tmpobjptr = getHead(&objqueue);
1240 while(tmpobjptr != NULL) {
1241 struct transObjInfo * objInfo =
1242 (struct transObjInfo *)(tmpobjptr->objectptr);
1243 markObj(objInfo->objptr);
1244 tmpobjptr = getNextQueueItem(tmpobjptr);
1248 BAMBOO_DEBUGPRINT(0xe507);
1250 // enqueue cached objs to be transferred
1251 struct QueueItem * item = getHead(totransobjqueue);
1252 while(item != NULL) {
1253 struct transObjInfo * totransobj =
1254 (struct transObjInfo *)(item->objectptr);
1255 markObj(totransobj->objptr);
1256 item = getNextQueueItem(item);
1257 } // while(item != NULL)
1260 BAMBOO_DEBUGPRINT(0xe508);
1262 // enqueue lock related info
1263 for(i = 0; i < runtime_locklen; ++i) {
1264 markObj((void *)(runtime_locks[i].redirectlock));
1265 if(runtime_locks[i].value != NULL) {
1266 markObj((void *)(runtime_locks[i].value));
1270 } // void tomark(struct garbagelist * stackptr)
1272 inline void mark(bool isfirst,
1273 struct garbagelist * stackptr) {
1275 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed01);
1279 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed02);
1281 // enqueue root objs
1283 gccurr_heaptop = 0; // record the size of all active objs in this core
1284 // aligned but does not consider block boundaries
1285 gcmarkedptrbound = 0;
1288 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed03);
1291 bool checkfield = true;
1292 bool sendStall = false;
1294 while(MARKPHASE == gcphase) {
1296 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed04);
1299 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1300 bool hasItems = gc_moreItems2_I();
1301 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1303 BAMBOO_DEBUGPRINT(0xed05);
1309 gcbusystatus = true;
1311 void * ptr = gc_dequeue2_I();
1314 BAMBOO_DEBUGPRINT_REG(ptr);
1319 // check if it is a shared obj
1320 if(ISSHAREDOBJ(ptr)) {
1321 // a shared obj, check if it is a local obj on this core
1322 int host = hostcore(ptr);
1323 bool islocal = (host == BAMBOO_NUM_OF_CORE);
1325 bool isnotmarked = (((int *)ptr)[6] == DISCOVERED);
1326 if(isLarge(ptr, &type, &size) && isnotmarked) {
1327 // ptr is a large object and not marked or enqueued
1329 BAMBOO_DEBUGPRINT(0xecec);
1330 BAMBOO_DEBUGPRINT_REG(ptr);
1331 BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
1333 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1334 gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
1336 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1338 ((int *)ptr)[6] = MARKED;
1339 } else if(isnotmarked) {
1340 // ptr is an unmarked active object on this core
1341 ALIGNSIZE(size, &isize);
1342 gccurr_heaptop += isize;
1344 BAMBOO_DEBUGPRINT(0xaaaa);
1345 BAMBOO_DEBUGPRINT_REG(ptr);
1346 BAMBOO_DEBUGPRINT_REG(isize);
1347 BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
1350 ((int *)ptr)[6] = MARKED;
1352 if(ptr + size > gcmarkedptrbound) {
1353 gcmarkedptrbound = ptr + size;
1354 } // if(ptr + size > gcmarkedptrbound)
1356 // ptr is not an active obj or has been marked
1358 } // if(isLarge(ptr, &type, &size)) else ...
1359 } /* can never reach here
1362 if(BAMBOO_NUM_OF_CORE == 0) {
1363 BAMBOO_DEBUGPRINT(0xbbbb);
1364 BAMBOO_DEBUGPRINT_REG(host);
1365 BAMBOO_DEBUGPRINT_REG(ptr);
1368 // check if this obj has been forwarded
1369 if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
1370 // send a msg to host informing that ptr is active
1371 send_msg_2(host, GCMARKEDOBJ, ptr);
1372 gcself_numsendobjs++;
1373 MGCHashadd(gcforwardobjtbl, (int)ptr);
1376 }// if(isLocal(ptr)) else ...*/
1377 } // if(ISSHAREDOBJ(ptr))
1379 BAMBOO_DEBUGPRINT(0xed06);
1383 // scan all pointers in ptr
1384 unsigned INTPTR * pointer;
1385 pointer=pointerarray[type];
1387 /* Array of primitives */
1389 } else if (((INTPTR)pointer)==1) {
1390 /* Array of pointers */
1391 struct ArrayObject *ao=(struct ArrayObject *) ptr;
1392 int length=ao->___length___;
1394 for(j=0; j<length; j++) {
1396 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
1400 INTPTR size=pointer[0];
1402 for(i=1; i<=size; i++) {
1403 unsigned int offset=pointer[i];
1404 void * objptr=*((void **)(((char *)ptr)+offset));
1407 } // if (pointer==0) else if ... else ...
1409 } // while(gc_moreItems2())
1411 BAMBOO_DEBUGPRINT(0xed07);
1413 gcbusystatus = false;
1414 // send mark finish msg to core coordinator
1415 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1417 BAMBOO_DEBUGPRINT(0xed08);
1419 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
1420 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
1421 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
1422 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
1426 BAMBOO_DEBUGPRINT(0xed09);
1428 send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
1429 gcself_numsendobjs, gcself_numreceiveobjs, false);
1432 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
1434 BAMBOO_DEBUGPRINT(0xed0a);
1437 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1439 BAMBOO_DEBUGPRINT(0xed0b);
1443 } // while(MARKPHASE == gcphase)
1446 inline void compact2Heaptophelper_I(int coren,
1451 int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
1452 if(STARTUPCORE == coren) {
1454 gcmovestartaddr = *p;
1455 gcdstcore = gctopcore;
1456 gcblock2fill = *numblocks + 1;
1458 send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
1461 BAMBOO_DEBUGPRINT_REG(coren);
1462 BAMBOO_DEBUGPRINT_REG(gctopcore);
1463 BAMBOO_DEBUGPRINT_REG(*p);
1464 BAMBOO_DEBUGPRINT_REG(*numblocks+1);
1466 if(memneed < *remain) {
1468 BAMBOO_DEBUGPRINT(0xd104);
1471 gcrequiredmems[coren] = 0;
1472 gcloads[gctopcore] += memneed;
1473 *remain = *remain - memneed;
1476 BAMBOO_DEBUGPRINT(0xd105);
1478 // next available block
1480 gcfilledblocks[gctopcore] += 1;
1482 BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
1483 gcloads[gctopcore] = newbase;
1484 gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
1485 gcstopblock[gctopcore]++;
1486 gctopcore = NEXTTOPCORE(gctopblock);
1488 *numblocks = gcstopblock[gctopcore];
1489 *p = gcloads[gctopcore];
1491 *remain=(b<NUMCORES4GC) ?
1492 ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
1493 : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
1495 BAMBOO_DEBUGPRINT(0xd106);
1496 BAMBOO_DEBUGPRINT_REG(gctopcore);
1497 BAMBOO_DEBUGPRINT_REG(*p);
1498 BAMBOO_DEBUGPRINT_REG(b);
1499 BAMBOO_DEBUGPRINT_REG(*remain);
1501 } // if(memneed < remain)
1503 } // void compact2Heaptophelper_I(int, int*, int*, int*)
1505 inline void compact2Heaptop() {
1506 // no cores with spare mem and some cores are blocked with pending move
1507 // find the current heap top and make them move to the heap top
1509 int numblocks = gcfilledblocks[gctopcore];
1510 //BASEPTR(gctopcore, numblocks, &p);
1511 p = gcloads[gctopcore];
1514 int remain = (b<NUMCORES4GC) ?
1515 ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
1516 : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
1517 // check if the top core finishes
1518 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1519 if(gccorestatus[gctopcore] != 0) {
1521 BAMBOO_DEBUGPRINT(0xd101);
1522 BAMBOO_DEBUGPRINT_REG(gctopcore);
1524 // let the top core finishes its own work first
1525 compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
1526 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1529 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1532 BAMBOO_DEBUGPRINT(0xd102);
1533 BAMBOO_DEBUGPRINT_REG(gctopcore);
1534 BAMBOO_DEBUGPRINT_REG(p);
1535 BAMBOO_DEBUGPRINT_REG(b);
1536 BAMBOO_DEBUGPRINT_REG(remain);
1538 for(int i = 0; i < NUMCORES4GC; i++) {
1539 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1540 if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
1542 BAMBOO_DEBUGPRINT(0xd103);
1544 compact2Heaptophelper_I(i, &p, &numblocks, &remain);
1545 if(gccorestatus[gctopcore] != 0) {
1547 BAMBOO_DEBUGPRINT(0xd101);
1548 BAMBOO_DEBUGPRINT_REG(gctopcore);
1550 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1551 // the top core is not free now
1554 } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
1555 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1556 } // for(i = 0; i < NUMCORES4GC; i++)
1558 BAMBOO_DEBUGPRINT(0xd106);
1560 } // void compact2Heaptop()
1562 inline void resolvePendingMoveRequest() {
1564 BAMBOO_DEBUGPRINT(0xeb01);
1567 BAMBOO_DEBUGPRINT(0xeeee);
1568 for(int k = 0; k < NUMCORES4GC; k++) {
1569 BAMBOO_DEBUGPRINT(0xf000+k);
1570 BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
1571 BAMBOO_DEBUGPRINT_REG(gcloads[k]);
1572 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
1573 BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
1575 BAMBOO_DEBUGPRINT(0xffff);
1579 bool nosparemem = true;
1580 bool haspending = false;
1581 bool hasrunning = false;
1582 bool noblock = false;
1583 int dstcore = 0; // the core who need spare mem
1584 int sourcecore = 0; // the core who has spare mem
1585 for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
1587 // check if there are cores with spare mem
1588 if(gccorestatus[i] == 0) {
1589 // finished working, check if it still have spare mem
1590 if(gcfilledblocks[i] < gcstopblock[i]) {
1591 // still have spare mem
1594 } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
1599 if(gccorestatus[j] != 0) {
1600 // not finished, check if it has pending move requests
1601 if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
1606 } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
1607 } // if(gccorestatus[i] == 0) else ...
1609 } // if(!haspending)
1610 if(!nosparemem && haspending) {
1614 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1615 gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
1616 gcrequiredmems[dstcore],
1619 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1621 BAMBOO_DEBUGPRINT(0xeb02);
1622 BAMBOO_DEBUGPRINT_REG(sourcecore);
1623 BAMBOO_DEBUGPRINT_REG(dstcore);
1624 BAMBOO_DEBUGPRINT_REG(startaddr);
1625 BAMBOO_DEBUGPRINT_REG(tomove);
1627 if(STARTUPCORE == dstcore) {
1629 BAMBOO_DEBUGPRINT(0xeb03);
1631 gcdstcore = sourcecore;
1633 gcmovestartaddr = startaddr;
1634 gcblock2fill = tomove;
1637 BAMBOO_DEBUGPRINT(0xeb04);
1639 send_msg_4(dstcore, GCMOVESTART, sourcecore,
1640 startaddr, tomove, false);
1647 } // for(i = 0; i < NUMCORES4GC; i++)
1649 BAMBOO_DEBUGPRINT(0xcccc);
1650 BAMBOO_DEBUGPRINT_REG(hasrunning);
1651 BAMBOO_DEBUGPRINT_REG(haspending);
1652 BAMBOO_DEBUGPRINT_REG(noblock);
1655 if(!hasrunning && !noblock) {
1656 gcphase = SUBTLECOMPACTPHASE;
1660 } // void resovePendingMoveRequest()
1663 int numblocks; // block num for heap
1664 INTPTR base; // base virtual address of current heap block
1665 INTPTR ptr; // virtual address of current heap top
1666 int offset; // offset in current heap block
1667 int blockbase; // virtual address of current small block to check
1668 int blockbound; // bound virtual address of current small blcok
1669 int sblockindex; // index of the small blocks
1670 int top; // real size of current heap block to check
1671 int bound; // bound size of current heap block to check
1672 }; // struct moveHelper
1674 // if out of boundary of valid shared memory, return false, else return true
1675 inline bool nextSBlock(struct moveHelper * orig) {
1676 orig->blockbase = orig->blockbound;
1677 bool sbchanged = false;
1679 BAMBOO_DEBUGPRINT(0xecc0);
1680 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1681 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1682 BAMBOO_DEBUGPRINT_REG(orig->bound);
1683 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1686 // check if across a big block
1687 if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)
1688 || ((orig->ptr != NULL) && (*((int*)orig->ptr))==0)
1689 || ((*((int*)orig->blockbase))==0)) {
1691 // end of current heap block, jump to next one
1694 BAMBOO_DEBUGPRINT(0xecc1);
1695 BAMBOO_DEBUGPRINT_REG(orig->numblocks);
1697 BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
1699 BAMBOO_DEBUGPRINT(orig->base);
1701 if(orig->base >= BAMBOO_BASE_VA + BAMBOO_SHARED_MEM_SIZE) {
1703 orig->ptr = orig->base; // set current ptr to out of boundary too
1706 orig->bound = orig->base + BAMBOO_SMEM_SIZE;
1707 orig->blockbase = orig->base;
1708 orig->sblockindex = (orig->blockbase-BAMBOO_BASE_VA)/BAMBOO_SMEM_SIZE;
1711 BLOCKINDEX(orig->base, &blocknum);
1712 if(bamboo_smemtbl[blocknum] == 0) {
1714 goto innernextSBlock;
1716 } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
1717 orig->sblockindex += 1;
1719 } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
1721 // check if this sblock should be skipped or have special start point
1722 if(gcsbstarttbl[orig->sblockindex] == -1) {
1725 BAMBOO_DEBUGPRINT(0xecc2);
1727 orig->sblockindex += 1;
1728 orig->blockbase += BAMBOO_SMEM_SIZE;
1729 goto outernextSBlock;
1730 } else if((gcsbstarttbl[orig->sblockindex] != 0)
1732 // the first time to access this SBlock
1734 BAMBOO_DEBUGPRINT(0xecc3);
1736 // not start from the very beginning
1737 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1738 } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
1740 // setup information for this sblock
1741 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1742 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1743 orig->ptr = orig->blockbase + orig->offset;
1745 BAMBOO_DEBUGPRINT(0xecc4);
1746 BAMBOO_DEBUGPRINT_REG(orig->base);
1747 BAMBOO_DEBUGPRINT_REG(orig->bound);
1748 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1749 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1750 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1751 BAMBOO_DEBUGPRINT_REG(orig->offset);
1753 if(orig->ptr >= orig->bound) {
1754 // met a lobj, move to next block
1755 goto innernextSBlock;
1759 } // bool nextSBlock(struct moveHelper * orig)
1761 // return false if there are no available data to compact
1762 inline bool initOrig_Dst(struct moveHelper * orig,
1763 struct moveHelper * to) {
1766 to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
1767 to->bound = BAMBOO_SMEM_SIZE_L;
1768 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1771 BAMBOO_DEBUGPRINT(0xef01);
1772 BAMBOO_DEBUGPRINT_REG(to->base);
1774 to->ptr = to->base + to->offset;
1776 // init the orig ptr
1777 orig->numblocks = 0;
1778 orig->base = to->base;
1779 orig->bound = to->base + BAMBOO_SMEM_SIZE_L;
1780 orig->blockbase = orig->base;
1781 orig->sblockindex = (orig->base - BAMBOO_BASE_VA) / BAMBOO_SMEM_SIZE;
1783 BAMBOO_DEBUGPRINT(0xef02);
1784 BAMBOO_DEBUGPRINT_REG(orig->base);
1785 BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
1786 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
1787 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
1790 if(gcsbstarttbl[orig->sblockindex] == -1) {
1792 BAMBOO_DEBUGPRINT(0xef03);
1796 BAMBOO_BASE_VA+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
1797 return nextSBlock(orig);
1798 } else if(gcsbstarttbl[orig->sblockindex] != 0) {
1800 BAMBOO_DEBUGPRINT(0xef04);
1802 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1805 BAMBOO_DEBUGPRINT(0xef05);
1807 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1808 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1809 orig->ptr = orig->blockbase + orig->offset;
1811 BAMBOO_DEBUGPRINT(0xef06);
1812 BAMBOO_DEBUGPRINT_REG(orig->base);
1815 } // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
1817 inline void nextBlock(struct moveHelper * to) {
1818 to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
1819 to->bound += BAMBOO_SMEM_SIZE;
1821 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1822 to->offset = BAMBOO_CACHE_LINE_SIZE;
1823 to->ptr = to->base + to->offset;
1824 } // void nextBlock(struct moveHelper * to)
1826 // endaddr does not contain spaces for headers
1827 inline bool moveobj(struct moveHelper * orig,
1828 struct moveHelper * to,
1830 if(stopblock == 0) {
1835 BAMBOO_DEBUGPRINT(0xe201);
1836 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1837 BAMBOO_DEBUGPRINT_REG(to->ptr);
1845 while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
1846 orig->ptr = (int*)(orig->ptr) + 1;
1848 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
1849 if(!nextSBlock(orig)) {
1850 // finished, no more data
1856 BAMBOO_DEBUGPRINT(0xe202);
1857 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1858 BAMBOO_DEBUGPRINT(((int *)(orig->ptr))[0]);
1860 // check the obj's type, size and mark flag
1861 type = ((int *)(orig->ptr))[0];
1864 // end of this block, go to next one
1865 if(!nextSBlock(orig)) {
1866 // finished, no more data
1870 } else if(type < NUMCLASSES) {
1872 size = classsize[type];
1875 struct ArrayObject *ao=(struct ArrayObject *)(orig->ptr);
1876 int elementsize=classsize[type];
1877 int length=ao->___length___;
1878 size=sizeof(struct ArrayObject)+length*elementsize;
1880 mark = ((int *)(orig->ptr))[6];
1882 BAMBOO_DEBUGPRINT(0xe203);
1883 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1884 BAMBOO_DEBUGPRINT_REG(size);
1886 ALIGNSIZE(size, &isize); // no matter is the obj marked or not
1887 // should be able to across it
1888 if(mark == MARKED) {
1890 BAMBOO_DEBUGPRINT(0xe204);
1892 // marked obj, copy it to current heap top
1893 // check to see if remaining space is enough
1894 if(to->top + isize > to->bound) {
1895 // fill 0 indicating the end of this block
1896 BAMBOO_MEMSET_WH(to->ptr, '\0', to->bound - to->top);
1897 // fill the header of this block and then go to next block
1898 to->offset += to->bound - to->top;
1899 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1900 (*((int*)(to->base))) = to->offset;
1902 if(stopblock == to->numblocks) {
1903 // already fulfilled the block
1905 } // if(stopblock == to->numblocks)
1906 } // if(to->top + isize > to->bound)
1907 // set the mark field to 2, indicating that this obj has been moved
1908 // and need to be flushed
1909 ((int *)(orig->ptr))[6] = COMPACTED;
1910 if(to->ptr != orig->ptr) {
1911 if((int)(orig->ptr) < (int)(to->ptr)+size) {
1912 memmove(to->ptr, orig->ptr, size);
1914 //BAMBOO_WRITE_HINT_CACHE(to->ptr, size);
1915 memcpy(to->ptr, orig->ptr, size);
1917 // fill the remaining space with -2
1918 BAMBOO_MEMSET_WH(to->ptr+size, -2, isize-size);
1920 // store mapping info
1921 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1922 //mgchashInsert_I(orig->ptr, to->ptr);
1923 RuntimeHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1924 //MGCHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1925 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1928 BAMBOO_DEBUGPRINT(0xcdce);
1929 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1930 BAMBOO_DEBUGPRINT_REG(to->ptr);
1932 gccurr_heaptop -= isize;
1934 to->offset += isize;
1936 if(to->top == to->bound) {
1937 // fill the header of this block and then go to next block
1938 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1939 (*((int*)(to->base))) = to->offset;
1944 BAMBOO_DEBUGPRINT(0xe205);
1950 BAMBOO_DEBUGPRINT_REG(isize);
1951 BAMBOO_DEBUGPRINT_REG(size);
1952 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1953 BAMBOO_DEBUGPRINT_REG(orig->bound);
1955 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
1957 BAMBOO_DEBUGPRINT(0xe206);
1959 if(!nextSBlock(orig)) {
1960 // finished, no more data
1965 BAMBOO_DEBUGPRINT(0xe207);
1966 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1969 } //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
1971 // should be invoked with interrupt closed
1972 inline int assignSpareMem_I(int sourcecore,
1977 BLOCKINDEX(gcloads[sourcecore], &b);
1978 int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
1979 : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
1980 int remain = boundptr - gcloads[sourcecore];
1981 int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
1982 *startaddr = gcloads[sourcecore];
1983 *tomove = gcfilledblocks[sourcecore] + 1;
1984 if(memneed < remain) {
1985 gcloads[sourcecore] += memneed;
1988 // next available block
1989 gcfilledblocks[sourcecore] += 1;
1991 BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
1992 gcloads[sourcecore] = newbase;
1993 return requiredmem-remain;
1995 } // int assignSpareMem_I(int ,int * , int * , int * )
1997 // should be invoked with interrupt closed
1998 inline bool gcfindSpareMem_I(int * startaddr,
2003 for(int k = 0; k < NUMCORES4GC; k++) {
2004 if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
2005 // check if this stopped core has enough mem
2006 assignSpareMem_I(k, requiredmem, tomove, startaddr);
2011 // if can not find spare mem right now, hold the request
2012 gcrequiredmems[requiredcore] = requiredmem;
2015 } //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
2017 inline bool compacthelper(struct moveHelper * orig,
2018 struct moveHelper * to,
2021 bool * localcompact) {
2022 // scan over all objs in this block, compact the marked objs
2023 // loop stop when finishing either scanning all active objs or
2024 // fulfilled the gcstopblock
2026 BAMBOO_DEBUGPRINT(0xe101);
2027 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2028 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2031 while(orig->ptr < gcmarkedptrbound) {
2032 bool stop = moveobj(orig, to, gcblock2fill);
2037 // if no objs have been compact, do nothing,
2038 // otherwise, fill the header of this block
2039 if(to->offset > BAMBOO_CACHE_LINE_SIZE) {
2040 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2041 (*((int*)(to->base))) = to->offset;
2045 to->top -= BAMBOO_CACHE_LINE_SIZE;
2046 } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
2048 *heaptopptr = to->ptr;
2049 *filledblocks = to->numblocks;
2052 BAMBOO_DEBUGPRINT(0xe102);
2053 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2054 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2055 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2056 BAMBOO_DEBUGPRINT_REG(*filledblocks);
2057 BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
2060 // send msgs to core coordinator indicating that the compact is finishing
2061 // send compact finish message to core coordinator
2062 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2063 gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
2064 gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
2065 if(orig->ptr < gcmarkedptrbound) {
2067 BAMBOO_DEBUGPRINT(0xe103);
2071 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2072 if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
2073 gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
2075 BAMBOO_DEBUGPRINT(0xe104);
2079 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2081 BAMBOO_DEBUGPRINT(0xe105);
2085 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2088 BAMBOO_DEBUGPRINT(0xe106);
2090 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2095 if(orig->ptr < gcmarkedptrbound) {
2097 BAMBOO_DEBUGPRINT(0xe107);
2101 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2102 *filledblocks, *heaptopptr, gccurr_heaptop, false);
2105 BAMBOO_DEBUGPRINT(0xe108);
2106 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2108 // finish compacting
2109 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2110 *filledblocks, *heaptopptr, 0, false);
2112 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
2114 if(orig->ptr < gcmarkedptrbound) {
2116 BAMBOO_DEBUGPRINT(0xe109);
2118 // still have unpacked obj
2127 BAMBOO_DEBUGPRINT(0xe10a);
2130 to->ptr = gcmovestartaddr;
2131 to->numblocks = gcblock2fill - 1;
2132 to->bound = (to->numblocks==0) ?
2133 BAMBOO_SMEM_SIZE_L :
2134 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2135 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2136 to->offset = to->ptr - to->base;
2137 to->top = (to->numblocks==0) ?
2138 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2140 to->offset = BAMBOO_CACHE_LINE_SIZE;
2141 to->ptr += to->offset; // for header
2142 to->top += to->offset;
2143 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2144 *localcompact = true;
2146 *localcompact = false;
2151 BAMBOO_DEBUGPRINT(0xe10b);
2154 } // void compacthelper()
2156 inline void compact() {
2157 if(COMPACTPHASE != gcphase) {
2158 BAMBOO_EXIT(0xb102);
2161 // initialize pointers for comapcting
2162 struct moveHelper * orig =
2163 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2164 struct moveHelper * to =
2165 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2167 if(!initOrig_Dst(orig, to)) {
2168 // no available data to compact
2169 // send compact finish msg to STARTUP core
2171 BAMBOO_DEBUGPRINT(0xe001);
2172 BAMBOO_DEBUGPRINT_REG(to->base);
2174 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2175 0, to->base, 0, false);
2181 int filledblocks = 0;
2182 INTPTR heaptopptr = 0;
2183 bool localcompact = true;
2184 compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
2190 // if return NULL, means
2191 // 1. objptr is NULL
2192 // 2. objptr is not a shared obj
2193 // in these cases, remain the original value is OK
2194 inline void * flushObj(void * objptr) {
2196 BAMBOO_DEBUGPRINT(0xe401);
2198 if(objptr == NULL) {
2201 void * dstptr = NULL;
2202 if(ISSHAREDOBJ(objptr)) {
2204 BAMBOO_DEBUGPRINT(0xe402);
2205 BAMBOO_DEBUGPRINT_REG(objptr);
2207 // a shared obj ptr, change to new address
2208 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2210 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2212 //dstptr = mgchashSearch(objptr);
2213 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2215 flushstalltime += BAMBOO_GET_EXE_TIME()-ttime;
2217 //MGCHashget(gcpointertbl, objptr, &dstptr);
2218 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2220 BAMBOO_DEBUGPRINT_REG(dstptr);
2222 if(NULL == dstptr) {
2225 BAMBOO_DEBUGPRINT(0xe403);
2226 BAMBOO_DEBUGPRINT_REG(objptr);
2227 BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
2229 if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) {
2230 // error! the obj is right on this core, but cannot find it
2231 BAMBOO_DEBUGPRINT_REG(objptr);
2232 BAMBOO_EXIT(0xb103);
2233 // assume that the obj has not been moved, use the original address
2236 // send msg to host core for the mapping info
2237 gcobj2map = (int)objptr;
2242 num_mapinforequest++;
2243 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2246 unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
2248 // the first time require the mapping, send msg to the hostcore
2249 // for the mapping info
2250 send_msg_3(hostcore(objptr), GCMAPREQUEST, (int)objptr,
2251 BAMBOO_NUM_OF_CORE, false);
2258 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
2262 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2264 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2265 //dstptr = mgchashSearch(objptr);
2266 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2267 //MGCHashget(gcpointertbl, objptr, &dstptr);
2268 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2269 } // if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) else ...
2271 BAMBOO_DEBUGPRINT_REG(dstptr);
2273 } // if(NULL == dstptr)
2274 } // if(ISSHAREDOBJ(objptr))
2275 // if not a shared obj, return NULL to indicate no need to flush
2277 BAMBOO_DEBUGPRINT(0xe404);
2280 } // void flushObj(void * objptr)
2282 inline void flushRuntimeObj(struct garbagelist * stackptr) {
2284 // flush current stack
2285 while(stackptr!=NULL) {
2286 for(i=0; i<stackptr->size; i++) {
2287 if(stackptr->array[i] != NULL) {
2288 void * dst = flushObj(stackptr->array[i]);
2290 stackptr->array[i] = dst;
2294 stackptr=stackptr->next;
2298 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
2299 for(i=0; i<NUMCLASSES; i++) {
2300 struct parameterwrapper ** queues =
2301 objectqueues[BAMBOO_NUM_OF_CORE][i];
2302 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
2303 for(j = 0; j < length; ++j) {
2304 struct parameterwrapper * parameter = queues[j];
2305 struct ObjectHash * set=parameter->objectset;
2306 struct ObjectNode * ptr=set->listhead;
2308 void * dst = flushObj((void *)ptr->key);
2314 ObjectHashrehash(set);
2319 // flush current task descriptor
2320 if(currtpd != NULL) {
2321 for(i=0; i<currtpd->numParameters; i++) {
2322 void * dst = flushObj(currtpd->parameterArray[i]);
2324 currtpd->parameterArray[i] = dst;
2329 // flush active tasks
2330 if(activetasks != NULL) {
2331 struct genpointerlist * ptr=activetasks->list;
2333 struct taskparamdescriptor *tpd=ptr->src;
2335 for(i=0; i<tpd->numParameters; i++) {
2336 void * dst = flushObj(tpd->parameterArray[i]);
2338 tpd->parameterArray[i] = dst;
2343 genrehash(activetasks);
2346 // flush cached transferred obj
2347 struct QueueItem * tmpobjptr = getHead(&objqueue);
2348 while(tmpobjptr != NULL) {
2349 struct transObjInfo * objInfo =
2350 (struct transObjInfo *)(tmpobjptr->objectptr);
2351 void * dst = flushObj(objInfo->objptr);
2353 objInfo->objptr = dst;
2355 tmpobjptr = getNextQueueItem(tmpobjptr);
2358 // flush cached objs to be transferred
2359 struct QueueItem * item = getHead(totransobjqueue);
2360 while(item != NULL) {
2361 struct transObjInfo * totransobj =
2362 (struct transObjInfo *)(item->objectptr);
2363 void * dst = flushObj(totransobj->objptr);
2365 totransobj->objptr = dst;
2367 item = getNextQueueItem(item);
2368 } // while(item != NULL)
2370 // enqueue lock related info
2371 for(i = 0; i < runtime_locklen; ++i) {
2372 void * dst = flushObj(runtime_locks[i].redirectlock);
2374 runtime_locks[i].redirectlock = (int)dst;
2376 if(runtime_locks[i].value != NULL) {
2377 void * dst=flushObj(runtime_locks[i].value);
2379 runtime_locks[i].value = (int)dst;
2384 } // void flushRuntimeObj(struct garbagelist * stackptr)
2386 inline void flush(struct garbagelist * stackptr) {
2388 if(BAMBOO_NUM_OF_CORE == 0) {
2389 BAMBOO_DEBUGPRINT(0xcccc);
2390 BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2393 flushRuntimeObj(stackptr);
2395 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2399 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2400 bool hasItems = gc_moreItems_I();
2401 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2407 BAMBOO_DEBUGPRINT(0xe301);
2409 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2410 void * ptr = gc_dequeue_I();
2411 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2412 if(ISSHAREDOBJ(ptr)) {
2413 // should be a local shared obj and should have mapping info
2414 ptr = flushObj(ptr);
2416 BAMBOO_DEBUGPRINT(0xe302);
2417 BAMBOO_DEBUGPRINT_REG(ptr);
2418 BAMBOO_DEBUGPRINT_REG(tptr);
2419 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2422 BAMBOO_EXIT(0xb105);
2424 } // if(ISSHAREDOBJ(ptr))
2425 if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED)) {
2426 int type = ((int *)(ptr))[0];
2427 // scan all pointers in ptr
2428 unsigned INTPTR * pointer;
2429 pointer=pointerarray[type];
2431 BAMBOO_DEBUGPRINT(0xe303);
2432 BAMBOO_DEBUGPRINT_REG(pointer);
2435 /* Array of primitives */
2437 } else if (((INTPTR)pointer)==1) {
2439 BAMBOO_DEBUGPRINT(0xe304);
2441 /* Array of pointers */
2442 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2443 int length=ao->___length___;
2445 for(j=0; j<length; j++) {
2447 BAMBOO_DEBUGPRINT(0xe305);
2450 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2452 BAMBOO_DEBUGPRINT_REG(objptr);
2454 if(objptr != NULL) {
2455 void * dst = flushObj(objptr);
2457 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2463 BAMBOO_DEBUGPRINT(0xe306);
2465 INTPTR size=pointer[0];
2467 for(i=1; i<=size; i++) {
2469 BAMBOO_DEBUGPRINT(0xe307);
2471 unsigned int offset=pointer[i];
2472 void * objptr=*((void **)(((char *)ptr)+offset));
2474 BAMBOO_DEBUGPRINT_REG(objptr);
2476 if(objptr != NULL) {
2477 void * dst = flushObj(objptr);
2479 *((void **)(((char *)ptr)+offset)) = dst;
2482 } // for(i=1; i<=size; i++)
2483 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2484 // restore the mark field, indicating that this obj has been flushed
2485 if(ISSHAREDOBJ(ptr)) {
2486 ((int *)(ptr))[6] = INIT;
2488 } // if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED))
2489 } // while(gc_moreItems())
2491 BAMBOO_DEBUGPRINT(0xe308);
2494 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2497 // TODO bug here: the startup core contains all lobjs' info, thus all the
2498 // lobjs are flushed in sequence.
2500 while(gc_lobjmoreItems_I()) {
2502 BAMBOO_DEBUGPRINT(0xe309);
2504 void * ptr = gc_lobjdequeue_I(NULL, NULL);
2505 ptr = flushObj(ptr);
2507 BAMBOO_DEBUGPRINT(0xe30a);
2508 BAMBOO_DEBUGPRINT_REG(ptr);
2509 BAMBOO_DEBUGPRINT_REG(tptr);
2510 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2515 if(((int *)(ptr))[6] == COMPACTED) {
2516 int type = ((int *)(ptr))[0];
2517 // scan all pointers in ptr
2518 unsigned INTPTR * pointer;
2519 pointer=pointerarray[type];
2521 BAMBOO_DEBUGPRINT(0xe30b);
2522 BAMBOO_DEBUGPRINT_REG(pointer);
2525 /* Array of primitives */
2527 } else if (((INTPTR)pointer)==1) {
2529 BAMBOO_DEBUGPRINT(0xe30c);
2531 /* Array of pointers */
2532 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2533 int length=ao->___length___;
2535 for(j=0; j<length; j++) {
2537 BAMBOO_DEBUGPRINT(0xe30d);
2540 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2542 BAMBOO_DEBUGPRINT_REG(objptr);
2544 if(objptr != NULL) {
2545 void * dst = flushObj(objptr);
2547 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2553 BAMBOO_DEBUGPRINT(0xe30e);
2555 INTPTR size=pointer[0];
2557 for(i=1; i<=size; i++) {
2559 BAMBOO_DEBUGPRINT(0xe30f);
2561 unsigned int offset=pointer[i];
2562 void * objptr=*((void **)(((char *)ptr)+offset));
2565 BAMBOO_DEBUGPRINT_REG(objptr);
2567 if(objptr != NULL) {
2568 void * dst = flushObj(objptr);
2570 *((void **)(((char *)ptr)+offset)) = dst;
2573 } // for(i=1; i<=size; i++)
2574 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2575 // restore the mark field, indicating that this obj has been flushed
2576 ((int *)(ptr))[6] = INIT;
2577 } // if(((int *)(ptr))[6] == COMPACTED)
2578 } // while(gc_lobjmoreItems())
2580 BAMBOO_DEBUGPRINT(0xe310);
2583 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2586 // send flush finish message to core coordinator
2587 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2588 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2590 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
2593 if(BAMBOO_NUM_OF_CORE == 0) {
2594 BAMBOO_DEBUGPRINT(0xffff);
2595 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest);
2596 BAMBOO_DEBUGPRINT_REG(flushstalltime);
2597 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest_i);
2598 BAMBOO_DEBUGPRINT_REG(flushstalltime_i);
2600 //BAMBOO_DEBUGPRINT_REG(flushstalltime);
2603 BAMBOO_DEBUGPRINT(0xe311);
2607 inline void gc_collect(struct garbagelist * stackptr) {
2608 // core collector routine
2610 if(INITPHASE == gcphase) {
2614 #ifdef RAWPATH // TODO GC_DEBUG
2615 printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2618 //send init finish msg to core coordinator
2619 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2621 if(MARKPHASE == gcphase) {
2625 #ifdef RAWPATH // TODO GC_DEBUG
2626 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2627 udn_tile_coord_y());
2629 mark(true, stackptr);
2630 #ifdef RAWPATH // TODO GC_DEBUG
2631 printf("(%x,%x) Finish mark phase, start compact phase\n",
2632 udn_tile_coord_x(), udn_tile_coord_y());
2635 #ifdef RAWPATH // TODO GC_DEBUG
2636 printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
2637 udn_tile_coord_y());
2640 if(FLUSHPHASE == gcphase) {
2644 #ifdef RAWPATH // TODO GC_DEBUG
2645 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2646 udn_tile_coord_y());
2649 #ifdef RAWPATH // TODO GC_DEBUG
2650 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2651 udn_tile_coord_y());
2655 if(FINISHPHASE == gcphase) {
2659 #ifdef RAWPATH // TODO GC_DEBUG
2660 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2662 } // void gc_collect(struct garbagelist * stackptr)
2664 inline void gc_nocollect(struct garbagelist * stackptr) {
2666 if(INITPHASE == gcphase) {
2670 #ifdef RAWPATH // TODO GC_DEBUG
2671 printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2674 //send init finish msg to core coordinator
2675 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2677 if(MARKPHASE == gcphase) {
2681 #ifdef RAWPATH // TODO GC_DEBUG
2682 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2683 udn_tile_coord_y());
2685 mark(true, stackptr);
2686 #ifdef RAWPATH // TODO GC_DEBUG
2687 printf("(%x,%x) Finish mark phase, wait for flush\n",
2688 udn_tile_coord_x(), udn_tile_coord_y());
2690 // non-gc core collector routine
2692 if(FLUSHPHASE == gcphase) {
2696 #ifdef RAWPATH // TODO GC_DEBUG
2697 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2698 udn_tile_coord_y());
2701 #ifdef RAWPATH // TODO GC_DEBUG
2702 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2703 udn_tile_coord_y());
2707 if(FINISHPHASE == gcphase) {
2711 #ifdef RAWPATH // TODO GC_DEBUG
2712 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2714 } // void gc_collect(struct garbagelist * stackptr)
2716 inline void gc(struct garbagelist * stackptr) {
2719 gcprocessing = false;
2723 // core coordinator routine
2724 if(0 == BAMBOO_NUM_OF_CORE) {
2726 printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
2727 udn_tile_coord_y());
2730 // not ready to do gc
2739 #ifdef RAWPATH // TODO GC_DEBUG
2740 printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
2743 gcprocessing = true;
2744 gcphase = INITPHASE;
2746 waitconfirm = false;
2750 // Note: all cores need to init gc including non-gc cores
2751 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
2752 // send GC init messages to all cores
2753 send_msg_1(i, GCSTARTINIT, false);
2755 bool isfirst = true;
2756 bool allStall = false;
2758 #ifdef RAWPATH // TODO GC_DEBUG
2759 printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
2760 udn_tile_coord_y());
2763 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2765 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2766 if(gc_checkAllCoreStatus_I()) {
2767 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2770 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2775 #ifdef RAWPATH // TODO GC_DEBUG
2776 printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
2777 udn_tile_coord_y());
2779 // all cores have finished compacting
2780 // restore the gcstatus of all cores
2781 // Note: all cores have to do mark including non-gc cores
2782 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
2783 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
2784 gccorestatus[i] = 1;
2785 // send GC start messages to all cores
2786 send_msg_1(i, GCSTART, false);
2789 gcphase = MARKPHASE;
2791 while(MARKPHASE == gcphase) {
2792 mark(isfirst, stackptr);
2799 } // while(MARKPHASE == gcphase)
2800 // send msgs to all cores requiring large objs info
2801 // Note: only need to ask gc cores, non-gc cores do not host any objs
2802 numconfirm = NUMCORES4GC - 1;
2803 for(i = 1; i < NUMCORES4GC; ++i) {
2804 send_msg_1(i, GCLOBJREQUEST, false);
2806 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
2811 } // wait for responses
2812 // check the heaptop
2813 if(gcheaptop < gcmarkedptrbound) {
2814 gcheaptop = gcmarkedptrbound;
2819 if(BAMBOO_NUM_OF_CORE == 0) {
2820 BAMBOO_DEBUGPRINT(0xeeee);
2821 BAMBOO_DEBUGPRINT_REG(num_markrequest);
2822 BAMBOO_DEBUGPRINT_REG(marktime);
2825 #ifdef RAWPATH // TODO GC_DEBUG
2826 printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
2827 udn_tile_coord_y());
2830 // cache all large objs
2832 // no enough space to cache large objs
2833 BAMBOO_EXIT(0xb107);
2835 // predict number of blocks to fill for each core
2837 int numpbc = loadbalance(&tmpheaptop);
2839 numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
2840 #ifdef RAWPATH // TODO GC_DEBUG
2841 printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
2842 udn_tile_coord_y());
2845 //int tmptopptr = 0;
2846 //BASEPTR(gctopcore, 0, &tmptopptr);
2848 //tmptopptr = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2849 tmpheaptop = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2851 BAMBOO_DEBUGPRINT(0xabab);
2852 BAMBOO_DEBUGPRINT_REG(tmptopptr);
2854 for(i = 0; i < NUMCORES4GC; ++i) {
2856 BASEPTR(i, numpbc, &tmpcoreptr);
2857 //send start compact messages to all cores
2858 //TODO bug here, do not know if the direction is positive or negtive?
2859 if (tmpcoreptr < tmpheaptop /*tmptopptr*/) {
2860 gcstopblock[i] = numpbc + 1;
2861 if(i != STARTUPCORE) {
2862 send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
2864 gcblock2fill = numpbc+1;
2865 } // if(i != STARTUPCORE)
2867 gcstopblock[i] = numpbc;
2868 if(i != STARTUPCORE) {
2869 send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
2871 gcblock2fill = numpbc;
2872 } // if(i != STARTUPCORE)
2875 BAMBOO_DEBUGPRINT(0xf000+i);
2876 BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
2877 BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
2879 // init some data strutures for compact phase
2881 gcfilledblocks[i] = 0;
2882 gcrequiredmems[i] = 0;
2890 bool finalcompact = false;
2891 // initialize pointers for comapcting
2892 struct moveHelper * orig =
2893 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2894 struct moveHelper * to =
2895 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2896 initOrig_Dst(orig, to);
2897 int filledblocks = 0;
2898 INTPTR heaptopptr = 0;
2899 bool finishcompact = false;
2900 bool iscontinue = true;
2901 bool localcompact = true;
2902 while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
2903 if((!finishcompact) && iscontinue) {
2905 BAMBOO_DEBUGPRINT(0xe001);
2906 BAMBOO_DEBUGPRINT_REG(numpbc);
2907 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2909 finishcompact = compacthelper(orig, to, &filledblocks,
2910 &heaptopptr, &localcompact);
2912 BAMBOO_DEBUGPRINT(0xe002);
2913 BAMBOO_DEBUGPRINT_REG(finishcompact);
2914 BAMBOO_DEBUGPRINT_REG(gctomove);
2915 BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
2916 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
2917 BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
2921 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2922 if(gc_checkCoreStatus_I()) {
2923 // all cores have finished compacting
2924 // restore the gcstatus of all cores
2925 for(i = 0; i < NUMCORES4GC; ++i) {
2926 gccorestatus[i] = 1;
2928 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2931 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2932 // check if there are spare mem for pending move requires
2933 if(COMPACTPHASE == gcphase) {
2935 BAMBOO_DEBUGPRINT(0xe003);
2937 resolvePendingMoveRequest();
2939 BAMBOO_DEBUGPRINT_REG(gctomove);
2943 BAMBOO_DEBUGPRINT(0xe004);
2947 } // if(gc_checkCoreStatus_I()) else ...
2951 BAMBOO_DEBUGPRINT(0xe005);
2952 BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
2953 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2954 BAMBOO_DEBUGPRINT_REG(gctomove);
2956 to->ptr = gcmovestartaddr;
2957 to->numblocks = gcblock2fill - 1;
2958 to->bound = (to->numblocks==0) ?
2959 BAMBOO_SMEM_SIZE_L :
2960 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2961 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2962 to->offset = to->ptr - to->base;
2963 to->top = (to->numblocks==0) ?
2964 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2966 to->offset = BAMBOO_CACHE_LINE_SIZE;
2967 to->ptr += to->offset; // for header
2968 to->top += to->offset;
2969 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2970 localcompact = true;
2972 localcompact = false;
2976 } else if(!finishcompact) {
2981 } // while(COMPACTPHASE == gcphase)
2985 #ifdef RAWPATH // TODO GC_DEBUG
2986 printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
2987 udn_tile_coord_y());
2992 #ifdef RAWPATH // TODO GC_DEBUG
2993 printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
2994 udn_tile_coord_y());
3001 gcphase = FLUSHPHASE;
3002 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3003 // Note: all cores should flush their runtime data including non-gc
3005 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3006 // send start flush messages to all cores
3007 gccorestatus[i] = 1;
3008 send_msg_1(i, GCSTARTFLUSH, false);
3013 #ifdef RAWPATH // TODO GC_DEBUG
3014 printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
3015 udn_tile_coord_y());
3019 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3020 while(FLUSHPHASE == gcphase) {
3021 // check the status of all cores
3022 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3023 if(gc_checkAllCoreStatus_I()) {
3024 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3027 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3028 } // while(FLUSHPHASE == gcphase)
3029 gcphase = FINISHPHASE;
3031 // invalidate all shared mem pointers
3032 // put it here as it takes time to inform all the other cores to
3033 // finish gc and it might cause problem when some core resumes
3034 // mutator earlier than the other cores
3035 bamboo_cur_msp = NULL;
3036 bamboo_smem_size = 0;
3038 gcprocessing = false;
3043 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3044 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3045 // send gc finish messages to all cores
3046 send_msg_1(i, GCFINISH, false);
3047 gccorestatus[i] = 1;
3049 #ifdef RAWPATH // TODO GC_DEBUG
3050 printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
3051 udn_tile_coord_y());
3054 } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
3055 gcprocessing = true;
3056 gc_collect(stackptr);
3058 // invalidate all shared mem pointers
3059 bamboo_cur_msp = NULL;
3060 bamboo_smem_size = 0;
3063 gcprocessing = false;
3065 // not a gc core, should wait for gcfinish msg
3066 gcprocessing = true;
3067 gc_nocollect(stackptr);
3069 // invalidate all shared mem pointers
3070 bamboo_cur_msp = NULL;
3071 bamboo_smem_size = 0;
3074 gcprocessing = false;
3076 } // void gc(struct garbagelist * stackptr)
3079 inline void gc_profileStart(void) {
3080 if(!gc_infoOverflow) {
3081 GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
3082 gc_infoArray[gc_infoIndex] = gcInfo;
3084 gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
3088 inline void gc_profileItem(void) {
3089 if(!gc_infoOverflow) {
3090 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3091 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3095 inline void gc_profileEnd(void) {
3096 if(!gc_infoOverflow) {
3097 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3098 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3100 if(gc_infoIndex == GCINFOLENGTH) {
3101 gc_infoOverflow = true;
3102 //taskInfoIndex = 0;
3107 // output the profiling data
3108 void gc_outputProfileData() {
3111 unsigned long long totalgc = 0;
3113 //printf("Start Time, End Time, Duration\n");
3114 // output task related info
3115 for(i = 0; i < gc_infoIndex; i++) {
3116 GCInfo * gcInfo = gc_infoArray[i];
3117 unsigned long long tmp = 0;
3118 for(j = 0; j < gcInfo->index; j++) {
3119 printf("%lld(%lld), ", gcInfo->time[j], (gcInfo->time[j]-tmp));
3120 tmp = gcInfo->time[j];
3122 tmp = (tmp-gcInfo->time[0]);
3123 printf(" ++ %lld \n", tmp);
3127 if(gc_infoOverflow) {
3128 printf("Caution: gc info overflow!\n");
3131 printf("\n\n total gc time: %lld \n", totalgc);
3135 unsigned long long totalgc = 0;
3137 BAMBOO_DEBUGPRINT(0xdddd);
3138 // output task related info
3139 for(i= 0; i < gc_infoIndex; i++) {
3140 GCInfo * gcInfo = gc_infoArray[i];
3141 unsigned long long tmp = 0;
3142 BAMBOO_DEBUGPRINT(0xddda);
3143 for(j = 0; j < gcInfo->index; j++) {
3144 BAMBOO_DEBUGPRINT(gcInfo->time[j]);
3145 BAMBOO_DEBUGPRINT(gcInfo->time[j]-tmp);
3146 BAMBOO_DEBUGPRINT(0xdddb);
3147 tmp = gcInfo->time[j];
3149 tmp = (tmp-gcInfo->time[0]);
3150 BAMBOO_DEBUGPRINT_REG(tmp);
3151 BAMBOO_DEBUGPRINT(0xdddc);
3154 BAMBOO_DEBUGPRINT(0xdddd);
3155 BAMBOO_DEBUGPRINT_REG(totalgc);
3157 if(gc_infoOverflow) {
3158 BAMBOO_DEBUGPRINT(0xefee);
3161 BAMBOO_DEBUGPRINT(0xeeee);
3164 #endif // #ifdef GC_PROFILE