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;
30 extern unsigned int gcmem_mixed_threshold;
31 extern unsigned int gcmem_mixed_usedmem;
36 struct pointerblock *next;
39 struct pointerblock *gchead=NULL;
41 struct pointerblock *gctail=NULL;
43 struct pointerblock *gctail2=NULL;
45 struct pointerblock *gcspare=NULL;
47 #define NUMLOBJPTRS 20
49 struct lobjpointerblock {
50 void * lobjs[NUMLOBJPTRS];
51 //void * dsts[NUMLOBJPTRS];
52 int lengths[NUMLOBJPTRS];
53 //void * origs[NUMLOBJPTRS];
54 int hosts[NUMLOBJPTRS];
55 struct lobjpointerblock *next;
56 struct lobjpointerblock *prev;
59 struct lobjpointerblock *gclobjhead=NULL;
60 int gclobjheadindex=0;
61 struct lobjpointerblock *gclobjtail=NULL;
62 int gclobjtailindex=0;
63 struct lobjpointerblock *gclobjtail2=NULL;
64 int gclobjtailindex2=0;
65 struct lobjpointerblock *gclobjspare=NULL;
68 // dump whole mem in blocks
69 inline void dumpSMem() {
77 printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
79 // reserved blocks for sblocktbl
80 printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
82 for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
83 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",
84 udn_tile_coord_x(), udn_tile_coord_y(),
85 *((int *)(i)), *((int *)(i + 4)),
86 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
87 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
88 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
89 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
90 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
91 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
92 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
94 sblock = gcreservedsb;
95 bool advanceblock = false;
97 for(i=gcbaseva; i<BAMBOO_BASE_VA+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
99 // computing sblock # and block #, core coordinate (x,y) also
100 if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
102 if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
103 if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
115 coren = gc_block2core[block%(NUMCORES4GC*2)];
117 // compute core coordinate
118 BAMBOO_COORDS(coren, &x, &y);
119 printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
120 udn_tile_coord_x(), udn_tile_coord_y(),
121 block, sblock++, x, y,
122 (sblock-1)*(BAMBOO_SMEM_SIZE)+BAMBOO_BASE_VA);
125 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",
126 udn_tile_coord_x(), udn_tile_coord_y(),
127 *((int *)(i)), *((int *)(i + 4)),
128 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
129 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
130 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
131 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
132 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
133 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
134 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
136 printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
140 // should be invoked with interruption closed
141 inline void gc_enqueue_I(void *ptr) {
143 BAMBOO_DEBUGPRINT(0xe601);
144 BAMBOO_DEBUGPRINT_REG(ptr);
146 if (gcheadindex==NUMPTRS) {
147 struct pointerblock * tmp;
152 tmp=RUNMALLOC_I(sizeof(struct pointerblock));
153 } // if (gcspare!=NULL)
157 } // if (gcheadindex==NUMPTRS)
158 gchead->ptrs[gcheadindex++]=ptr;
160 BAMBOO_DEBUGPRINT(0xe602);
162 } // void gc_enqueue_I(void *ptr)
164 // dequeue and destroy the queue
165 inline void * gc_dequeue_I() {
166 if (gctailindex==NUMPTRS) {
167 struct pointerblock *tmp=gctail;
174 } // if (gcspare!=NULL)
175 } // if (gctailindex==NUMPTRS)
176 return gctail->ptrs[gctailindex++];
177 } // void * gc_dequeue()
179 // dequeue and do not destroy the queue
180 inline void * gc_dequeue2_I() {
181 if (gctailindex2==NUMPTRS) {
182 struct pointerblock *tmp=gctail2;
183 gctail2=gctail2->next;
185 } // if (gctailindex2==NUMPTRS)
186 return gctail2->ptrs[gctailindex2++];
187 } // void * gc_dequeue2()
189 inline int gc_moreItems_I() {
190 if ((gchead==gctail)&&(gctailindex==gcheadindex))
193 } // int gc_moreItems()
195 inline int gc_moreItems2_I() {
196 if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
199 } // int gc_moreItems2()
201 // should be invoked with interruption closed
202 // enqueue a large obj: start addr & length
203 inline void gc_lobjenqueue_I(void *ptr,
207 BAMBOO_DEBUGPRINT(0xe901);
209 if (gclobjheadindex==NUMLOBJPTRS) {
210 struct lobjpointerblock * tmp;
211 if (gclobjspare!=NULL) {
215 tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
216 } // if (gclobjspare!=NULL)
217 gclobjhead->next=tmp;
218 tmp->prev = gclobjhead;
221 } // if (gclobjheadindex==NUMLOBJPTRS)
222 gclobjhead->lobjs[gclobjheadindex]=ptr;
223 gclobjhead->lengths[gclobjheadindex]=length;
224 gclobjhead->hosts[gclobjheadindex++]=host;
226 BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
227 BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
228 BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
230 } // void gc_lobjenqueue_I(void *ptr...)
232 // dequeue and destroy the queue
233 inline void * gc_lobjdequeue_I(int * length,
235 if (gclobjtailindex==NUMLOBJPTRS) {
236 struct lobjpointerblock *tmp=gclobjtail;
237 gclobjtail=gclobjtail->next;
239 gclobjtail->prev = NULL;
240 if (gclobjspare!=NULL) {
246 } // if (gclobjspare!=NULL)
247 } // if (gclobjtailindex==NUMLOBJPTRS)
249 *length = gclobjtail->lengths[gclobjtailindex];
252 *host = (int)(gclobjtail->hosts[gclobjtailindex]);
254 return gclobjtail->lobjs[gclobjtailindex++];
255 } // void * gc_lobjdequeue()
257 inline int gc_lobjmoreItems_I() {
258 if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
261 } // int gc_lobjmoreItems()
263 // dequeue and don't destroy the queue
264 inline void gc_lobjdequeue2_I() {
265 if (gclobjtailindex2==NUMLOBJPTRS) {
266 gclobjtail2=gclobjtail2->next;
270 } // if (gclobjtailindex2==NUMLOBJPTRS)
271 } // void * gc_lobjdequeue2()
273 inline int gc_lobjmoreItems2_I() {
274 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
277 } // int gc_lobjmoreItems2()
279 // 'reversly' dequeue and don't destroy the queue
280 inline void gc_lobjdequeue3_I() {
281 if (gclobjtailindex2==0) {
282 gclobjtail2=gclobjtail2->prev;
283 gclobjtailindex2=NUMLOBJPTRS-1;
286 } // if (gclobjtailindex2==NUMLOBJPTRS)
287 } // void * gc_lobjdequeue3()
289 inline int gc_lobjmoreItems3_I() {
290 if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
293 } // int gc_lobjmoreItems3()
295 inline void gc_lobjqueueinit4_I() {
296 gclobjtail2 = gclobjtail;
297 gclobjtailindex2 = gclobjtailindex;
298 } // void gc_lobjqueueinit2()
300 inline void * gc_lobjdequeue4_I(int * length,
302 if (gclobjtailindex2==NUMLOBJPTRS) {
303 gclobjtail2=gclobjtail2->next;
305 } // if (gclobjtailindex==NUMLOBJPTRS)
307 *length = gclobjtail2->lengths[gclobjtailindex2];
310 *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
312 return gclobjtail2->lobjs[gclobjtailindex2++];
313 } // void * gc_lobjdequeue()
315 inline int gc_lobjmoreItems4_I() {
316 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
319 } // int gc_lobjmoreItems(
321 INTPTR gccurr_heapbound = 0;
323 inline void gettype_size(void * ptr,
326 int type = ((int *)ptr)[0];
328 if(type < NUMCLASSES) {
330 size = classsize[type];
333 struct ArrayObject *ao=(struct ArrayObject *)ptr;
334 int elementsize=classsize[type];
335 int length=ao->___length___;
336 size=sizeof(struct ArrayObject)+length*elementsize;
337 } // if(type < NUMCLASSES)
342 inline bool isLarge(void * ptr,
346 BAMBOO_DEBUGPRINT(0xe701);
347 BAMBOO_DEBUGPRINT_REG(ptr);
349 // check if a pointer is referring to a large object
350 gettype_size(ptr, ttype, tsize);
352 BAMBOO_DEBUGPRINT(*tsize);
354 int bound = (BAMBOO_SMEM_SIZE);
355 if(((int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
356 bound = (BAMBOO_SMEM_SIZE_L);
358 if((((int)ptr-gcbaseva)%(bound))==0) {
359 // ptr is a start of a block
361 BAMBOO_DEBUGPRINT(0xe702);
362 BAMBOO_DEBUGPRINT(1);
366 if((bound-(((int)ptr-gcbaseva)%bound)) < (*tsize)) {
367 // it acrosses the boundary of current block
369 BAMBOO_DEBUGPRINT(0xe703);
370 BAMBOO_DEBUGPRINT(1);
375 BAMBOO_DEBUGPRINT(0);
378 } // bool isLarge(void * ptr, int * ttype, int * tsize)
380 inline int hostcore(void * ptr) {
381 // check the host core of ptr
383 RESIDECORE(ptr, &host);
385 BAMBOO_DEBUGPRINT(0xedd0);
386 BAMBOO_DEBUGPRINT_REG(ptr);
387 BAMBOO_DEBUGPRINT_REG(host);
390 } // int hostcore(void * ptr)
392 inline bool isLocal(void * ptr) {
393 // check if a pointer is in shared heap on this core
394 return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
395 } // bool isLocal(void * ptr)
397 inline bool gc_checkCoreStatus_I() {
398 bool allStall = true;
399 for(int i = 0; i < NUMCORES4GC; ++i) {
400 if(gccorestatus[i] != 0) {
403 } // if(gccorestatus[i] != 0)
404 } // for(i = 0; i < NUMCORES4GC; ++i)
408 inline bool gc_checkAllCoreStatus_I() {
409 bool allStall = true;
410 for(int i = 0; i < NUMCORESACTIVE; ++i) {
411 if(gccorestatus[i] != 0) {
414 } // if(gccorestatus[i] != 0)
415 } // for(i = 0; i < NUMCORESACTIVE; ++i)
419 inline void checkMarkStatue() {
421 BAMBOO_DEBUGPRINT(0xee01);
425 (waitconfirm && (numconfirm == 0))) {
427 BAMBOO_DEBUGPRINT(0xee02);
429 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
430 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
431 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
432 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
433 // check the status of all cores
434 bool allStall = gc_checkAllCoreStatus_I();
436 BAMBOO_DEBUGPRINT(0xee03);
440 BAMBOO_DEBUGPRINT(0xee04);
445 BAMBOO_DEBUGPRINT(0xee05);
447 // the first time found all cores stall
448 // send out status confirm msg to all other cores
449 // reset the corestatus array too
450 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
452 numconfirm = NUMCORESACTIVE - 1;
453 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
454 for(i = 1; i < NUMCORESACTIVE; ++i) {
456 // send mark phase finish confirm request msg to core i
457 send_msg_1(i, GCMARKCONFIRM, false);
458 } // for(i = 1; i < NUMCORESACTIVE; ++i)
460 // check if the sum of send objs and receive obj are the same
461 // yes->check if the info is the latest; no->go on executing
463 for(i = 0; i < NUMCORESACTIVE; ++i) {
464 sumsendobj += gcnumsendobjs[i];
465 } // for(i = 0; i < NUMCORESACTIVE; ++i)
467 BAMBOO_DEBUGPRINT(0xee06);
468 BAMBOO_DEBUGPRINT_REG(sumsendobj);
470 for(i = 0; i < NUMCORESACTIVE; ++i) {
471 sumsendobj -= gcnumreceiveobjs[i];
472 } // for(i = 0; i < NUMCORESACTIVE; ++i)
474 BAMBOO_DEBUGPRINT(0xee07);
475 BAMBOO_DEBUGPRINT_REG(sumsendobj);
477 if(0 == sumsendobj) {
479 BAMBOO_DEBUGPRINT(0xee08);
481 // all the core status info are the latest
483 gcphase = COMPACTPHASE;
484 // restore the gcstatus for all cores
485 for(i = 0; i < NUMCORESACTIVE; ++i) {
487 } // for(i = 0; i < NUMCORESACTIVE; ++i)
489 // wait for a while and ask for confirm again
494 } // if(0 == sumsendobj) else ...
495 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
496 } // if(!gcwaitconfirm) else()
498 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
500 } // if((!waitconfirm)...
502 BAMBOO_DEBUGPRINT(0xee0a);
504 } // void checkMarkStatue()
506 inline bool preGC() {
507 // preparation for gc
508 // make sure to clear all incoming msgs espacially transfer obj msgs
510 BAMBOO_DEBUGPRINT(0xec01);
514 (waitconfirm && (numconfirm == 0))) {
515 // send out status confirm msgs to all cores to check if there are
516 // transfer obj msgs on-the-fly
518 numconfirm = NUMCORESACTIVE - 1;
519 for(i = 1; i < NUMCORESACTIVE; ++i) {
521 // send status confirm msg to core i
522 send_msg_1(i, STATUSCONFIRM, false);
523 } // for(i = 1; i < NUMCORESACTIVE; ++i)
526 BAMBOO_DEBUGPRINT(0xec02);
529 if(numconfirm == 0) {
532 } // wait for confirmations
536 BAMBOO_DEBUGPRINT(0xec03);
538 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
539 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
542 BAMBOO_DEBUGPRINT(0xec04);
544 for(i = 0; i < NUMCORESACTIVE; ++i) {
545 sumsendobj += numsendobjs[i];
547 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
549 } // for(i = 1; i < NUMCORESACTIVE; ++i)
551 BAMBOO_DEBUGPRINT(0xec05);
552 BAMBOO_DEBUGPRINT_REG(sumsendobj);
554 for(i = 0; i < NUMCORESACTIVE; ++i) {
555 sumsendobj -= numreceiveobjs[i];
557 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
559 } // for(i = 1; i < NUMCORESACTIVE; ++i)
561 BAMBOO_DEBUGPRINT(0xec06);
562 BAMBOO_DEBUGPRINT_REG(sumsendobj);
564 if(0 == sumsendobj) {
567 // still have some transfer obj msgs on-the-fly, can not start gc
569 } // if(0 == sumsendobj)
572 BAMBOO_DEBUGPRINT(0xec07);
574 // previously asked for status confirmation and do not have all the
575 // confirmations yet, can not start gc
577 } // if((!waitconfirm) ||
580 inline void initGC() {
582 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
583 for(i = 0; i < NUMCORES4GC; ++i) {
585 gcnumsendobjs[i] = 0;
586 gcnumreceiveobjs[i] = 0;
588 gcrequiredmems[i] = 0;
589 gcfilledblocks[i] = 0;
591 } // for(i = 0; i < NUMCORES4GC; ++i)
592 for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
594 gcnumsendobjs[i] = 0;
595 gcnumreceiveobjs[i] = 0;
600 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
601 gcself_numsendobjs = 0;
602 gcself_numreceiveobjs = 0;
603 gcmarkedptrbound = 0;
606 //gcismapped = false;
617 gcheadindex=gctailindex=gctailindex2 = 0;
618 gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
620 gctailindex = gctailindex2 = gcheadindex;
621 gctail = gctail2 = gchead;
624 // initialize the large obj queues
625 if (gclobjhead==NULL) {
628 gclobjtailindex2 = 0;
629 gclobjhead=gclobjtail=gclobjtail2=
630 RUNMALLOC(sizeof(struct lobjpointerblock));
632 gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
633 gclobjtail = gclobjtail2 = gclobjhead;
635 gclobjhead->next = gclobjhead->prev = NULL;
637 freeRuntimeHash(gcpointertbl);
638 gcpointertbl = allocateRuntimeHash(20);
639 //gcpointertbl = allocateMGCHash(20);
642 freeMGCHash(gcforwardobjtbl);
643 gcforwardobjtbl = allocateMGCHash(20, 3);
645 // initialize the mapping info related structures
646 if((BAMBOO_NUM_OF_CORE < NUMCORES4GC) && (gcsharedptbl != NULL)) {
647 // Never free the shared hash table, just reset it
648 /*freeGCSharedHash(gcsharedptbl);
649 gcsharedptbl = allocateGCSharedHash(20);*/
650 mgcsharedhashReset(gcsharedptbl);
652 // the shared hash tables are never changed
653 //BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(struct RuntimeHash *)*NUMCORES4GC);
656 num_mapinforequest = 0;
657 num_mapinforequest_i = 0;
659 flushstalltime_i = 0;
665 // compute load balance for all cores
666 inline int loadbalance(int * heaptop) {
667 // compute load balance
670 // get the total loads
671 int tloads = gcloads[STARTUPCORE];
672 for(i = 1; i < NUMCORES4GC; i++) {
673 tloads += gcloads[i];
675 *heaptop = gcbaseva + tloads;
677 BAMBOO_DEBUGPRINT(0xdddd);
678 BAMBOO_DEBUGPRINT_REG(tloads);
679 BAMBOO_DEBUGPRINT_REG(*heaptop);
682 BLOCKINDEX(*heaptop, &b);
683 int numbpc = b / NUMCORES4GC; // num of blocks per core
685 BAMBOO_DEBUGPRINT_REG(b);
686 BAMBOO_DEBUGPRINT_REG(numbpc);
689 RESIDECORE(heaptop, &gctopcore);
691 BAMBOO_DEBUGPRINT_REG(gctopcore);
694 } // void loadbalance(int * heaptop)
696 inline bool cacheLObjs() {
697 // check the total mem size need for large objs
701 BAMBOO_DEBUGPRINT(0xe801);
703 gclobjtail2 = gclobjtail;
704 gclobjtailindex2 = gclobjtailindex;
708 // compute total mem size required and sort the lobjs in ascending order
709 while(gc_lobjmoreItems2_I()) {
711 tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
712 tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
713 tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
716 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
717 BAMBOO_DEBUGPRINT_REG(tmp_len);
718 BAMBOO_DEBUGPRINT_REG(sumsize);
720 int i = gclobjtailindex2-1;
721 struct lobjpointerblock * tmp_block = gclobjtail2;
722 // find the place to insert
725 if(tmp_block->prev == NULL) {
728 if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
729 tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
730 tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
731 tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
732 tmp_block = tmp_block->prev;
736 } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
738 if(tmp_block->lobjs[i-1] > tmp_lobj) {
739 tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
740 tmp_block->lengths[i] = tmp_block->lengths[i-1];
741 tmp_block->hosts[i] = tmp_block->hosts[i-1];
745 } // if(tmp_block->lobjs[i-1] < tmp_lobj)
746 } // if(i ==0 ) else {}
749 if(i != gclobjtailindex2 - 1) {
750 tmp_block->lobjs[i] = tmp_lobj;
751 tmp_block->lengths[i] = tmp_len;
752 tmp_block->hosts[i] = tmp_host;
754 } // while(gc_lobjmoreItems2())
756 // check if there are enough space to cache these large objs
757 INTPTR dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
758 if(gcheaptop > dst) {
759 // do not have enough room to cache large objs
761 BAMBOO_DEBUGPRINT(0xe802);
762 BAMBOO_DEBUGPRINT_REG(dst);
763 BAMBOO_DEBUGPRINT_REG(gcheaptop);
768 BAMBOO_DEBUGPRINT(0xe803);
769 BAMBOO_DEBUGPRINT_REG(dst);
770 BAMBOO_DEBUGPRINT_REG(gcheaptop);
773 gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
774 // cache the largeObjs to the top of the shared heap
775 //gclobjtail2 = gclobjtail;
776 //gclobjtailindex2 = gclobjtailindex;
777 dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
778 while(gc_lobjmoreItems3_I()) {
780 size = gclobjtail2->lengths[gclobjtailindex2];
781 // set the mark field to , indicating that this obj has been moved
782 // and need to be flushed
783 ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[6] = COMPACTED;
785 if((int)dst < (int)(gclobjtail2->lobjs[gclobjtailindex2])+size) {
786 memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
788 //BAMBOO_WRITE_HINT_CACHE(dst, size);
789 memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
792 BAMBOO_DEBUGPRINT(0x804);
793 BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
794 BAMBOO_DEBUGPRINT(dst);
795 BAMBOO_DEBUGPRINT_REG(size);
796 BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
797 BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
801 } // void cacheLObjs()
803 // update the bmmboo_smemtbl to record current shared mem usage
804 void updateSmemTbl(int coren,
807 int bound = BAMBOO_SMEM_SIZE_L;
808 BLOCKINDEX(localtop, <opcore);
809 if(localtop >= (gcbaseva+(BAMBOO_LARGE_SMEM_BOUND))) {
810 bound = BAMBOO_SMEM_SIZE;
812 int load = (localtop-gcbaseva)%bound;
817 toset = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
818 if(toset < ltopcore) {
819 bamboo_smemtbl[toset]=
820 (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
822 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
824 } else if(toset == ltopcore) {
825 bamboo_smemtbl[toset] = load;
827 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
839 } // void updateSmemTbl(int, int)
841 inline void moveLObjs() {
843 BAMBOO_DEBUGPRINT(0xea01);
846 // update the gcmem_mixed_usedmem
847 gcmem_mixed_usedmem = 0;
849 // zero out the smemtbl
850 BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
851 // find current heap top
852 // flush all gcloads to indicate the real heap top on one core
853 // previous it represents the next available ptr on a core
854 if((gcloads[0] > (gcbaseva+(BAMBOO_SMEM_SIZE_L)))
855 && ((gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
856 // edge of a block, check if this is exactly the heaptop
857 BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
858 gcloads[0]+=(gcfilledblocks[0]>1 ?
859 (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
861 updateSmemTbl(0, gcloads[0]);
863 BAMBOO_DEBUGPRINT(0xea02);
864 BAMBOO_DEBUGPRINT_REG(gcloads[0]);
865 BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
867 for(int i = 1; i < NUMCORES4GC; i++) {
870 BAMBOO_DEBUGPRINT(0xf000+i);
871 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
872 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
874 if((gcfilledblocks[i] > 0)
875 && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
876 // edge of a block, check if this is exactly the heaptop
877 BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
879 +=(gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
882 updateSmemTbl(i, gcloads[i]);
884 BAMBOO_DEBUGPRINT_REG(gcloads[i]);
886 } // for(int i = 1; i < NUMCORES4GC; i++) {
888 // find current heap top
890 // a bug here: when using local allocation, directly move large objects
891 // to the highest free chunk might not be memory efficient
896 for(i = gcnumblock-1; i >= 0; i--) {
897 if(bamboo_smemtbl[i] > 0) {
902 tmpheaptop = gcbaseva;
904 tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
905 (BAMBOO_SMEM_SIZE_L*i) :
906 (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
909 // move large objs from gcheaptop to tmpheaptop
910 // write the header first
911 unsigned int tomove = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) -gcheaptop;
913 gcmem_mixed_usedmem += tomove;
916 BAMBOO_DEBUGPRINT(0xea03);
917 BAMBOO_DEBUGPRINT_REG(tomove);
918 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
919 BAMBOO_DEBUGPRINT_REG(gcheaptop);
921 // flush the sbstartbl
922 BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
923 (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-gcreservedsb)*sizeof(INTPTR));
925 gcheaptop = tmpheaptop;
927 // check how many blocks it acrosses
928 int remain = tmpheaptop-gcbaseva;
929 int sb = remain/(BAMBOO_SMEM_SIZE) + gcreservedsb;//number of the sblock
930 int b = 0; // number of the block
931 BLOCKINDEX(tmpheaptop, &b);
932 // check the remaining space in this block
933 bound = (BAMBOO_SMEM_SIZE);
934 if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
935 bound = (BAMBOO_SMEM_SIZE_L);
937 remain = bound - remain%bound;
940 BAMBOO_DEBUGPRINT(0xea04);
946 int base = tmpheaptop;
948 remain -= BAMBOO_CACHE_LINE_SIZE;
949 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
950 gc_lobjqueueinit4_I();
951 while(gc_lobjmoreItems4_I()) {
952 ptr = (int)(gc_lobjdequeue4_I(&size, &host));
953 ALIGNSIZE(size, &isize);
955 // this object acrosses blocks
957 // close current block, fill its header
958 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
959 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
960 bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE;// add the size of the header
964 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
965 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
967 remain -= BAMBOO_CACHE_LINE_SIZE;
968 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
969 BLOCKINDEX(tmpheaptop, &b);
970 sb = (tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE) + gcreservedsb;
973 // move the large obj
974 if((int)gcheaptop < (int)(tmpheaptop)+size) {
975 memmove(tmpheaptop, gcheaptop, size);
977 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
978 memcpy(tmpheaptop, gcheaptop, size);
980 // fill the remaining space with -2 padding
981 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
982 // zero out original mem caching the lobj
983 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
985 BAMBOO_DEBUGPRINT(0xea05);
986 BAMBOO_DEBUGPRINT_REG(gcheaptop);
987 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
988 BAMBOO_DEBUGPRINT_REG(size);
989 BAMBOO_DEBUGPRINT_REG(isize);
990 BAMBOO_DEBUGPRINT_REG(base);
993 // cache the mapping info anyway
994 //if(ptr != tmpheaptop) {
995 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
996 //mgchashInsert_I(ptr, tmpheaptop);
997 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
998 //struct nodemappinginfo * nodeinfo = NULL;
999 //RuntimeHashget(gcpointertbl, ptr, &nodeinfo);
1000 //nodeinfo->ptr = tmpheaptop;
1001 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
1002 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1005 BAMBOO_DEBUGPRINT(0xcdca);
1006 BAMBOO_DEBUGPRINT_REG(ptr);
1007 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1009 if(host != BAMBOO_NUM_OF_CORE) {
1010 // send the original host core with the mapping info
1011 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
1013 BAMBOO_DEBUGPRINT(0xcdcb);
1014 BAMBOO_DEBUGPRINT_REG(ptr);
1015 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1017 } // if(host != BAMBOO_NUM_OF_CORE)
1018 tmpheaptop += isize;
1020 // set the gcsbstarttbl and bamboo_smemtbl
1021 int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
1022 for(int k = 1; k < tmpsbs; k++) {
1023 gcsbstarttbl[sb+k] = (INTPTR)(-1);
1026 bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1027 BLOCKINDEX(tmpheaptop-1, &tmpsbs);
1028 for(; b < tmpsbs; b++) {
1029 bamboo_smemtbl[b] = bound;
1030 if(b==NUMCORES4GC-1) {
1031 bound = BAMBOO_SMEM_SIZE;
1034 if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
1035 gcsbstarttbl[sb] = (INTPTR)(-1);
1036 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
1037 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1038 bamboo_smemtbl[b] = bound;
1040 gcsbstarttbl[sb] = (INTPTR)(tmpheaptop);
1041 remain = tmpheaptop-gcbaseva;
1042 bamboo_smemtbl[b] = remain%bound;
1043 remain = bound - bamboo_smemtbl[b];
1044 } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
1046 // close current block and fill the header
1047 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1048 *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
1051 if(remain == BAMBOO_CACHE_LINE_SIZE) {
1052 // fill with 0 in case
1053 BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
1055 remain -= BAMBOO_CACHE_LINE_SIZE;
1056 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
1059 // move the large obj
1060 if((int)gcheaptop < (int)(tmpheaptop)+size) {
1061 memmove(tmpheaptop, gcheaptop, size);
1063 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
1064 memcpy(tmpheaptop, gcheaptop, size);
1066 // fill the remaining space with -2 padding
1067 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
1068 // zero out original mem caching the lobj
1069 BAMBOO_MEMSET_WH(gcheaptop, '\0', size);
1071 BAMBOO_DEBUGPRINT(0xea06);
1072 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1073 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1074 BAMBOO_DEBUGPRINT_REG(size);
1075 BAMBOO_DEBUGPRINT_REG(isize);
1080 // cache the mapping info anyway
1081 //if(ptr != tmpheaptop) {
1082 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1083 //mgchashInsert_I(ptr, tmpheaptop);
1084 RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
1085 //struct nodemappinginfo * nodeinfo = NULL;
1086 //RuntimeHashget(gcpointertbl, ptr, &nodeinfo);
1087 //nodeinfo->ptr = tmpheaptop;
1088 //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
1089 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1092 BAMBOO_DEBUGPRINT(0xcdcc);
1093 BAMBOO_DEBUGPRINT_REG(ptr);
1094 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1095 BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
1097 if(host != BAMBOO_NUM_OF_CORE) {
1098 // send the original host core with the mapping info
1099 send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
1101 BAMBOO_DEBUGPRINT(0xcdcd);
1102 BAMBOO_DEBUGPRINT_REG(ptr);
1103 BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1105 } // if(host != BAMBOO_NUM_OF_CORE)
1106 tmpheaptop += isize;
1108 // update bamboo_smemtbl
1109 bamboo_smemtbl[b] += isize;
1110 } // if(remain < isize) else ...
1111 } // while(gc_lobjmoreItems())
1113 // close current block, fill the header
1114 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1115 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
1116 bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE; // add the size of the header
1118 tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
1120 gcheaptop = tmpheaptop;
1122 } // if(tomove == 0)
1125 BAMBOO_DEBUGPRINT(0xea07);
1126 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1129 bamboo_free_block = 0;
1132 tbound = (bamboo_free_block<NUMCORES4GC) ?
1133 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1134 if(bamboo_smemtbl[bamboo_free_block] == tbound) {
1135 bamboo_free_block++;
1137 // the first non-full partition
1142 BAMBOO_DEBUGPRINT(0xea08);
1143 BAMBOO_DEBUGPRINT_REG(gcheaptop);
1145 } // void moveLObjs()
1147 inline void markObj(void * objptr) {
1148 if(objptr == NULL) {
1151 if(ISSHAREDOBJ(objptr)) {
1152 int host = hostcore(objptr);
1153 if(BAMBOO_NUM_OF_CORE == host) {
1155 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1156 if(((int *)objptr)[6] == INIT) {
1157 // this is the first time that this object is discovered,
1158 // set the flag as DISCOVERED
1159 ((int *)objptr)[6] |= DISCOVERED;
1160 gc_enqueue_I(objptr);
1162 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1165 BAMBOO_DEBUGPRINT(0xbbbb);
1166 BAMBOO_DEBUGPRINT_REG(host);
1167 BAMBOO_DEBUGPRINT_REG(objptr);
1169 // check if this obj has been forwarded
1170 if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
1172 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
1174 // send a msg to host informing that objptr is active
1175 send_msg_2(host, GCMARKEDOBJ, objptr, /*BAMBOO_NUM_OF_CORE,*/ false);
1179 marktime += BAMBOO_GET_EXE_TIME() - ttime;
1180 num_markrequest++;*/
1182 gcself_numsendobjs++;
1183 MGCHashadd(gcforwardobjtbl, (int)objptr);
1187 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1188 gc_enqueue_I(objptr);
1189 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1190 } // if(ISSHAREDOBJ(objptr))
1191 } // void markObj(void * objptr)
1193 // enqueue root objs
1194 inline void tomark(struct garbagelist * stackptr) {
1195 if(MARKPHASE != gcphase) {
1197 BAMBOO_DEBUGPRINT_REG(gcphase);
1199 BAMBOO_EXIT(0xb101);
1201 gcbusystatus = true;
1205 // enqueue current stack
1206 while(stackptr!=NULL) {
1208 BAMBOO_DEBUGPRINT(0xe501);
1209 BAMBOO_DEBUGPRINT_REG(stackptr->size);
1210 BAMBOO_DEBUGPRINT_REG(stackptr->next);
1211 BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
1213 for(i=0; i<stackptr->size; i++) {
1214 if(stackptr->array[i] != NULL) {
1215 markObj(stackptr->array[i]);
1218 stackptr=stackptr->next;
1222 BAMBOO_DEBUGPRINT(0xe503);
1224 // enqueue objectsets
1225 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1226 for(i=0; i<NUMCLASSES; i++) {
1227 struct parameterwrapper ** queues =
1228 objectqueues[BAMBOO_NUM_OF_CORE][i];
1229 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
1230 for(j = 0; j < length; ++j) {
1231 struct parameterwrapper * parameter = queues[j];
1232 struct ObjectHash * set=parameter->objectset;
1233 struct ObjectNode * ptr=set->listhead;
1235 markObj((void *)ptr->key);
1242 // euqueue current task descriptor
1243 if(currtpd != NULL) {
1245 BAMBOO_DEBUGPRINT(0xe504);
1247 for(i=0; i<currtpd->numParameters; i++) {
1248 markObj(currtpd->parameterArray[i]);
1253 BAMBOO_DEBUGPRINT(0xe505);
1255 // euqueue active tasks
1256 if(activetasks != NULL) {
1257 struct genpointerlist * ptr=activetasks->list;
1259 struct taskparamdescriptor *tpd=ptr->src;
1261 for(i=0; i<tpd->numParameters; i++) {
1262 markObj(tpd->parameterArray[i]);
1269 BAMBOO_DEBUGPRINT(0xe506);
1271 // enqueue cached transferred obj
1272 struct QueueItem * tmpobjptr = getHead(&objqueue);
1273 while(tmpobjptr != NULL) {
1274 struct transObjInfo * objInfo =
1275 (struct transObjInfo *)(tmpobjptr->objectptr);
1276 markObj(objInfo->objptr);
1277 tmpobjptr = getNextQueueItem(tmpobjptr);
1281 BAMBOO_DEBUGPRINT(0xe507);
1283 // enqueue cached objs to be transferred
1284 struct QueueItem * item = getHead(totransobjqueue);
1285 while(item != NULL) {
1286 struct transObjInfo * totransobj =
1287 (struct transObjInfo *)(item->objectptr);
1288 markObj(totransobj->objptr);
1289 item = getNextQueueItem(item);
1290 } // while(item != NULL)
1293 BAMBOO_DEBUGPRINT(0xe508);
1295 // enqueue lock related info
1296 for(i = 0; i < runtime_locklen; ++i) {
1297 markObj((void *)(runtime_locks[i].redirectlock));
1298 if(runtime_locks[i].value != NULL) {
1299 markObj((void *)(runtime_locks[i].value));
1303 } // void tomark(struct garbagelist * stackptr)
1305 inline void mark(bool isfirst,
1306 struct garbagelist * stackptr) {
1308 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed01);
1312 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed02);
1314 // enqueue root objs
1316 gccurr_heaptop = 0; // record the size of all active objs in this core
1317 // aligned but does not consider block boundaries
1318 gcmarkedptrbound = 0;
1321 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed03);
1324 bool checkfield = true;
1325 bool sendStall = false;
1327 while(MARKPHASE == gcphase) {
1329 if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed04);
1332 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1333 bool hasItems = gc_moreItems2_I();
1334 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1336 BAMBOO_DEBUGPRINT(0xed05);
1342 gcbusystatus = true;
1344 void * ptr = gc_dequeue2_I();
1347 BAMBOO_DEBUGPRINT_REG(ptr);
1352 // check if it is a shared obj
1353 if(ISSHAREDOBJ(ptr)) {
1354 // a shared obj, check if it is a local obj on this core
1355 int host = hostcore(ptr);
1356 bool islocal = (host == BAMBOO_NUM_OF_CORE);
1358 bool isnotmarked = ((((int *)ptr)[6] & DISCOVERED) != 0);
1359 if(isLarge(ptr, &type, &size) && isnotmarked) {
1360 // ptr is a large object and not marked or enqueued
1362 BAMBOO_DEBUGPRINT(0xecec);
1363 BAMBOO_DEBUGPRINT_REG(ptr);
1364 BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
1366 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1367 gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
1369 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1371 ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
1372 } else if(isnotmarked) {
1373 // ptr is an unmarked active object on this core
1374 ALIGNSIZE(size, &isize);
1375 gccurr_heaptop += isize;
1377 BAMBOO_DEBUGPRINT(0xaaaa);
1378 BAMBOO_DEBUGPRINT_REG(ptr);
1379 BAMBOO_DEBUGPRINT_REG(isize);
1380 BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
1383 ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
1385 if(ptr + size > gcmarkedptrbound) {
1386 gcmarkedptrbound = ptr + size;
1387 } // if(ptr + size > gcmarkedptrbound)
1389 // ptr is not an active obj or has been marked
1391 } // if(isLarge(ptr, &type, &size)) else ...
1392 } /* can never reach here
1395 if(BAMBOO_NUM_OF_CORE == 0) {
1396 BAMBOO_DEBUGPRINT(0xbbbb);
1397 BAMBOO_DEBUGPRINT_REG(host);
1398 BAMBOO_DEBUGPRINT_REG(ptr);
1401 // check if this obj has been forwarded
1402 if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
1403 // send a msg to host informing that ptr is active
1404 send_msg_2(host, GCMARKEDOBJ, ptr, false);
1405 gcself_numsendobjs++;
1406 MGCHashadd(gcforwardobjtbl, (int)ptr);
1409 }// if(isLocal(ptr)) else ...*/
1410 } // if(ISSHAREDOBJ(ptr))
1412 BAMBOO_DEBUGPRINT(0xed06);
1416 // scan all pointers in ptr
1417 unsigned INTPTR * pointer;
1418 pointer=pointerarray[type];
1420 /* Array of primitives */
1422 } else if (((INTPTR)pointer)==1) {
1423 /* Array of pointers */
1424 struct ArrayObject *ao=(struct ArrayObject *) ptr;
1425 int length=ao->___length___;
1427 for(j=0; j<length; j++) {
1429 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
1433 INTPTR size=pointer[0];
1435 for(i=1; i<=size; i++) {
1436 unsigned int offset=pointer[i];
1437 void * objptr=*((void **)(((char *)ptr)+offset));
1440 } // if (pointer==0) else if ... else ...
1442 } // while(gc_moreItems2())
1444 BAMBOO_DEBUGPRINT(0xed07);
1446 gcbusystatus = false;
1447 // send mark finish msg to core coordinator
1448 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1450 BAMBOO_DEBUGPRINT(0xed08);
1452 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
1453 gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
1454 gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
1455 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
1459 BAMBOO_DEBUGPRINT(0xed09);
1461 send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
1462 gcself_numsendobjs, gcself_numreceiveobjs, false);
1465 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
1467 BAMBOO_DEBUGPRINT(0xed0a);
1470 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1472 BAMBOO_DEBUGPRINT(0xed0b);
1476 } // while(MARKPHASE == gcphase)
1479 inline void compact2Heaptophelper_I(int coren,
1484 int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
1485 if(STARTUPCORE == coren) {
1487 gcmovestartaddr = *p;
1488 gcdstcore = gctopcore;
1489 gcblock2fill = *numblocks + 1;
1491 send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
1494 BAMBOO_DEBUGPRINT_REG(coren);
1495 BAMBOO_DEBUGPRINT_REG(gctopcore);
1496 BAMBOO_DEBUGPRINT_REG(*p);
1497 BAMBOO_DEBUGPRINT_REG(*numblocks+1);
1499 if(memneed < *remain) {
1501 BAMBOO_DEBUGPRINT(0xd104);
1504 gcrequiredmems[coren] = 0;
1505 gcloads[gctopcore] += memneed;
1506 *remain = *remain - memneed;
1509 BAMBOO_DEBUGPRINT(0xd105);
1511 // next available block
1513 gcfilledblocks[gctopcore] += 1;
1515 BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
1516 gcloads[gctopcore] = newbase;
1517 gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
1518 gcstopblock[gctopcore]++;
1519 gctopcore = NEXTTOPCORE(gctopblock);
1521 *numblocks = gcstopblock[gctopcore];
1522 *p = gcloads[gctopcore];
1524 *remain=(b<NUMCORES4GC) ?
1525 ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
1526 : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
1528 BAMBOO_DEBUGPRINT(0xd106);
1529 BAMBOO_DEBUGPRINT_REG(gctopcore);
1530 BAMBOO_DEBUGPRINT_REG(*p);
1531 BAMBOO_DEBUGPRINT_REG(b);
1532 BAMBOO_DEBUGPRINT_REG(*remain);
1534 } // if(memneed < remain)
1536 } // void compact2Heaptophelper_I(int, int*, int*, int*)
1538 inline void compact2Heaptop() {
1539 // no cores with spare mem and some cores are blocked with pending move
1540 // find the current heap top and make them move to the heap top
1542 int numblocks = gcfilledblocks[gctopcore];
1543 //BASEPTR(gctopcore, numblocks, &p);
1544 p = gcloads[gctopcore];
1547 int remain = (b<NUMCORES4GC) ?
1548 ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
1549 : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
1550 // check if the top core finishes
1551 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1552 if(gccorestatus[gctopcore] != 0) {
1554 BAMBOO_DEBUGPRINT(0xd101);
1555 BAMBOO_DEBUGPRINT_REG(gctopcore);
1557 // let the top core finishes its own work first
1558 compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
1559 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1562 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1565 BAMBOO_DEBUGPRINT(0xd102);
1566 BAMBOO_DEBUGPRINT_REG(gctopcore);
1567 BAMBOO_DEBUGPRINT_REG(p);
1568 BAMBOO_DEBUGPRINT_REG(b);
1569 BAMBOO_DEBUGPRINT_REG(remain);
1571 for(int i = 0; i < NUMCORES4GC; i++) {
1572 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1573 if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
1575 BAMBOO_DEBUGPRINT(0xd103);
1577 compact2Heaptophelper_I(i, &p, &numblocks, &remain);
1578 if(gccorestatus[gctopcore] != 0) {
1580 BAMBOO_DEBUGPRINT(0xd101);
1581 BAMBOO_DEBUGPRINT_REG(gctopcore);
1583 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1584 // the top core is not free now
1587 } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
1588 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1589 } // for(i = 0; i < NUMCORES4GC; i++)
1591 BAMBOO_DEBUGPRINT(0xd106);
1593 } // void compact2Heaptop()
1595 inline void resolvePendingMoveRequest() {
1597 BAMBOO_DEBUGPRINT(0xeb01);
1600 BAMBOO_DEBUGPRINT(0xeeee);
1601 for(int k = 0; k < NUMCORES4GC; k++) {
1602 BAMBOO_DEBUGPRINT(0xf000+k);
1603 BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
1604 BAMBOO_DEBUGPRINT_REG(gcloads[k]);
1605 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
1606 BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
1608 BAMBOO_DEBUGPRINT(0xffff);
1612 bool nosparemem = true;
1613 bool haspending = false;
1614 bool hasrunning = false;
1615 bool noblock = false;
1616 int dstcore = 0; // the core who need spare mem
1617 int sourcecore = 0; // the core who has spare mem
1618 for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
1620 // check if there are cores with spare mem
1621 if(gccorestatus[i] == 0) {
1622 // finished working, check if it still have spare mem
1623 if(gcfilledblocks[i] < gcstopblock[i]) {
1624 // still have spare mem
1627 } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
1632 if(gccorestatus[j] != 0) {
1633 // not finished, check if it has pending move requests
1634 if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
1639 } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
1640 } // if(gccorestatus[i] == 0) else ...
1642 } // if(!haspending)
1643 if(!nosparemem && haspending) {
1647 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1648 gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
1649 gcrequiredmems[dstcore],
1652 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1654 BAMBOO_DEBUGPRINT(0xeb02);
1655 BAMBOO_DEBUGPRINT_REG(sourcecore);
1656 BAMBOO_DEBUGPRINT_REG(dstcore);
1657 BAMBOO_DEBUGPRINT_REG(startaddr);
1658 BAMBOO_DEBUGPRINT_REG(tomove);
1660 if(STARTUPCORE == dstcore) {
1662 BAMBOO_DEBUGPRINT(0xeb03);
1664 gcdstcore = sourcecore;
1666 gcmovestartaddr = startaddr;
1667 gcblock2fill = tomove;
1670 BAMBOO_DEBUGPRINT(0xeb04);
1672 send_msg_4(dstcore, GCMOVESTART, sourcecore,
1673 startaddr, tomove, false);
1680 } // for(i = 0; i < NUMCORES4GC; i++)
1682 BAMBOO_DEBUGPRINT(0xcccc);
1683 BAMBOO_DEBUGPRINT_REG(hasrunning);
1684 BAMBOO_DEBUGPRINT_REG(haspending);
1685 BAMBOO_DEBUGPRINT_REG(noblock);
1688 if(!hasrunning && !noblock) {
1689 gcphase = SUBTLECOMPACTPHASE;
1693 } // void resovePendingMoveRequest()
1696 int numblocks; // block num for heap
1697 INTPTR base; // base virtual address of current heap block
1698 INTPTR ptr; // virtual address of current heap top
1699 int offset; // offset in current heap block
1700 int blockbase; // virtual address of current small block to check
1701 int blockbound; // bound virtual address of current small blcok
1702 int sblockindex; // index of the small blocks
1703 int top; // real size of current heap block to check
1704 int bound; // bound size of current heap block to check
1705 }; // struct moveHelper
1707 // if out of boundary of valid shared memory, return false, else return true
1708 inline bool nextSBlock(struct moveHelper * orig) {
1709 orig->blockbase = orig->blockbound;
1710 bool sbchanged = false;
1712 BAMBOO_DEBUGPRINT(0xecc0);
1713 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1714 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1715 BAMBOO_DEBUGPRINT_REG(orig->bound);
1716 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1719 // check if across a big block
1720 if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)
1721 || ((orig->ptr != NULL) && (*((int*)orig->ptr))==0)
1722 || ((*((int*)orig->blockbase))==0)) {
1724 // end of current heap block, jump to next one
1727 BAMBOO_DEBUGPRINT(0xecc1);
1728 BAMBOO_DEBUGPRINT_REG(orig->numblocks);
1730 BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
1732 BAMBOO_DEBUGPRINT(orig->base);
1734 if(orig->base >= BAMBOO_BASE_VA + BAMBOO_SHARED_MEM_SIZE) {
1736 orig->ptr = orig->base; // set current ptr to out of boundary too
1739 orig->bound = orig->base + BAMBOO_SMEM_SIZE;
1740 orig->blockbase = orig->base;
1741 orig->sblockindex = (orig->blockbase-BAMBOO_BASE_VA)/BAMBOO_SMEM_SIZE;
1744 BLOCKINDEX(orig->base, &blocknum);
1745 if(bamboo_smemtbl[blocknum] == 0) {
1747 goto innernextSBlock;
1749 } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
1750 orig->sblockindex += 1;
1752 } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
1754 // check if this sblock should be skipped or have special start point
1755 if(gcsbstarttbl[orig->sblockindex] == -1) {
1758 BAMBOO_DEBUGPRINT(0xecc2);
1760 orig->sblockindex += 1;
1761 orig->blockbase += BAMBOO_SMEM_SIZE;
1762 goto outernextSBlock;
1763 } else if((gcsbstarttbl[orig->sblockindex] != 0)
1765 // the first time to access this SBlock
1767 BAMBOO_DEBUGPRINT(0xecc3);
1769 // not start from the very beginning
1770 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1771 } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
1773 // setup information for this sblock
1774 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1775 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1776 orig->ptr = orig->blockbase + orig->offset;
1778 BAMBOO_DEBUGPRINT(0xecc4);
1779 BAMBOO_DEBUGPRINT_REG(orig->base);
1780 BAMBOO_DEBUGPRINT_REG(orig->bound);
1781 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1782 BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1783 BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1784 BAMBOO_DEBUGPRINT_REG(orig->offset);
1786 if(orig->ptr >= orig->bound) {
1787 // met a lobj, move to next block
1788 goto innernextSBlock;
1792 } // bool nextSBlock(struct moveHelper * orig)
1794 // return false if there are no available data to compact
1795 inline bool initOrig_Dst(struct moveHelper * orig,
1796 struct moveHelper * to) {
1799 to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
1800 to->bound = BAMBOO_SMEM_SIZE_L;
1801 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1804 BAMBOO_DEBUGPRINT(0xef01);
1805 BAMBOO_DEBUGPRINT_REG(to->base);
1807 to->ptr = to->base + to->offset;
1809 // init the orig ptr
1810 orig->numblocks = 0;
1811 orig->base = to->base;
1812 orig->bound = to->base + BAMBOO_SMEM_SIZE_L;
1813 orig->blockbase = orig->base;
1814 orig->sblockindex = (orig->base - BAMBOO_BASE_VA) / BAMBOO_SMEM_SIZE;
1816 BAMBOO_DEBUGPRINT(0xef02);
1817 BAMBOO_DEBUGPRINT_REG(orig->base);
1818 BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
1819 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
1820 BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
1823 if(gcsbstarttbl[orig->sblockindex] == -1) {
1825 BAMBOO_DEBUGPRINT(0xef03);
1829 BAMBOO_BASE_VA+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
1830 return nextSBlock(orig);
1831 } else if(gcsbstarttbl[orig->sblockindex] != 0) {
1833 BAMBOO_DEBUGPRINT(0xef04);
1835 orig->blockbase = gcsbstarttbl[orig->sblockindex];
1838 BAMBOO_DEBUGPRINT(0xef05);
1840 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1841 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1842 orig->ptr = orig->blockbase + orig->offset;
1844 BAMBOO_DEBUGPRINT(0xef06);
1845 BAMBOO_DEBUGPRINT_REG(orig->base);
1848 } // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
1850 inline void nextBlock(struct moveHelper * to) {
1851 to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
1852 to->bound += BAMBOO_SMEM_SIZE;
1854 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1855 to->offset = BAMBOO_CACHE_LINE_SIZE;
1856 to->ptr = to->base + to->offset;
1857 } // void nextBlock(struct moveHelper * to)
1859 // endaddr does not contain spaces for headers
1860 inline bool moveobj(struct moveHelper * orig,
1861 struct moveHelper * to,
1863 if(stopblock == 0) {
1868 BAMBOO_DEBUGPRINT(0xe201);
1869 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1870 BAMBOO_DEBUGPRINT_REG(to->ptr);
1878 while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
1879 orig->ptr = (int*)(orig->ptr) + 1;
1881 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
1882 if(!nextSBlock(orig)) {
1883 // finished, no more data
1889 BAMBOO_DEBUGPRINT(0xe202);
1890 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1891 BAMBOO_DEBUGPRINT(((int *)(orig->ptr))[0]);
1893 // check the obj's type, size and mark flag
1894 type = ((int *)(orig->ptr))[0];
1897 // end of this block, go to next one
1898 if(!nextSBlock(orig)) {
1899 // finished, no more data
1903 } else if(type < NUMCLASSES) {
1905 size = classsize[type];
1908 struct ArrayObject *ao=(struct ArrayObject *)(orig->ptr);
1909 int elementsize=classsize[type];
1910 int length=ao->___length___;
1911 size=sizeof(struct ArrayObject)+length*elementsize;
1913 mark = ((int *)(orig->ptr))[6];
1914 bool isremote = ((((int *)(orig->ptr))[6] & REMOTEM) != 0);
1916 BAMBOO_DEBUGPRINT(0xe203);
1917 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1918 BAMBOO_DEBUGPRINT_REG(size);
1920 ALIGNSIZE(size, &isize); // no matter is the obj marked or not
1921 // should be able to across it
1922 if((mark & MARKED) != 0) {
1924 BAMBOO_DEBUGPRINT(0xe204);
1926 // marked obj, copy it to current heap top
1927 // check to see if remaining space is enough
1928 if(to->top + isize > to->bound) {
1929 // fill 0 indicating the end of this block
1930 BAMBOO_MEMSET_WH(to->ptr, '\0', to->bound - to->top);
1931 // fill the header of this block and then go to next block
1932 to->offset += to->bound - to->top;
1933 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1934 (*((int*)(to->base))) = to->offset;
1936 if(stopblock == to->numblocks) {
1937 // already fulfilled the block
1939 } // if(stopblock == to->numblocks)
1940 } // if(to->top + isize > to->bound)
1941 // set the mark field to 2, indicating that this obj has been moved
1942 // and need to be flushed
1943 ((int *)(orig->ptr))[6] = COMPACTED;
1944 if(to->ptr != orig->ptr) {
1945 if((int)(orig->ptr) < (int)(to->ptr)+size) {
1946 memmove(to->ptr, orig->ptr, size);
1948 //BAMBOO_WRITE_HINT_CACHE(to->ptr, size);
1949 memcpy(to->ptr, orig->ptr, size);
1951 // fill the remaining space with -2
1952 BAMBOO_MEMSET_WH(to->ptr+size, -2, isize-size);
1954 // store mapping info
1955 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1956 //mgchashInsert_I(orig->ptr, to->ptr);
1957 RuntimeHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1960 //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
1962 // add to the sharedptbl
1963 if(gcsharedptbl != NULL) {
1964 //GCSharedHashadd_I(gcsharedptbl, orig->ptr, to->ptr);
1965 mgcsharedhashInsert_I(gcsharedptbl, orig->ptr, to->ptr);
1966 //num_mapinforequest++; // TODO
1969 //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
1972 //MGCHashadd_I(gcpointertbl, orig->ptr, to->ptr);
1973 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1976 BAMBOO_DEBUGPRINT(0xcdce);
1977 BAMBOO_DEBUGPRINT_REG(orig->ptr);
1978 BAMBOO_DEBUGPRINT_REG(to->ptr);
1980 gccurr_heaptop -= isize;
1982 to->offset += isize;
1984 if(to->top == to->bound) {
1985 // fill the header of this block and then go to next block
1986 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
1987 (*((int*)(to->base))) = to->offset;
1992 BAMBOO_DEBUGPRINT(0xe205);
1998 BAMBOO_DEBUGPRINT_REG(isize);
1999 BAMBOO_DEBUGPRINT_REG(size);
2000 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2001 BAMBOO_DEBUGPRINT_REG(orig->bound);
2003 if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
2005 BAMBOO_DEBUGPRINT(0xe206);
2007 if(!nextSBlock(orig)) {
2008 // finished, no more data
2013 BAMBOO_DEBUGPRINT(0xe207);
2014 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2017 } //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
2019 // should be invoked with interrupt closed
2020 inline int assignSpareMem_I(int sourcecore,
2025 BLOCKINDEX(gcloads[sourcecore], &b);
2026 int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
2027 : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
2028 int remain = boundptr - gcloads[sourcecore];
2029 int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
2030 *startaddr = gcloads[sourcecore];
2031 *tomove = gcfilledblocks[sourcecore] + 1;
2032 if(memneed < remain) {
2033 gcloads[sourcecore] += memneed;
2036 // next available block
2037 gcfilledblocks[sourcecore] += 1;
2039 BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
2040 gcloads[sourcecore] = newbase;
2041 return requiredmem-remain;
2043 } // int assignSpareMem_I(int ,int * , int * , int * )
2045 // should be invoked with interrupt closed
2046 inline bool gcfindSpareMem_I(int * startaddr,
2051 for(int k = 0; k < NUMCORES4GC; k++) {
2052 if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
2053 // check if this stopped core has enough mem
2054 assignSpareMem_I(k, requiredmem, tomove, startaddr);
2059 // if can not find spare mem right now, hold the request
2060 gcrequiredmems[requiredcore] = requiredmem;
2063 } //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
2065 inline bool compacthelper(struct moveHelper * orig,
2066 struct moveHelper * to,
2069 bool * localcompact) {
2070 // scan over all objs in this block, compact the marked objs
2071 // loop stop when finishing either scanning all active objs or
2072 // fulfilled the gcstopblock
2074 BAMBOO_DEBUGPRINT(0xe101);
2075 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2076 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2079 while(orig->ptr < gcmarkedptrbound) {
2080 bool stop = moveobj(orig, to, gcblock2fill);
2085 // if no objs have been compact, do nothing,
2086 // otherwise, fill the header of this block
2087 if(to->offset > BAMBOO_CACHE_LINE_SIZE) {
2088 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2089 (*((int*)(to->base))) = to->offset;
2093 to->top -= BAMBOO_CACHE_LINE_SIZE;
2094 } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
2096 *heaptopptr = to->ptr;
2097 *filledblocks = to->numblocks;
2100 BAMBOO_DEBUGPRINT(0xe102);
2101 BAMBOO_DEBUGPRINT_REG(orig->ptr);
2102 BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2103 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2104 BAMBOO_DEBUGPRINT_REG(*filledblocks);
2105 BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
2108 // send msgs to core coordinator indicating that the compact is finishing
2109 // send compact finish message to core coordinator
2110 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2111 gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
2112 gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
2113 if(orig->ptr < gcmarkedptrbound) {
2115 BAMBOO_DEBUGPRINT(0xe103);
2119 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2120 if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
2121 gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
2123 BAMBOO_DEBUGPRINT(0xe104);
2127 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2129 BAMBOO_DEBUGPRINT(0xe105);
2133 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2136 BAMBOO_DEBUGPRINT(0xe106);
2138 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2143 if(orig->ptr < gcmarkedptrbound) {
2145 BAMBOO_DEBUGPRINT(0xe107);
2149 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2150 *filledblocks, *heaptopptr, gccurr_heaptop, false);
2153 BAMBOO_DEBUGPRINT(0xe108);
2154 BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2156 // finish compacting
2157 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2158 *filledblocks, *heaptopptr, 0, false);
2160 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
2162 if(orig->ptr < gcmarkedptrbound) {
2164 BAMBOO_DEBUGPRINT(0xe109);
2166 // still have unpacked obj
2175 BAMBOO_DEBUGPRINT(0xe10a);
2178 to->ptr = gcmovestartaddr;
2179 to->numblocks = gcblock2fill - 1;
2180 to->bound = (to->numblocks==0) ?
2181 BAMBOO_SMEM_SIZE_L :
2182 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2183 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2184 to->offset = to->ptr - to->base;
2185 to->top = (to->numblocks==0) ?
2186 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2188 to->offset = BAMBOO_CACHE_LINE_SIZE;
2189 to->ptr += to->offset; // for header
2190 to->top += to->offset;
2191 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2192 *localcompact = true;
2194 *localcompact = false;
2199 BAMBOO_DEBUGPRINT(0xe10b);
2202 } // void compacthelper()
2204 inline void compact() {
2205 if(COMPACTPHASE != gcphase) {
2206 BAMBOO_EXIT(0xb102);
2209 // initialize pointers for comapcting
2210 struct moveHelper * orig =
2211 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2212 struct moveHelper * to =
2213 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2215 if(!initOrig_Dst(orig, to)) {
2216 // no available data to compact
2217 // send compact finish msg to STARTUP core
2219 BAMBOO_DEBUGPRINT(0xe001);
2220 BAMBOO_DEBUGPRINT_REG(to->base);
2222 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2223 0, to->base, 0, false);
2229 int filledblocks = 0;
2230 INTPTR heaptopptr = 0;
2231 bool localcompact = true;
2232 compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
2238 // if return NULL, means
2239 // 1. objptr is NULL
2240 // 2. objptr is not a shared obj
2241 // in these cases, remain the original value is OK
2242 inline void * flushObj(void * objptr) {
2244 BAMBOO_DEBUGPRINT(0xe401);
2246 if(objptr == NULL) {
2249 void * dstptr = NULL;
2250 if(ISSHAREDOBJ(objptr)) {
2252 BAMBOO_DEBUGPRINT(0xe402);
2253 BAMBOO_DEBUGPRINT_REG(objptr);
2255 // a shared obj ptr, change to new address
2256 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2258 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2260 //dstptr = mgchashSearch(objptr);
2261 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2263 flushstalltime += BAMBOO_GET_EXE_TIME()-ttime;
2265 //MGCHashget(gcpointertbl, objptr, &dstptr);
2266 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2268 BAMBOO_DEBUGPRINT_REG(dstptr);
2271 if(NULL == dstptr) {
2274 BAMBOO_DEBUGPRINT(0xe403);
2275 BAMBOO_DEBUGPRINT_REG(objptr);
2276 BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
2278 if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) {
2279 // error! the obj is right on this core, but cannot find it
2280 BAMBOO_DEBUGPRINT_REG(objptr);
2281 BAMBOO_EXIT(0xb103);
2282 // assume that the obj has not been moved, use the original address
2285 int hostc = hostcore(objptr);
2287 unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
2289 // check the corresponsing sharedptbl
2290 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2291 //struct GCSharedHash * sptbl = gcrpointertbls[hostcore(objptr)];
2292 mgcsharedhashtbl_t * sptbl = gcrpointertbls[hostc];
2294 //GCSharedHashget(sptbl, (int)objptr, &dstptr);
2295 dstptr = mgcsharedhashSearch(sptbl, (int)objptr);
2296 if(dstptr != NULL) {
2297 RuntimeHashadd_I(gcpointertbl, (int)objptr, (int)dstptr);
2300 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2302 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
2305 if(dstptr == NULL) {
2306 // still can not get the mapping info,
2307 // send msg to host core for the mapping info
2308 gcobj2map = (int)objptr;
2313 //num_mapinforequest++;
2314 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2317 //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
2319 // the first time require the mapping, send msg to the hostcore
2320 // for the mapping info
2321 send_msg_3(hostc, GCMAPREQUEST, (int)objptr,
2322 BAMBOO_NUM_OF_CORE, false);
2329 //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
2333 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2335 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2336 //dstptr = mgchashSearch(objptr);
2337 RuntimeHashget(gcpointertbl, objptr, &dstptr);
2338 //MGCHashget(gcpointertbl, objptr, &dstptr);
2339 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2340 } // if(dstptr == NULL)
2341 } // if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) else ...
2343 BAMBOO_DEBUGPRINT_REG(dstptr);
2345 } // if(NULL == dstptr)
2346 } // if(ISSHAREDOBJ(objptr))
2347 // if not a shared obj, return NULL to indicate no need to flush
2349 BAMBOO_DEBUGPRINT(0xe404);
2352 } // void flushObj(void * objptr)
2354 inline void flushRuntimeObj(struct garbagelist * stackptr) {
2356 // flush current stack
2357 while(stackptr!=NULL) {
2358 for(i=0; i<stackptr->size; i++) {
2359 if(stackptr->array[i] != NULL) {
2360 void * dst = flushObj(stackptr->array[i]);
2362 stackptr->array[i] = dst;
2366 stackptr=stackptr->next;
2370 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
2371 for(i=0; i<NUMCLASSES; i++) {
2372 struct parameterwrapper ** queues =
2373 objectqueues[BAMBOO_NUM_OF_CORE][i];
2374 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
2375 for(j = 0; j < length; ++j) {
2376 struct parameterwrapper * parameter = queues[j];
2377 struct ObjectHash * set=parameter->objectset;
2378 struct ObjectNode * ptr=set->listhead;
2380 void * dst = flushObj((void *)ptr->key);
2386 ObjectHashrehash(set);
2391 // flush current task descriptor
2392 if(currtpd != NULL) {
2393 for(i=0; i<currtpd->numParameters; i++) {
2394 void * dst = flushObj(currtpd->parameterArray[i]);
2396 currtpd->parameterArray[i] = dst;
2401 // flush active tasks
2402 if(activetasks != NULL) {
2403 struct genpointerlist * ptr=activetasks->list;
2405 struct taskparamdescriptor *tpd=ptr->src;
2407 for(i=0; i<tpd->numParameters; i++) {
2408 void * dst = flushObj(tpd->parameterArray[i]);
2410 tpd->parameterArray[i] = dst;
2415 genrehash(activetasks);
2418 // flush cached transferred obj
2419 struct QueueItem * tmpobjptr = getHead(&objqueue);
2420 while(tmpobjptr != NULL) {
2421 struct transObjInfo * objInfo =
2422 (struct transObjInfo *)(tmpobjptr->objectptr);
2423 void * dst = flushObj(objInfo->objptr);
2425 objInfo->objptr = dst;
2427 tmpobjptr = getNextQueueItem(tmpobjptr);
2430 // flush cached objs to be transferred
2431 struct QueueItem * item = getHead(totransobjqueue);
2432 while(item != NULL) {
2433 struct transObjInfo * totransobj =
2434 (struct transObjInfo *)(item->objectptr);
2435 void * dst = flushObj(totransobj->objptr);
2437 totransobj->objptr = dst;
2439 item = getNextQueueItem(item);
2440 } // while(item != NULL)
2442 // enqueue lock related info
2443 for(i = 0; i < runtime_locklen; ++i) {
2444 void * dst = flushObj(runtime_locks[i].redirectlock);
2446 runtime_locks[i].redirectlock = (int)dst;
2448 if(runtime_locks[i].value != NULL) {
2449 void * dst=flushObj(runtime_locks[i].value);
2451 runtime_locks[i].value = (int)dst;
2456 } // void flushRuntimeObj(struct garbagelist * stackptr)
2458 inline void transmappinginfo() {
2459 // inform the other cores the mapping info they need
2460 /*struct RuntimeIterator* it_pointertbl =
2461 RuntimeHashcreateiterator(gcpointertbl);
2462 while(RunhasNext(it_pointertbl)) {
2463 int obj = Runkey(it_pointertbl);
2464 struct nodemappinginfo * info =
2465 (struct nodemappinginfo *)Runnext(it_pointertbl);
2466 int newptr = (int)info->ptr;
2467 struct requestcoreinfo * coreinfo = info->cores;
2469 // send the mapping info to all requested cores
2470 while(coreinfo != NULL) {
2471 struct requestcoreinfo * tmp = coreinfo;
2472 coreinfo = coreinfo->next;
2473 send_msg_3(tmp->core, GCMAPINFO, obj, newptr, false);
2474 RUNFREE(tmp); // release the node
2477 /* int core = (BAMBOO_NUM_OF_CORE + 1) % NUMCORESACTIVE;
2478 for(int i = 0; i < NUMCORESACTIVE - 1; i++) {
2479 for(int j = 1; j < gcmappingtbl[core][0]+1; j++) {
2480 int obj = gcmappingtbl[core][j];
2482 RuntimeHashget(gcpointertbl, obj, &newptr);
2483 send_msg_3(core, GCMAPINFO, obj, newptr, false);
2485 //tprintf("send mapping %x -> %x, %x \n", (int)obj, (int)newptr, i);
2488 //tprintf("send mapping to core %d \n", core);
2489 core = (core + 1) % NUMCORESACTIVE;
2493 // broadcast the sharedptbl pointer
2494 for(int i = 0; i < NUMCORESACTIVE; i++) {
2495 if(i != BAMBOO_NUM_OF_CORE) {
2496 send_msg_3(i, GCMAPTBL, gcsharedptbl, BAMBOO_NUM_OF_CORE, false);
2501 //BAMBOO_DEBUGPRINT(0xeeee);
2503 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
2504 send_msg_2(STARTUPCORE, GCFINISHMAPINFO, BAMBOO_NUM_OF_CORE, false);
2508 inline void flush(struct garbagelist * stackptr) {
2510 /* TODO if(BAMBOO_NUM_OF_CORE == 0) {
2511 BAMBOO_DEBUGPRINT(0xcccc);
2512 BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2516 flushRuntimeObj(stackptr);
2518 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2522 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2523 bool hasItems = gc_moreItems_I();
2524 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2530 BAMBOO_DEBUGPRINT(0xe301);
2532 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2533 void * ptr = gc_dequeue_I();
2534 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2535 if(ISSHAREDOBJ(ptr)) {
2536 // should be a local shared obj and should have mapping info
2537 ptr = flushObj(ptr);
2539 BAMBOO_DEBUGPRINT(0xe302);
2540 BAMBOO_DEBUGPRINT_REG(ptr);
2541 BAMBOO_DEBUGPRINT_REG(tptr);
2542 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2545 BAMBOO_EXIT(0xb105);
2547 } // if(ISSHAREDOBJ(ptr))
2548 if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED)) {
2549 int type = ((int *)(ptr))[0];
2550 // scan all pointers in ptr
2551 unsigned INTPTR * pointer;
2552 pointer=pointerarray[type];
2554 BAMBOO_DEBUGPRINT(0xe303);
2555 BAMBOO_DEBUGPRINT_REG(pointer);
2558 /* Array of primitives */
2560 } else if (((INTPTR)pointer)==1) {
2562 BAMBOO_DEBUGPRINT(0xe304);
2564 /* Array of pointers */
2565 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2566 int length=ao->___length___;
2568 for(j=0; j<length; j++) {
2570 BAMBOO_DEBUGPRINT(0xe305);
2573 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2575 BAMBOO_DEBUGPRINT_REG(objptr);
2577 if(objptr != NULL) {
2578 void * dst = flushObj(objptr);
2580 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2586 BAMBOO_DEBUGPRINT(0xe306);
2588 INTPTR size=pointer[0];
2590 for(i=1; i<=size; i++) {
2592 BAMBOO_DEBUGPRINT(0xe307);
2594 unsigned int offset=pointer[i];
2595 void * objptr=*((void **)(((char *)ptr)+offset));
2597 BAMBOO_DEBUGPRINT_REG(objptr);
2599 if(objptr != NULL) {
2600 void * dst = flushObj(objptr);
2602 *((void **)(((char *)ptr)+offset)) = dst;
2605 } // for(i=1; i<=size; i++)
2606 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2607 // restore the mark field, indicating that this obj has been flushed
2608 if(ISSHAREDOBJ(ptr)) {
2609 ((int *)(ptr))[6] = INIT;
2611 } // if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED))
2612 } // while(gc_moreItems())
2614 BAMBOO_DEBUGPRINT(0xe308);
2617 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2620 // TODO bug here: the startup core contains all lobjs' info, thus all the
2621 // lobjs are flushed in sequence.
2623 while(gc_lobjmoreItems_I()) {
2625 BAMBOO_DEBUGPRINT(0xe309);
2627 void * ptr = gc_lobjdequeue_I(NULL, NULL);
2628 ptr = flushObj(ptr);
2630 BAMBOO_DEBUGPRINT(0xe30a);
2631 BAMBOO_DEBUGPRINT_REG(ptr);
2632 BAMBOO_DEBUGPRINT_REG(tptr);
2633 BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2638 if(((int *)(ptr))[6] == COMPACTED) {
2639 int type = ((int *)(ptr))[0];
2640 // scan all pointers in ptr
2641 unsigned INTPTR * pointer;
2642 pointer=pointerarray[type];
2644 BAMBOO_DEBUGPRINT(0xe30b);
2645 BAMBOO_DEBUGPRINT_REG(pointer);
2648 /* Array of primitives */
2650 } else if (((INTPTR)pointer)==1) {
2652 BAMBOO_DEBUGPRINT(0xe30c);
2654 /* Array of pointers */
2655 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2656 int length=ao->___length___;
2658 for(j=0; j<length; j++) {
2660 BAMBOO_DEBUGPRINT(0xe30d);
2663 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2665 BAMBOO_DEBUGPRINT_REG(objptr);
2667 if(objptr != NULL) {
2668 void * dst = flushObj(objptr);
2670 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2676 BAMBOO_DEBUGPRINT(0xe30e);
2678 INTPTR size=pointer[0];
2680 for(i=1; i<=size; i++) {
2682 BAMBOO_DEBUGPRINT(0xe30f);
2684 unsigned int offset=pointer[i];
2685 void * objptr=*((void **)(((char *)ptr)+offset));
2688 BAMBOO_DEBUGPRINT_REG(objptr);
2690 if(objptr != NULL) {
2691 void * dst = flushObj(objptr);
2693 *((void **)(((char *)ptr)+offset)) = dst;
2696 } // for(i=1; i<=size; i++)
2697 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2698 // restore the mark field, indicating that this obj has been flushed
2699 ((int *)(ptr))[6] = INIT;
2700 } // if(((int *)(ptr))[6] == COMPACTED)
2701 } // while(gc_lobjmoreItems())
2703 BAMBOO_DEBUGPRINT(0xe310);
2706 // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
2709 // send flush finish message to core coordinator
2710 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2711 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2713 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
2717 //if(BAMBOO_NUM_OF_CORE == 0) {
2718 //BAMBOO_DEBUGPRINT(0xffff);
2719 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest);
2720 //BAMBOO_DEBUGPRINT_REG(flushstalltime);
2721 //BAMBOO_DEBUGPRINT_REG(num_mapinforequest_i);
2722 //BAMBOO_DEBUGPRINT_REG(flushstalltime_i);
2724 //BAMBOO_DEBUGPRINT_REG(flushstalltime);
2727 BAMBOO_DEBUGPRINT(0xe311);
2731 inline void gc_collect(struct garbagelist * stackptr) {
2732 // core collector routine
2734 if(INITPHASE == gcphase) {
2738 #ifdef RAWPATH // TODO GC_DEBUG
2739 printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2742 //send init finish msg to core coordinator
2743 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2745 if(MARKPHASE == gcphase) {
2749 #ifdef RAWPATH // TODO GC_DEBUG
2750 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2751 udn_tile_coord_y());
2753 mark(true, stackptr);
2754 #ifdef RAWPATH // TODO GC_DEBUG
2755 printf("(%x,%x) Finish mark phase, start compact phase\n",
2756 udn_tile_coord_x(), udn_tile_coord_y());
2759 #ifdef RAWPATH // TODO GC_DEBUG
2760 printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
2761 udn_tile_coord_y());
2764 if(MAPPHASE == gcphase) {
2768 #ifdef RAWPATH // TODO GC_DEBUG
2769 printf("(%x,%x) Start map phase\n", udn_tile_coord_x(),
2770 udn_tile_coord_y());
2773 #ifdef RAWPATH // TODO GC_DEBUG
2774 printf("(%x,%x) Finish map phase\n", udn_tile_coord_x(),
2775 udn_tile_coord_y());
2778 if(FLUSHPHASE == gcphase) {
2782 #ifdef RAWPATH // TODO GC_DEBUG
2783 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2784 udn_tile_coord_y());
2787 #ifdef RAWPATH // TODO GC_DEBUG
2788 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2789 udn_tile_coord_y());
2793 if(FINISHPHASE == gcphase) {
2797 #ifdef RAWPATH // TODO GC_DEBUG
2798 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2800 } // void gc_collect(struct garbagelist * stackptr)
2802 inline void gc_nocollect(struct garbagelist * stackptr) {
2804 if(INITPHASE == gcphase) {
2808 #ifdef RAWPATH // TODO GC_DEBUG
2809 printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
2812 //send init finish msg to core coordinator
2813 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
2815 if(MARKPHASE == gcphase) {
2819 #ifdef RAWPATH // TODO GC_DEBUG
2820 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
2821 udn_tile_coord_y());
2823 mark(true, stackptr);
2824 #ifdef RAWPATH // TODO GC_DEBUG
2825 printf("(%x,%x) Finish mark phase, wait for flush\n",
2826 udn_tile_coord_x(), udn_tile_coord_y());
2828 // non-gc core collector routine
2830 if(FLUSHPHASE == gcphase) {
2834 #ifdef RAWPATH // TODO GC_DEBUG
2835 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
2836 udn_tile_coord_y());
2839 #ifdef RAWPATH // TODO GC_DEBUG
2840 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
2841 udn_tile_coord_y());
2845 if(FINISHPHASE == gcphase) {
2849 #ifdef RAWPATH // TODO GC_DEBUG
2850 printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
2852 } // void gc_collect(struct garbagelist * stackptr)
2854 inline void gc(struct garbagelist * stackptr) {
2857 gcprocessing = false;
2861 // core coordinator routine
2862 if(0 == BAMBOO_NUM_OF_CORE) {
2864 printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
2865 udn_tile_coord_y());
2868 // not ready to do gc
2877 #ifdef RAWPATH // TODO GC_DEBUG
2878 printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
2881 gcprocessing = true;
2882 gcphase = INITPHASE;
2884 waitconfirm = false;
2888 // Note: all cores need to init gc including non-gc cores
2889 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
2890 // send GC init messages to all cores
2891 send_msg_1(i, GCSTARTINIT, false);
2893 bool isfirst = true;
2894 bool allStall = false;
2896 #ifdef RAWPATH // TODO GC_DEBUG
2897 printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
2898 udn_tile_coord_y());
2901 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2903 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2904 if(gc_checkAllCoreStatus_I()) {
2905 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2908 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2913 #ifdef RAWPATH // TODO GC_DEBUG
2914 printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
2915 udn_tile_coord_y());
2917 // all cores have finished compacting
2918 // restore the gcstatus of all cores
2919 // Note: all cores have to do mark including non-gc cores
2920 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
2921 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
2922 gccorestatus[i] = 1;
2923 // send GC start messages to all cores
2924 send_msg_1(i, GCSTART, false);
2927 gcphase = MARKPHASE;
2929 while(MARKPHASE == gcphase) {
2930 mark(isfirst, stackptr);
2937 } // while(MARKPHASE == gcphase)
2938 // send msgs to all cores requiring large objs info
2939 // Note: only need to ask gc cores, non-gc cores do not host any objs
2940 numconfirm = NUMCORES4GC - 1;
2941 for(i = 1; i < NUMCORES4GC; ++i) {
2942 send_msg_1(i, GCLOBJREQUEST, false);
2944 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
2949 } // wait for responses
2950 // check the heaptop
2951 if(gcheaptop < gcmarkedptrbound) {
2952 gcheaptop = gcmarkedptrbound;
2957 /*if(BAMBOO_NUM_OF_CORE == 0) {
2958 BAMBOO_DEBUGPRINT(0xeeee);
2959 BAMBOO_DEBUGPRINT_REG(num_markrequest);
2960 BAMBOO_DEBUGPRINT_REG(marktime);
2963 #ifdef RAWPATH // TODO GC_DEBUG
2964 printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
2965 udn_tile_coord_y());
2968 // cache all large objs
2970 // no enough space to cache large objs
2971 BAMBOO_EXIT(0xb107);
2973 // predict number of blocks to fill for each core
2975 int numpbc = loadbalance(&tmpheaptop);
2977 numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
2978 #ifdef RAWPATH // TODO GC_DEBUG
2979 printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
2980 udn_tile_coord_y());
2983 //int tmptopptr = 0;
2984 //BASEPTR(gctopcore, 0, &tmptopptr);
2986 //tmptopptr = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2987 tmpheaptop = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
2989 BAMBOO_DEBUGPRINT(0xabab);
2990 BAMBOO_DEBUGPRINT_REG(tmptopptr);
2992 for(i = 0; i < NUMCORES4GC; ++i) {
2994 BASEPTR(i, numpbc, &tmpcoreptr);
2995 //send start compact messages to all cores
2996 //TODO bug here, do not know if the direction is positive or negtive?
2997 if (tmpcoreptr < tmpheaptop /*tmptopptr*/) {
2998 gcstopblock[i] = numpbc + 1;
2999 if(i != STARTUPCORE) {
3000 send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
3002 gcblock2fill = numpbc+1;
3003 } // if(i != STARTUPCORE)
3005 gcstopblock[i] = numpbc;
3006 if(i != STARTUPCORE) {
3007 send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
3009 gcblock2fill = numpbc;
3010 } // if(i != STARTUPCORE)
3013 BAMBOO_DEBUGPRINT(0xf000+i);
3014 BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
3015 BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
3017 // init some data strutures for compact phase
3019 gcfilledblocks[i] = 0;
3020 gcrequiredmems[i] = 0;
3028 bool finalcompact = false;
3029 // initialize pointers for comapcting
3030 struct moveHelper * orig =
3031 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3032 struct moveHelper * to =
3033 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3034 initOrig_Dst(orig, to);
3035 int filledblocks = 0;
3036 INTPTR heaptopptr = 0;
3037 bool finishcompact = false;
3038 bool iscontinue = true;
3039 bool localcompact = true;
3040 while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
3041 if((!finishcompact) && iscontinue) {
3043 BAMBOO_DEBUGPRINT(0xe001);
3044 BAMBOO_DEBUGPRINT_REG(numpbc);
3045 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3047 finishcompact = compacthelper(orig, to, &filledblocks,
3048 &heaptopptr, &localcompact);
3050 BAMBOO_DEBUGPRINT(0xe002);
3051 BAMBOO_DEBUGPRINT_REG(finishcompact);
3052 BAMBOO_DEBUGPRINT_REG(gctomove);
3053 BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
3054 BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
3055 BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
3059 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3060 if(gc_checkCoreStatus_I()) {
3061 // all cores have finished compacting
3062 // restore the gcstatus of all cores
3063 for(i = 0; i < NUMCORES4GC; ++i) {
3064 gccorestatus[i] = 1;
3066 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3069 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3070 // check if there are spare mem for pending move requires
3071 if(COMPACTPHASE == gcphase) {
3073 BAMBOO_DEBUGPRINT(0xe003);
3075 resolvePendingMoveRequest();
3077 BAMBOO_DEBUGPRINT_REG(gctomove);
3081 BAMBOO_DEBUGPRINT(0xe004);
3085 } // if(gc_checkCoreStatus_I()) else ...
3089 BAMBOO_DEBUGPRINT(0xe005);
3090 BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
3091 BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3092 BAMBOO_DEBUGPRINT_REG(gctomove);
3094 to->ptr = gcmovestartaddr;
3095 to->numblocks = gcblock2fill - 1;
3096 to->bound = (to->numblocks==0) ?
3097 BAMBOO_SMEM_SIZE_L :
3098 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
3099 BASEPTR(gcdstcore, to->numblocks, &(to->base));
3100 to->offset = to->ptr - to->base;
3101 to->top = (to->numblocks==0) ?
3102 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
3104 to->offset = BAMBOO_CACHE_LINE_SIZE;
3105 to->ptr += to->offset; // for header
3106 to->top += to->offset;
3107 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
3108 localcompact = true;
3110 localcompact = false;
3114 } else if(!finishcompact) {
3119 } // while(COMPACTPHASE == gcphase)
3123 #ifdef RAWPATH // TODO GC_DEBUG
3124 printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
3125 udn_tile_coord_y());
3130 #ifdef RAWPATH // TODO GC_DEBUG
3131 printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
3132 udn_tile_coord_y());
3140 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3141 // Note: all cores should flush their runtime data including non-gc
3143 for(i = 1; i < NUMCORES4GC; ++i) {
3144 // send start flush messages to all cores
3145 gccorestatus[i] = 1;
3146 send_msg_1(i, GCSTARTMAPINFO, false);
3151 #ifdef RAWPATH // TODO GC_DEBUG
3152 printf("(%x,%x) Start map phase \n", udn_tile_coord_x(),
3153 udn_tile_coord_y());
3157 #ifdef RAWPATH // TODO GC_DEBUG
3158 printf("(%x,%x) Finish map phase \n", udn_tile_coord_x(),
3159 udn_tile_coord_y());
3161 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3162 while(MAPPHASE == gcphase) {
3163 // check the status of all cores
3164 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3165 if(gc_checkCoreStatus_I()) {
3166 // all cores have finished sending mapping info
3167 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3170 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3171 } // while(MAPPHASE == gcphase)
3173 gcphase = FLUSHPHASE;
3174 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3175 // Note: all cores should flush their runtime data including non-gc
3177 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3178 // send start flush messages to all cores
3179 gccorestatus[i] = 1;
3180 send_msg_1(i, GCSTARTFLUSH, false);
3185 #ifdef RAWPATH // TODO GC_DEBUG
3186 printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
3187 udn_tile_coord_y());
3191 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3192 while(FLUSHPHASE == gcphase) {
3193 // check the status of all cores
3194 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3195 if(gc_checkAllCoreStatus_I()) {
3196 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3199 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3200 } // while(FLUSHPHASE == gcphase)
3201 gcphase = FINISHPHASE;
3203 // invalidate all shared mem pointers
3204 // put it here as it takes time to inform all the other cores to
3205 // finish gc and it might cause problem when some core resumes
3206 // mutator earlier than the other cores
3207 bamboo_cur_msp = NULL;
3208 bamboo_smem_size = 0;
3210 gcprocessing = false;
3215 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3216 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
3217 // send gc finish messages to all cores
3218 send_msg_1(i, GCFINISH, false);
3219 gccorestatus[i] = 1;
3221 #ifdef RAWPATH // TODO GC_DEBUG
3222 printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
3223 udn_tile_coord_y());
3227 /*extern int gc_num_search;
3228 extern int gc_num_collision;
3229 tprintf("Average collision: %d \n", gc_num_collision/gc_num_search);*/
3230 } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
3231 gcprocessing = true;
3232 gc_collect(stackptr);
3234 // invalidate all shared mem pointers
3235 bamboo_cur_msp = NULL;
3236 bamboo_smem_size = 0;
3239 gcprocessing = false;
3241 // not a gc core, should wait for gcfinish msg
3242 gcprocessing = true;
3243 gc_nocollect(stackptr);
3245 // invalidate all shared mem pointers
3246 bamboo_cur_msp = NULL;
3247 bamboo_smem_size = 0;
3250 gcprocessing = false;
3252 } // void gc(struct garbagelist * stackptr)
3255 inline void gc_profileStart(void) {
3256 if(!gc_infoOverflow) {
3257 GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
3258 gc_infoArray[gc_infoIndex] = gcInfo;
3260 gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
3264 inline void gc_profileItem(void) {
3265 if(!gc_infoOverflow) {
3266 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3267 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3271 inline void gc_profileEnd(void) {
3272 if(!gc_infoOverflow) {
3273 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
3274 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
3276 if(gc_infoIndex == GCINFOLENGTH) {
3277 gc_infoOverflow = true;
3278 //taskInfoIndex = 0;
3283 // output the profiling data
3284 void gc_outputProfileData() {
3287 unsigned long long totalgc = 0;
3289 //printf("Start Time, End Time, Duration\n");
3290 // output task related info
3291 for(i = 0; i < gc_infoIndex; i++) {
3292 GCInfo * gcInfo = gc_infoArray[i];
3293 unsigned long long tmp = 0;
3294 for(j = 0; j < gcInfo->index; j++) {
3295 printf("%lld(%lld), ", gcInfo->time[j], (gcInfo->time[j]-tmp));
3296 tmp = gcInfo->time[j];
3298 tmp = (tmp-gcInfo->time[0]);
3299 printf(" ++ %lld \n", tmp);
3303 if(gc_infoOverflow) {
3304 printf("Caution: gc info overflow!\n");
3307 printf("\n\n total gc time: %lld \n", totalgc);
3311 unsigned long long totalgc = 0;
3313 BAMBOO_DEBUGPRINT(0xdddd);
3314 // output task related info
3315 for(i= 0; i < gc_infoIndex; i++) {
3316 GCInfo * gcInfo = gc_infoArray[i];
3317 unsigned long long tmp = 0;
3318 BAMBOO_DEBUGPRINT(0xddda);
3319 for(j = 0; j < gcInfo->index; j++) {
3320 BAMBOO_DEBUGPRINT(gcInfo->time[j]);
3321 BAMBOO_DEBUGPRINT(gcInfo->time[j]-tmp);
3322 BAMBOO_DEBUGPRINT(0xdddb);
3323 tmp = gcInfo->time[j];
3325 tmp = (tmp-gcInfo->time[0]);
3326 BAMBOO_DEBUGPRINT_REG(tmp);
3327 BAMBOO_DEBUGPRINT(0xdddc);
3330 BAMBOO_DEBUGPRINT(0xdddd);
3331 BAMBOO_DEBUGPRINT_REG(totalgc);
3333 if(gc_infoOverflow) {
3334 BAMBOO_DEBUGPRINT(0xefee);
3337 BAMBOO_DEBUGPRINT(0xeeee);
3340 #endif // #ifdef GC_PROFILE