1 // BAMBOO_EXIT(0xb000);
4 #include "multicoregarbage.h"
5 #include "multicoreruntime.h"
6 #include "runtime_arch.h"
7 #include "SimpleHash.h"
8 #include "GenericHashtable.h"
9 #include "ObjectHash.h"
10 #include "GCSharedHash.h"
14 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
15 extern int numqueues[][NUMCLASSES];
16 extern struct genhashtable * activetasks;
17 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
18 extern struct taskparamdescriptor *currtpd;
19 extern struct LockValue runtime_locks[MAXTASKPARAMS];
20 extern int runtime_locklen;
23 extern struct global_defs_t * global_defs_p;
26 extern unsigned int gcmem_mixed_threshold;
27 extern unsigned int gcmem_mixed_usedmem;
31 extern unsigned int bamboo_threadlocks;
34 //int gcmarkwaitcounter = -1;
38 struct pointerblock *next;
41 struct pointerblock *gchead=NULL;
43 struct pointerblock *gctail=NULL;
45 struct pointerblock *gctail2=NULL;
47 struct pointerblock *gcspare=NULL;
49 #define NUMLOBJPTRS 20
51 struct lobjpointerblock {
52 void * lobjs[NUMLOBJPTRS];
53 int lengths[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 typedef struct gc_cache_revise_info {
69 int orig_page_start_va;
75 unsigned int revised_sampling[NUMCORESACTIVE];
76 } gc_cache_revise_info_t;
77 gc_cache_revise_info_t gc_cache_revise_infomation;
78 #endif// GC_CACHE_ADAPT
81 // dump whole mem in blocks
82 inline void dumpSMem() {
90 printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
92 // reserved blocks for sblocktbl
93 printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
95 for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
96 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",
97 udn_tile_coord_x(), udn_tile_coord_y(),
98 *((int *)(i)), *((int *)(i + 4)),
99 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
100 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
101 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
102 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
103 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
104 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
105 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
107 sblock = gcreservedsb;
108 bool advanceblock = false;
110 for(i=gcbaseva; i<gcbaseva+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
111 advanceblock = false;
112 // computing sblock # and block #, core coordinate (x,y) also
113 if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
115 if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
116 if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
128 coren = gc_block2core[block%(NUMCORES4GC*2)];
130 // compute core coordinate
131 BAMBOO_COORDS(coren, &x, &y);
132 printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
133 udn_tile_coord_x(), udn_tile_coord_y(),
134 block, sblock++, x, y,
135 (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
138 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",
139 udn_tile_coord_x(), udn_tile_coord_y(),
140 *((int *)(i)), *((int *)(i + 4)),
141 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
142 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
143 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
144 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
145 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
146 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
147 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
149 printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
153 // should be invoked with interruption closed
154 inline void gc_enqueue_I(void *ptr) {
155 GC_BAMBOO_DEBUGPRINT(0xe601);
156 GC_BAMBOO_DEBUGPRINT_REG(ptr);
157 if (gcheadindex==NUMPTRS) {
158 struct pointerblock * tmp;
163 tmp=RUNMALLOC_I(sizeof(struct pointerblock));
164 } // if (gcspare!=NULL)
168 } // if (gcheadindex==NUMPTRS)
169 gchead->ptrs[gcheadindex++]=ptr;
170 GC_BAMBOO_DEBUGPRINT(0xe602);
171 } // void gc_enqueue_I(void *ptr)
173 // dequeue and destroy the queue
174 inline void * gc_dequeue_I() {
175 if (gctailindex==NUMPTRS) {
176 struct pointerblock *tmp=gctail;
183 } // if (gcspare!=NULL)
184 } // if (gctailindex==NUMPTRS)
185 return gctail->ptrs[gctailindex++];
186 } // void * gc_dequeue()
188 // dequeue and do not destroy the queue
189 inline void * gc_dequeue2_I() {
190 if (gctailindex2==NUMPTRS) {
191 struct pointerblock *tmp=gctail2;
192 gctail2=gctail2->next;
194 } // if (gctailindex2==NUMPTRS)
195 return gctail2->ptrs[gctailindex2++];
196 } // void * gc_dequeue2()
198 inline int gc_moreItems_I() {
199 if ((gchead==gctail)&&(gctailindex==gcheadindex))
202 } // int gc_moreItems()
204 inline int gc_moreItems2_I() {
205 if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
208 } // int gc_moreItems2()
210 // should be invoked with interruption closed
211 // enqueue a large obj: start addr & length
212 inline void gc_lobjenqueue_I(void *ptr,
215 GC_BAMBOO_DEBUGPRINT(0xe901);
216 if (gclobjheadindex==NUMLOBJPTRS) {
217 struct lobjpointerblock * tmp;
218 if (gclobjspare!=NULL) {
222 tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
223 } // if (gclobjspare!=NULL)
224 gclobjhead->next=tmp;
225 tmp->prev = gclobjhead;
228 } // if (gclobjheadindex==NUMLOBJPTRS)
229 gclobjhead->lobjs[gclobjheadindex]=ptr;
230 gclobjhead->lengths[gclobjheadindex]=length;
231 gclobjhead->hosts[gclobjheadindex++]=host;
232 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
233 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
234 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
235 } // void gc_lobjenqueue_I(void *ptr...)
237 // dequeue and destroy the queue
238 inline void * gc_lobjdequeue_I(unsigned int * length,
239 unsigned int * host) {
240 if (gclobjtailindex==NUMLOBJPTRS) {
241 struct lobjpointerblock *tmp=gclobjtail;
242 gclobjtail=gclobjtail->next;
244 gclobjtail->prev = NULL;
245 if (gclobjspare!=NULL) {
251 } // if (gclobjspare!=NULL)
252 } // if (gclobjtailindex==NUMLOBJPTRS)
254 *length = gclobjtail->lengths[gclobjtailindex];
257 *host = (unsigned int)(gclobjtail->hosts[gclobjtailindex]);
259 return gclobjtail->lobjs[gclobjtailindex++];
260 } // void * gc_lobjdequeue()
262 inline int gc_lobjmoreItems_I() {
263 if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
266 } // int gc_lobjmoreItems()
268 // dequeue and don't destroy the queue
269 inline void gc_lobjdequeue2_I() {
270 if (gclobjtailindex2==NUMLOBJPTRS) {
271 gclobjtail2=gclobjtail2->next;
275 } // if (gclobjtailindex2==NUMLOBJPTRS)
276 } // void * gc_lobjdequeue2()
278 inline int gc_lobjmoreItems2_I() {
279 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
282 } // int gc_lobjmoreItems2()
284 // 'reversly' dequeue and don't destroy the queue
285 inline void gc_lobjdequeue3_I() {
286 if (gclobjtailindex2==0) {
287 gclobjtail2=gclobjtail2->prev;
288 gclobjtailindex2=NUMLOBJPTRS-1;
291 } // if (gclobjtailindex2==NUMLOBJPTRS)
292 } // void * gc_lobjdequeue3()
294 inline int gc_lobjmoreItems3_I() {
295 if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
298 } // int gc_lobjmoreItems3()
300 inline void gc_lobjqueueinit4_I() {
301 gclobjtail2 = gclobjtail;
302 gclobjtailindex2 = gclobjtailindex;
303 } // void gc_lobjqueueinit2()
305 inline void * gc_lobjdequeue4_I(unsigned int * length,
306 unsigned int * host) {
307 if (gclobjtailindex2==NUMLOBJPTRS) {
308 gclobjtail2=gclobjtail2->next;
310 } // if (gclobjtailindex==NUMLOBJPTRS)
312 *length = gclobjtail2->lengths[gclobjtailindex2];
315 *host = (unsigned int)(gclobjtail2->hosts[gclobjtailindex2]);
317 return gclobjtail2->lobjs[gclobjtailindex2++];
318 } // void * gc_lobjdequeue()
320 inline int gc_lobjmoreItems4_I() {
321 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
324 } // int gc_lobjmoreItems(
326 unsigned int gccurr_heapbound = 0;
328 inline void gettype_size(void * ptr,
330 unsigned int * tsize) {
331 int type = ((int *)ptr)[0];
332 unsigned int size = 0;
333 if(type < NUMCLASSES) {
335 size = classsize[type];
338 struct ArrayObject *ao=(struct ArrayObject *)ptr;
339 unsigned int elementsize=classsize[type];
340 unsigned int length=ao->___length___;
341 size=sizeof(struct ArrayObject)+length*elementsize;
342 } // if(type < NUMCLASSES)
347 inline bool isLarge(void * ptr,
349 unsigned int * tsize) {
350 GC_BAMBOO_DEBUGPRINT(0xe701);
351 GC_BAMBOO_DEBUGPRINT_REG(ptr);
352 // check if a pointer is referring to a large object
353 gettype_size(ptr, ttype, tsize);
354 GC_BAMBOO_DEBUGPRINT(*tsize);
355 unsigned int bound = (BAMBOO_SMEM_SIZE);
356 if(((unsigned int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
357 bound = (BAMBOO_SMEM_SIZE_L);
359 if((((unsigned int)ptr-gcbaseva)%(bound))==0) {
360 // ptr is a start of a block
361 GC_BAMBOO_DEBUGPRINT(0xe702);
362 GC_BAMBOO_DEBUGPRINT(1);
365 if((bound-(((unsigned int)ptr-gcbaseva)%bound)) < (*tsize)) {
366 // it acrosses the boundary of current block
367 GC_BAMBOO_DEBUGPRINT(0xe703);
368 GC_BAMBOO_DEBUGPRINT(1);
371 GC_BAMBOO_DEBUGPRINT(0);
373 } // bool isLarge(void * ptr, int * ttype, int * tsize)
375 inline unsigned int hostcore(void * ptr) {
376 // check the host core of ptr
377 unsigned int host = 0;
378 RESIDECORE(ptr, &host);
379 GC_BAMBOO_DEBUGPRINT(0xedd0);
380 GC_BAMBOO_DEBUGPRINT_REG(ptr);
381 GC_BAMBOO_DEBUGPRINT_REG(host);
383 } // int hostcore(void * ptr)
385 inline void cpu2coords(unsigned int coren,
388 *x = bamboo_cpu2coords[2*coren];
389 *y = bamboo_cpu2coords[2*coren+1];
390 } // void cpu2coords(...)
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() {
420 GC_BAMBOO_DEBUGPRINT(0xee01);
423 (waitconfirm && (numconfirm == 0))) {
424 GC_BAMBOO_DEBUGPRINT(0xee02);
425 unsigned int entry_index = 0;
428 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
431 entry_index = gcnumsrobjs_index;
433 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
434 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
435 gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
436 gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
437 // check the status of all cores
438 bool allStall = gc_checkAllCoreStatus_I();
439 GC_BAMBOO_DEBUGPRINT(0xee03);
441 GC_BAMBOO_DEBUGPRINT(0xee04);
444 GC_BAMBOO_DEBUGPRINT(0xee05);
445 // the first time found all cores stall
446 // send out status confirm msg to all other cores
447 // reset the corestatus array too
448 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
450 numconfirm = NUMCORESACTIVE - 1;
451 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
452 for(i = 1; i < NUMCORESACTIVE; ++i) {
454 // send mark phase finish confirm request msg to core i
455 send_msg_1(i, GCMARKCONFIRM, false);
456 } // for(i = 1; i < NUMCORESACTIVE; ++i)
459 // check if the sum of send objs and receive obj are the same
460 // yes->check if the info is the latest; no->go on executing
461 unsigned int sumsendobj = 0;
462 for(i = 0; i < NUMCORESACTIVE; ++i) {
463 sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
464 } // for(i = 0; i < NUMCORESACTIVE; ++i)
465 GC_BAMBOO_DEBUGPRINT(0xee06);
466 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
467 for(i = 0; i < NUMCORESACTIVE; ++i) {
468 sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
469 } // for(i = 0; i < NUMCORESACTIVE; ++i)
470 GC_BAMBOO_DEBUGPRINT(0xee07);
471 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
472 if(0 == sumsendobj) {
473 // Check if there are changes of the numsendobjs or numreceiveobjs on
475 bool ischanged = false;
476 for(i = 0; i < NUMCORESACTIVE; ++i) {
477 if((gcnumsendobjs[0][i] != gcnumsendobjs[1][i]) ||
478 (gcnumreceiveobjs[0][i] != gcnumreceiveobjs[1][i]) ) {
482 } // for(i = 0; i < NUMCORESACTIVE; ++i)
483 GC_BAMBOO_DEBUGPRINT(0xee08);
484 GC_BAMBOO_DEBUGPRINT_REG(ischanged);
486 GC_BAMBOO_DEBUGPRINT(0xee09);
487 // all the core status info are the latest
489 gcphase = COMPACTPHASE;
490 // restore the gcstatus for all cores
491 for(i = 0; i < NUMCORESACTIVE; ++i) {
493 } // for(i = 0; i < NUMCORESACTIVE; ++i)
495 // There were changes between phase 1 and phase 2, can not decide
496 // whether the mark phase has been finished
498 // As it fails in phase 2, flip the entries
499 gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
502 // There were changes between phase 1 and phase 2, can not decide
503 // whether the mark phase has been finished
505 // As it fails in phase 2, flip the entries
506 gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
507 } // if(0 == sumsendobj) else ...
508 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
509 } // if(!gcwaitconfirm) else()
512 // There were changes between phase 1 and phase 2, can not decide
513 // whether the mark phase has been finished
515 // As it fails in phase 2, flip the entries
516 gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
517 //gcmarkwaitcounter = 1000;
518 //BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
519 }*/ /*else if(gcmarkwaitcounter == 0) {
520 tprintf("mark confirm reques \n");
521 // need to triger status check
522 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
524 numconfirm = NUMCORESACTIVE - 1;
525 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
526 for(i = 1; i < NUMCORESACTIVE; ++i) {
528 // send mark phase finish confirm request msg to core i
529 send_msg_1(i, GCMARKCONFIRM, false);
530 } // for(i = 1; i < NUMCORESACTIVE; ++i)
531 gcmarkwaitcounter = -1;
532 } else if(gcmarkwaitcounter != -1) {
534 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
536 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
538 } // if((!waitconfirm)...
539 GC_BAMBOO_DEBUGPRINT(0xee0a);
540 } // void checkMarkStatue()
542 inline void initGC() {
544 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
545 //gcmarkwaitcounter = -1;
546 for(i = 0; i < NUMCORES4GC; ++i) {
548 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
549 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
551 gcrequiredmems[i] = 0;
552 gcfilledblocks[i] = 0;
554 } // for(i = 0; i < NUMCORES4GC; ++i)
555 for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
557 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
558 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
564 // initialize the gcmappingtbl
565 BAMBOO_MEMSET_WH(gcmappingtbl, 0, bamboo_rmsp_size);
567 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
568 gcself_numsendobjs = 0;
569 gcself_numreceiveobjs = 0;
570 gcmarkedptrbound = 0;
581 gcheadindex=gctailindex=gctailindex2 = 0;
582 gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
584 gctailindex = gctailindex2 = gcheadindex;
585 gctail = gctail2 = gchead;
588 // initialize the large obj queues
589 if (gclobjhead==NULL) {
592 gclobjtailindex2 = 0;
593 gclobjhead=gclobjtail=gclobjtail2=
594 RUNMALLOC(sizeof(struct lobjpointerblock));
596 gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
597 gclobjtail = gclobjtail2 = gclobjhead;
599 gclobjhead->next = gclobjhead->prev = NULL;
601 freeMGCHash(gcforwardobjtbl);
602 gcforwardobjtbl = allocateMGCHash(20, 3);
605 gc_num_livespace = 0;
606 gc_num_freespace = 0;
608 gc_num_lobjspace = 0;
610 gc_num_forwardobj = 0;
611 gc_num_profiles = NUMCORESACTIVE - 1;
615 // compute load balance for all cores
616 inline int loadbalance(unsigned int * heaptop) {
617 // compute load balance
620 // get the total loads
621 unsigned int tloads = gcloads[STARTUPCORE];
622 for(i = 1; i < NUMCORES4GC; i++) {
623 tloads += gcloads[i];
625 *heaptop = gcbaseva + tloads;
627 GC_BAMBOO_DEBUGPRINT(0xdddd);
628 GC_BAMBOO_DEBUGPRINT_REG(tloads);
629 GC_BAMBOO_DEBUGPRINT_REG(*heaptop);
631 BLOCKINDEX(*heaptop, &b);
632 unsigned int numbpc = (unsigned int)b/(unsigned int)(NUMCORES4GC);// num of blocks per core
633 GC_BAMBOO_DEBUGPRINT_REG(b);
634 GC_BAMBOO_DEBUGPRINT_REG(numbpc);
636 RESIDECORE(heaptop, &gctopcore);
637 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
639 } // void loadbalance(int * heaptop)
641 inline bool cacheLObjs() {
642 // check the total mem size need for large objs
643 unsigned long long sumsize = 0;
644 unsigned int size = 0;
645 GC_BAMBOO_DEBUGPRINT(0xe801);
646 gclobjtail2 = gclobjtail;
647 gclobjtailindex2 = gclobjtailindex;
648 unsigned int tmp_lobj = 0;
649 unsigned int tmp_len = 0;
650 unsigned int tmp_host = 0;
651 // compute total mem size required and sort the lobjs in ascending order
652 // TODO USE QUICK SORT INSTEAD?
653 while(gc_lobjmoreItems2_I()) {
655 tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
656 tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
657 tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
661 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
668 GC_BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
669 GC_BAMBOO_DEBUGPRINT_REG(tmp_len);
670 GC_BAMBOO_DEBUGPRINT_REG(sumsize);
671 unsigned int i = gclobjtailindex2-1;
672 struct lobjpointerblock * tmp_block = gclobjtail2;
673 // find the place to insert
676 if(tmp_block->prev == NULL) {
679 if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
680 tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
681 tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
682 tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
683 tmp_block = tmp_block->prev;
687 } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
689 if(tmp_block->lobjs[i-1] > tmp_lobj) {
690 tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
691 tmp_block->lengths[i] = tmp_block->lengths[i-1];
692 tmp_block->hosts[i] = tmp_block->hosts[i-1];
696 } // if(tmp_block->lobjs[i-1] < tmp_lobj)
697 } // if(i ==0 ) else {}
700 if(i != gclobjtailindex2 - 1) {
701 tmp_block->lobjs[i] = tmp_lobj;
702 tmp_block->lengths[i] = tmp_len;
703 tmp_block->hosts[i] = tmp_host;
705 } // while(gc_lobjmoreItems2())
709 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
711 gc_num_lobjspace = sumsize;
716 // check if there are enough space to cache these large objs
717 unsigned int dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
718 if((unsigned long long)gcheaptop > (unsigned long long)dst) {
719 // do not have enough room to cache large objs
720 GC_BAMBOO_DEBUGPRINT(0xe802);
721 GC_BAMBOO_DEBUGPRINT_REG(dst);
722 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
723 GC_BAMBOO_DEBUGPRINT_REG(sumsize);
726 GC_BAMBOO_DEBUGPRINT(0xe803);
727 GC_BAMBOO_DEBUGPRINT_REG(dst);
728 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
730 gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
731 // cache the largeObjs to the top of the shared heap
732 dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
733 while(gc_lobjmoreItems3_I()) {
735 size = gclobjtail2->lengths[gclobjtailindex2];
736 // set the mark field to , indicating that this obj has been moved
737 // and need to be flushed
738 ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[BAMBOOMARKBIT] = COMPACTED;
740 if((unsigned int)dst <
741 (unsigned int)(gclobjtail2->lobjs[gclobjtailindex2]+size)) {
742 memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
744 memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
746 GC_BAMBOO_DEBUGPRINT(0x804);
747 GC_BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
748 GC_BAMBOO_DEBUGPRINT(dst);
749 GC_BAMBOO_DEBUGPRINT_REG(size);
750 GC_BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
751 GC_BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
754 } // void cacheLObjs()
756 // update the bmmboo_smemtbl to record current shared mem usage
757 void updateSmemTbl(unsigned int coren,
758 unsigned int localtop) {
759 unsigned int ltopcore = 0;
760 unsigned int bound = BAMBOO_SMEM_SIZE_L;
761 BLOCKINDEX(localtop, <opcore);
762 if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
763 bound = BAMBOO_SMEM_SIZE;
765 unsigned int load = (unsigned int)(localtop-gcbaseva)%(unsigned int)bound;
768 unsigned int toset = 0;
770 toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
772 if(toset >= gcnumblock) {
773 tprintf("ltopcore: %d, localtop: %x, toset: %d, gcnumblock: %d (%d, %d) \n", ltopcore, localtop, toset, gcnumblock, i, j);
777 if(toset < ltopcore) {
778 bamboo_smemtbl[toset]=
779 (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
781 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
783 } else if(toset == ltopcore) {
784 bamboo_smemtbl[toset] = load;
786 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
798 } // void updateSmemTbl(int, int)
800 inline void moveLObjs() {
801 GC_BAMBOO_DEBUGPRINT(0xea01);
803 // update the gcmem_mixed_usedmem
804 gcmem_mixed_usedmem = 0;
806 // zero out the smemtbl
807 BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
808 // find current heap top
809 // flush all gcloads to indicate the real heap top on one core
810 // previous it represents the next available ptr on a core
811 if(((unsigned int)gcloads[0] > (unsigned int)(gcbaseva+BAMBOO_SMEM_SIZE_L))
812 && (((unsigned int)gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
813 // edge of a block, check if this is exactly the heaptop
814 BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
815 gcloads[0]+=(gcfilledblocks[0]>1 ?
816 (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
818 updateSmemTbl(0, gcloads[0]);
819 GC_BAMBOO_DEBUGPRINT(0xea02);
820 GC_BAMBOO_DEBUGPRINT_REG(gcloads[0]);
821 GC_BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
822 for(int i = 1; i < NUMCORES4GC; i++) {
823 unsigned int tmptop = 0;
824 GC_BAMBOO_DEBUGPRINT(0xf000+i);
825 GC_BAMBOO_DEBUGPRINT_REG(gcloads[i]);
826 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
827 if((gcfilledblocks[i] > 0)
828 && (((unsigned int)gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
829 // edge of a block, check if this is exactly the heaptop
830 BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
832 (gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
835 updateSmemTbl(i, gcloads[i]);
836 GC_BAMBOO_DEBUGPRINT_REG(gcloads[i]);
837 } // for(int i = 1; i < NUMCORES4GC; i++) {
839 // find current heap top
841 // a bug here: when using local allocation, directly move large objects
842 // to the highest free chunk might not be memory efficient
843 unsigned int tmpheaptop = 0;
844 unsigned int size = 0;
845 unsigned int bound = 0;
847 for(i = gcnumblock-1; i >= 0; i--) {
848 if(bamboo_smemtbl[i] > 0) {
853 tmpheaptop = gcbaseva;
855 tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
856 (BAMBOO_SMEM_SIZE_L*i) :
857 (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
860 // move large objs from gcheaptop to tmpheaptop
861 // write the header first
862 unsigned int tomove = gcbaseva+(BAMBOO_SHARED_MEM_SIZE)-gcheaptop;
864 gcmem_mixed_usedmem += tomove;
866 GC_BAMBOO_DEBUGPRINT(0xea03);
867 GC_BAMBOO_DEBUGPRINT_REG(tomove);
868 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
869 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
870 // flush the sbstartbl
871 BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
872 (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-(unsigned int)gcreservedsb)
873 *sizeof(unsigned int));
875 gcheaptop = tmpheaptop;
877 // check how many blocks it acrosses
878 unsigned int remain = tmpheaptop-gcbaseva;
879 unsigned int sb = remain/BAMBOO_SMEM_SIZE+(unsigned int)gcreservedsb;//number of the sblock
880 unsigned int b = 0; // number of the block
881 BLOCKINDEX(tmpheaptop, &b);
882 // check the remaining space in this block
883 bound = (BAMBOO_SMEM_SIZE);
884 if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
885 bound = (BAMBOO_SMEM_SIZE_L);
887 remain = bound - remain%bound;
889 GC_BAMBOO_DEBUGPRINT(0xea04);
891 unsigned int isize = 0;
892 unsigned int host = 0;
893 unsigned int ptr = 0;
894 unsigned int base = tmpheaptop;
895 unsigned int cpysize = 0;
896 remain -= BAMBOO_CACHE_LINE_SIZE;
897 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
898 gc_lobjqueueinit4_I();
899 while(gc_lobjmoreItems4_I()) {
900 ptr = (unsigned int)(gc_lobjdequeue4_I(&size, &host));
901 ALIGNSIZE(size, &isize);
903 // this object acrosses blocks
905 // close current block, fill its header
906 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
907 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
908 bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE;//add the size of header
910 if(b >= gcnumblock) {
917 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
918 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
920 remain -= BAMBOO_CACHE_LINE_SIZE;
921 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
922 BLOCKINDEX(tmpheaptop, &b);
923 sb = (unsigned int)(tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE)
927 // move the large obj
928 if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
929 memmove(tmpheaptop, gcheaptop, size);
931 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
932 memcpy(tmpheaptop, gcheaptop, size);
934 // fill the remaining space with -2 padding
935 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
936 GC_BAMBOO_DEBUGPRINT(0xea05);
937 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
938 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
939 GC_BAMBOO_DEBUGPRINT_REG(size);
940 GC_BAMBOO_DEBUGPRINT_REG(isize);
941 GC_BAMBOO_DEBUGPRINT_REG(base);
944 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] != 3)) {
945 tprintf("Error moveLobj: %x %x \n",
946 (int)ptr, ((int *)(ptr))[BAMBOOMARKBIT] );
950 // cache the mapping info
951 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] =
952 (unsigned int)tmpheaptop;
954 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] ==
955 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)-1]) {
956 tprintf("Error moveobj ^^ : %x, %x, %d \n", (int)ptr,
957 (int)tmpheaptop, OBJMAPPINGINDEX((unsigned int)ptr));
961 GC_BAMBOO_DEBUGPRINT(0xcdca);
962 GC_BAMBOO_DEBUGPRINT_REG(ptr);
963 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
966 // set the gcsbstarttbl and bamboo_smemtbl
967 unsigned int tmpsbs=1+(unsigned int)(isize-remain-1)/BAMBOO_SMEM_SIZE;
968 for(int k = 1; k < tmpsbs; k++) {
969 gcsbstarttbl[sb+k] = -1;
971 if((sb+k) >= gcsbstarttbl_len) {
977 bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
978 BLOCKINDEX(tmpheaptop-1, &tmpsbs);
979 for(; b < tmpsbs; b++) {
980 bamboo_smemtbl[b] = bound;
982 if(b >= gcnumblock) {
986 if(b==NUMCORES4GC-1) {
987 bound = BAMBOO_SMEM_SIZE;
990 if(((unsigned int)(isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
991 gcsbstarttbl[sb] = -1;
992 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
993 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
994 bamboo_smemtbl[b] = bound;
996 gcsbstarttbl[sb] = (int)tmpheaptop;
997 remain = tmpheaptop-gcbaseva;
998 bamboo_smemtbl[b] = remain%bound;
999 remain = bound - bamboo_smemtbl[b];
1000 } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
1002 if(sb >= gcsbstarttbl_len) {
1003 BAMBOO_EXIT(0xb007);
1005 if(b >= gcnumblock) {
1006 BAMBOO_EXIT(0xb008);
1010 // close current block and fill the header
1011 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1012 *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
1015 if(remain == BAMBOO_CACHE_LINE_SIZE) {
1016 // fill with 0 in case
1017 BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
1019 remain -= BAMBOO_CACHE_LINE_SIZE;
1020 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
1023 // move the large obj
1024 if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
1025 memmove(tmpheaptop, gcheaptop, size);
1027 memcpy(tmpheaptop, gcheaptop, size);
1029 // fill the remaining space with -2 padding
1030 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
1031 GC_BAMBOO_DEBUGPRINT(0xea06);
1032 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1033 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1034 GC_BAMBOO_DEBUGPRINT_REG(size);
1035 GC_BAMBOO_DEBUGPRINT_REG(isize);
1040 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] != 3)) {
1041 tprintf("Error moveLobj: %x %x \n", (int)ptr,
1042 ((int *)(ptr))[BAMBOOMARKBIT] );
1043 BAMBOO_EXIT(0xb009);
1046 // cache the mapping info
1047 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] =
1048 (unsigned int)tmpheaptop;
1050 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] ==
1051 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)-1]) {
1052 tprintf("Error moveobj ?? : %x, %x, %d \n", (int)ptr,
1053 (int)tmpheaptop, OBJMAPPINGINDEX((unsigned int)ptr));
1054 BAMBOO_EXIT(0xb00a);
1056 if(!ISSHAREDOBJ(tmpheaptop)) {
1057 tprintf("Error: %x, %x \n", (int)ptr, (int)tmpheaptop);
1058 BAMBOO_EXIT(0xb00b);
1061 GC_BAMBOO_DEBUGPRINT(0xcdcc);
1062 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1063 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1064 GC_BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
1065 tmpheaptop += isize;
1067 // update bamboo_smemtbl
1068 bamboo_smemtbl[b] += isize;
1070 if(b >= gcnumblock) {
1071 BAMBOO_EXIT(0xb00c);
1074 } // if(remain < isize) else ...
1075 } // while(gc_lobjmoreItems())
1077 // close current block, fill the header
1078 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1079 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
1080 bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;//add the size of the header
1082 if(b >= gcnumblock) {
1083 BAMBOO_EXIT(0xb00d);
1087 tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
1089 gcheaptop = tmpheaptop;
1091 } // if(tomove == 0)
1093 GC_BAMBOO_DEBUGPRINT(0xea07);
1094 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1096 bamboo_free_block = 0;
1097 unsigned int tbound = 0;
1099 tbound = (bamboo_free_block<NUMCORES4GC) ?
1100 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1101 if(bamboo_smemtbl[bamboo_free_block] == tbound) {
1102 bamboo_free_block++;
1104 // the first non-full partition
1109 if(bamboo_free_block >= gcnumblock) {
1110 BAMBOO_EXIT(0xb00e);
1116 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
1118 // check how many live space there are
1119 gc_num_livespace = 0;
1120 for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
1121 gc_num_livespace += bamboo_smemtbl[tmpi];
1123 gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace;
1128 GC_BAMBOO_DEBUGPRINT(0xea08);
1129 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1130 } // void moveLObjs()
1132 inline void markObj(void * objptr) {
1133 if(objptr == NULL) {
1136 if(ISSHAREDOBJ(objptr)) {
1137 unsigned int host = hostcore(objptr);
1138 if(BAMBOO_NUM_OF_CORE == host) {
1140 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1141 if(((int *)objptr)[BAMBOOMARKBIT] == INIT) {
1142 // this is the first time that this object is discovered,
1143 // set the flag as DISCOVERED
1144 ((int *)objptr)[BAMBOOMARKBIT] = DISCOVERED;
1145 BAMBOO_CACHE_FLUSH_LINE(objptr);
1146 gc_enqueue_I(objptr);
1149 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]=1;
1152 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1154 GC_BAMBOO_DEBUGPRINT(0xbbbb);
1155 GC_BAMBOO_DEBUGPRINT_REG(host);
1156 GC_BAMBOO_DEBUGPRINT_REG(objptr);
1157 // check if this obj has been forwarded
1158 if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
1159 // send a msg to host informing that objptr is active
1160 send_msg_2(host, GCMARKEDOBJ, objptr, false);
1163 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
1165 gc_num_forwardobj++;
1169 #endif // GC_PROFILE
1170 gcself_numsendobjs++;
1171 MGCHashadd(gcforwardobjtbl, (int)objptr);
1176 tprintf("Non shared pointer to be marked %x \n", (int)objptr);
1177 BAMBOO_EXIT(0xb00f);
1179 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1180 gc_enqueue_I(objptr);
1181 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1182 } // if(ISSHAREDOBJ(objptr))
1183 } // void markObj(void * objptr)
1185 // enqueue root objs
1186 inline void tomark(struct garbagelist * stackptr) {
1187 if(MARKPHASE != gcphase) {
1188 GC_BAMBOO_DEBUGPRINT_REG(gcphase);
1189 BAMBOO_EXIT(0xb010);
1191 gcbusystatus = true;
1196 // enqueue current stack
1197 while(stackptr!=NULL) {
1198 GC_BAMBOO_DEBUGPRINT(0xe501);
1199 GC_BAMBOO_DEBUGPRINT_REG(stackptr->size);
1200 GC_BAMBOO_DEBUGPRINT_REG(stackptr->next);
1201 GC_BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
1202 for(i=0; i<stackptr->size; i++) {
1203 if(stackptr->array[i] != NULL) {
1204 markObj(stackptr->array[i]);
1207 stackptr=stackptr->next;
1209 GC_BAMBOO_DEBUGPRINT(0xe502);
1211 // enqueue static pointers global_defs_p
1212 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1213 struct garbagelist * staticptr=(struct garbagelist *)global_defs_p;
1214 while(staticptr != NULL) {
1215 for(i=0; i<staticptr->size; i++) {
1216 if(staticptr->array[i] != NULL) {
1217 markObj(staticptr->array[i]);
1220 staticptr = staticptr->next;
1223 GC_BAMBOO_DEBUGPRINT(0xe503);
1226 // enqueue objectsets
1227 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1228 for(i=0; i<NUMCLASSES; i++) {
1229 struct parameterwrapper ** queues =
1230 objectqueues[BAMBOO_NUM_OF_CORE][i];
1231 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
1232 for(j = 0; j < length; ++j) {
1233 struct parameterwrapper * parameter = queues[j];
1234 struct ObjectHash * set=parameter->objectset;
1235 struct ObjectNode * ptr=set->listhead;
1237 markObj((void *)ptr->key);
1244 // euqueue current task descriptor
1245 if(currtpd != NULL) {
1246 GC_BAMBOO_DEBUGPRINT(0xe504);
1247 for(i=0; i<currtpd->numParameters; i++) {
1248 markObj(currtpd->parameterArray[i]);
1252 GC_BAMBOO_DEBUGPRINT(0xe505);
1253 // euqueue active tasks
1254 if(activetasks != NULL) {
1255 struct genpointerlist * ptr=activetasks->list;
1257 struct taskparamdescriptor *tpd=ptr->src;
1259 for(i=0; i<tpd->numParameters; i++) {
1260 markObj(tpd->parameterArray[i]);
1266 GC_BAMBOO_DEBUGPRINT(0xe506);
1267 // enqueue cached transferred obj
1268 struct QueueItem * tmpobjptr = getHead(&objqueue);
1269 while(tmpobjptr != NULL) {
1270 struct transObjInfo * objInfo =
1271 (struct transObjInfo *)(tmpobjptr->objectptr);
1272 markObj(objInfo->objptr);
1273 tmpobjptr = getNextQueueItem(tmpobjptr);
1276 GC_BAMBOO_DEBUGPRINT(0xe507);
1277 // enqueue cached objs to be transferred
1278 struct QueueItem * item = getHead(totransobjqueue);
1279 while(item != NULL) {
1280 struct transObjInfo * totransobj =
1281 (struct transObjInfo *)(item->objectptr);
1282 markObj(totransobj->objptr);
1283 item = getNextQueueItem(item);
1284 } // while(item != NULL)
1286 GC_BAMBOO_DEBUGPRINT(0xe508);
1287 // enqueue lock related info
1288 for(i = 0; i < runtime_locklen; ++i) {
1289 markObj((void *)(runtime_locks[i].redirectlock));
1290 if(runtime_locks[i].value != NULL) {
1291 markObj((void *)(runtime_locks[i].value));
1294 GC_BAMBOO_DEBUGPRINT(0xe509);
1298 // enqueue global thread queue
1299 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1301 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
1302 if(thread_counter > 0) {
1303 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
1304 for(i = thread_counter; i > 0; i--) {
1305 markObj((void *)bamboo_thread_queue[4+start]);
1306 start = (start+1)&bamboo_max_thread_num_mask;
1311 // enqueue the bamboo_threadlocks
1312 if(bamboo_threadlocks != 0) {
1313 markObj((void *)bamboo_threadlocks);
1316 // enqueue the bamboo_current_thread
1317 if(bamboo_current_thread != 0) {
1318 markObj((void *)bamboo_current_thread);
1321 GC_BAMBOO_DEBUGPRINT(0xe50a);
1323 } // void tomark(struct garbagelist * stackptr)
1325 inline void mark(bool isfirst,
1326 struct garbagelist * stackptr) {
1327 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed01);
1329 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed02);
1330 // enqueue root objs
1332 gccurr_heaptop = 0; // record the size of all active objs in this core
1333 // aligned but does not consider block boundaries
1334 gcmarkedptrbound = 0;
1336 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed03);
1337 unsigned int isize = 0;
1338 bool checkfield = true;
1339 bool sendStall = false;
1341 while(MARKPHASE == gcphase) {
1342 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed04);
1344 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1345 bool hasItems = gc_moreItems2_I();
1346 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1347 GC_BAMBOO_DEBUGPRINT(0xed05);
1352 gcbusystatus = true;
1354 void * ptr = gc_dequeue2_I();
1356 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1357 unsigned int size = 0;
1358 unsigned int isize = 0;
1359 unsigned int type = 0;
1360 // check if it is a shared obj
1361 if(ISSHAREDOBJ(ptr)) {
1362 // a shared obj, check if it is a local obj on this core
1363 unsigned int host = hostcore(ptr);
1364 bool islocal = (host == BAMBOO_NUM_OF_CORE);
1366 bool isnotmarked = (((int *)ptr)[BAMBOOMARKBIT] == DISCOVERED);
1367 if(isLarge(ptr, &type, &size) && isnotmarked) {
1368 // ptr is a large object and not marked or enqueued
1369 GC_BAMBOO_DEBUGPRINT(0xecec);
1370 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1371 GC_BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
1372 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1373 gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
1375 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1377 ((int *)ptr)[BAMBOOMARKBIT] = MARKED;
1378 BAMBOO_CACHE_FLUSH_LINE(ptr);
1381 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=3;
1383 } else if(isnotmarked) {
1384 // ptr is an unmarked active object on this core
1385 ALIGNSIZE(size, &isize);
1386 gccurr_heaptop += isize;
1387 GC_BAMBOO_DEBUGPRINT(0xaaaa);
1388 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1389 GC_BAMBOO_DEBUGPRINT_REG(isize);
1390 GC_BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
1392 ((int *)ptr)[BAMBOOMARKBIT] = MARKED;
1393 BAMBOO_CACHE_FLUSH_LINE(ptr);
1396 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=2;
1399 if((unsigned int)(ptr + size) > (unsigned int)gcmarkedptrbound) {
1400 gcmarkedptrbound = (unsigned int)(ptr + size);
1401 } // if(ptr + size > gcmarkedptrbound)
1403 // ptr is not an active obj or has been marked
1405 } // if(isLarge(ptr, &type, &size)) else ...
1409 tprintf("Error mark: %x, %d, %d \n", (int)ptr, BAMBOO_NUM_OF_CORE,
1411 BAMBOO_EXIT(0xb011);
1413 #endif /* can never reach here
1415 // check if this obj has been forwarded
1416 if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
1417 // send a msg to host informing that ptr is active
1418 send_msg_2(host, GCMARKEDOBJ, ptr, false);
1419 gcself_numsendobjs++;
1420 MGCHashadd(gcforwardobjtbl, (int)ptr);
1423 }// if(isLocal(ptr)) else ...*/
1424 } // if(ISSHAREDOBJ(ptr))
1425 GC_BAMBOO_DEBUGPRINT(0xed06);
1428 // scan all pointers in ptr
1429 unsigned int * pointer;
1430 pointer=pointerarray[type];
1432 /* Array of primitives */
1434 } else if (((unsigned int)pointer)==1) {
1435 /* Array of pointers */
1436 struct ArrayObject *ao=(struct ArrayObject *) ptr;
1437 int length=ao->___length___;
1439 for(j=0; j<length; j++) {
1441 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
1444 /* check the ArrayObject struct first*/
1446 pointer=pointerarray[OBJECTTYPE];
1447 //handle object class
1448 unsigned int size=pointer[0];
1450 for(i=1; i<=size; i++) {
1451 unsigned int offset=pointer[i];
1452 void * objptr=*((void **)(((char *)ao)+offset));
1457 unsigned int size=pointer[0];
1459 for(i=1; i<=size; i++) {
1460 unsigned int offset=pointer[i];
1461 void * objptr=*((void **)(((char *)ptr)+offset));
1464 } // if (pointer==0) else if ... else ...
1466 } // while(gc_moreItems2())
1467 GC_BAMBOO_DEBUGPRINT(0xed07);
1468 gcbusystatus = false;
1469 // send mark finish msg to core coordinator
1470 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1471 GC_BAMBOO_DEBUGPRINT(0xed08);
1472 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
1473 gcnumsendobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
1474 gcnumreceiveobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=
1475 gcself_numreceiveobjs;
1476 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
1479 GC_BAMBOO_DEBUGPRINT(0xed09);
1480 send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
1481 gcself_numsendobjs, gcself_numreceiveobjs, false);
1484 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
1485 GC_BAMBOO_DEBUGPRINT(0xed0a);
1487 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1488 GC_BAMBOO_DEBUGPRINT(0xed0b);
1491 } // while(MARKPHASE == gcphase)
1496 inline void compact2Heaptophelper_I(unsigned int coren,
1498 unsigned int* numblocks,
1499 unsigned int* remain) {
1501 unsigned int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
1502 if(STARTUPCORE == coren) {
1504 gcmovestartaddr = *p;
1505 gcdstcore = gctopcore;
1506 gcblock2fill = *numblocks + 1;
1508 send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
1510 GC_BAMBOO_DEBUGPRINT_REG(coren);
1511 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1512 GC_BAMBOO_DEBUGPRINT_REG(*p);
1513 GC_BAMBOO_DEBUGPRINT_REG(*numblocks+1);
1514 if(memneed < *remain) {
1515 GC_BAMBOO_DEBUGPRINT(0xd104);
1517 gcrequiredmems[coren] = 0;
1518 gcloads[gctopcore] += memneed;
1519 *remain = *remain - memneed;
1521 GC_BAMBOO_DEBUGPRINT(0xd105);
1522 // next available block
1524 gcfilledblocks[gctopcore] += 1;
1525 unsigned int newbase = 0;
1526 BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
1527 gcloads[gctopcore] = newbase;
1528 gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
1529 gcstopblock[gctopcore]++;
1530 gctopcore = NEXTTOPCORE(gctopblock);
1532 *numblocks = gcstopblock[gctopcore];
1533 *p = gcloads[gctopcore];
1535 *remain=(b<NUMCORES4GC) ?
1536 ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
1537 : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
1538 GC_BAMBOO_DEBUGPRINT(0xd106);
1539 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1540 GC_BAMBOO_DEBUGPRINT_REG(*p);
1541 GC_BAMBOO_DEBUGPRINT_REG(b);
1542 GC_BAMBOO_DEBUGPRINT_REG(*remain);
1543 } // if(memneed < remain)
1545 } // void compact2Heaptophelper_I(int, int*, int*, int*)
1547 inline void compact2Heaptop() {
1548 // no cores with spare mem and some cores are blocked with pending move
1549 // find the current heap top and make them move to the heap top
1551 unsigned int numblocks = gcfilledblocks[gctopcore];
1552 p = gcloads[gctopcore];
1555 unsigned int remain = (b<NUMCORES4GC) ?
1556 ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
1557 : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
1558 // check if the top core finishes
1559 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1560 if(gccorestatus[gctopcore] != 0) {
1561 GC_BAMBOO_DEBUGPRINT(0xd101);
1562 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1563 // let the top core finishes its own work first
1564 compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
1565 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1568 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1570 GC_BAMBOO_DEBUGPRINT(0xd102);
1571 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1572 GC_BAMBOO_DEBUGPRINT_REG(p);
1573 GC_BAMBOO_DEBUGPRINT_REG(b);
1574 GC_BAMBOO_DEBUGPRINT_REG(remain);
1575 for(int i = 0; i < NUMCORES4GC; i++) {
1576 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1577 if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
1578 GC_BAMBOO_DEBUGPRINT(0xd103);
1579 compact2Heaptophelper_I(i, &p, &numblocks, &remain);
1580 if(gccorestatus[gctopcore] != 0) {
1581 GC_BAMBOO_DEBUGPRINT(0xd101);
1582 GC_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++)
1590 GC_BAMBOO_DEBUGPRINT(0xd106);
1591 } // void compact2Heaptop()
1593 inline void resolvePendingMoveRequest() {
1594 GC_BAMBOO_DEBUGPRINT(0xeb01);
1595 GC_BAMBOO_DEBUGPRINT(0xeeee);
1596 for(int k = 0; k < NUMCORES4GC; k++) {
1597 GC_BAMBOO_DEBUGPRINT(0xf000+k);
1598 GC_BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
1599 GC_BAMBOO_DEBUGPRINT_REG(gcloads[k]);
1600 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
1601 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
1603 GC_BAMBOO_DEBUGPRINT(0xffff);
1606 bool nosparemem = true;
1607 bool haspending = false;
1608 bool hasrunning = false;
1609 bool noblock = false;
1610 unsigned int dstcore = 0; // the core who need spare mem
1611 unsigned int sourcecore = 0; // the core who has spare mem
1612 for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
1614 // check if there are cores with spare mem
1615 if(gccorestatus[i] == 0) {
1616 // finished working, check if it still have spare mem
1617 if(gcfilledblocks[i] < gcstopblock[i]) {
1618 // still have spare mem
1621 } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
1626 if(gccorestatus[j] != 0) {
1627 // not finished, check if it has pending move requests
1628 if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
1633 } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
1634 } // if(gccorestatus[i] == 0) else ...
1636 } // if(!haspending)
1637 if(!nosparemem && haspending) {
1639 unsigned int tomove = 0;
1640 unsigned int startaddr = 0;
1641 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1642 gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
1643 gcrequiredmems[dstcore],
1646 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1647 GC_BAMBOO_DEBUGPRINT(0xeb02);
1648 GC_BAMBOO_DEBUGPRINT_REG(sourcecore);
1649 GC_BAMBOO_DEBUGPRINT_REG(dstcore);
1650 GC_BAMBOO_DEBUGPRINT_REG(startaddr);
1651 GC_BAMBOO_DEBUGPRINT_REG(tomove);
1652 if(STARTUPCORE == dstcore) {
1653 GC_BAMBOO_DEBUGPRINT(0xeb03);
1654 gcdstcore = sourcecore;
1656 gcmovestartaddr = startaddr;
1657 gcblock2fill = tomove;
1659 GC_BAMBOO_DEBUGPRINT(0xeb04);
1660 send_msg_4(dstcore, GCMOVESTART, sourcecore,
1661 startaddr, tomove, false);
1668 } // for(i = 0; i < NUMCORES4GC; i++)
1669 GC_BAMBOO_DEBUGPRINT(0xcccc);
1670 GC_BAMBOO_DEBUGPRINT_REG(hasrunning);
1671 GC_BAMBOO_DEBUGPRINT_REG(haspending);
1672 GC_BAMBOO_DEBUGPRINT_REG(noblock);
1674 if(!hasrunning && !noblock) {
1675 gcphase = SUBTLECOMPACTPHASE;
1679 } // void resovePendingMoveRequest()
1682 unsigned int numblocks; // block num for heap
1683 unsigned int base; // base virtual address of current heap block
1684 unsigned int ptr; // virtual address of current heap top
1685 unsigned int offset; // offset in current heap block
1686 unsigned int blockbase; // virtual address of current small block to check
1687 unsigned int blockbound; // bound virtual address of current small blcok
1688 unsigned int sblockindex; // index of the small blocks
1689 unsigned int top; // real size of current heap block to check
1690 unsigned int bound; // bound size of current heap block to check
1691 }; // struct moveHelper
1693 // If out of boundary of valid shared memory, return false, else return true
1694 inline bool nextSBlock(struct moveHelper * orig) {
1695 orig->blockbase = orig->blockbound;
1697 bool sbchanged = false;
1698 unsigned int origptr = orig->ptr;
1699 unsigned int blockbase = orig->blockbase;
1700 unsigned int blockbound = orig->blockbound;
1701 unsigned int bound = orig->bound;
1702 GC_BAMBOO_DEBUGPRINT(0xecc0);
1703 GC_BAMBOO_DEBUGPRINT_REG(blockbase);
1704 GC_BAMBOO_DEBUGPRINT_REG(blockbound);
1705 GC_BAMBOO_DEBUGPRINT_REG(bound);
1706 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1708 // check if across a big block
1709 // TODO now do not zero out the whole memory, maybe the last two conditions
1711 if((blockbase>=bound)||(origptr>=bound)
1712 ||((origptr!=NULL)&&(*((int*)origptr))==0)||((*((int*)blockbase))==0)) {
1714 // end of current heap block, jump to next one
1716 GC_BAMBOO_DEBUGPRINT(0xecc1);
1717 GC_BAMBOO_DEBUGPRINT_REG(orig->numblocks);
1718 BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
1719 GC_BAMBOO_DEBUGPRINT(orig->base);
1720 if(orig->base >= gcbaseva + BAMBOO_SHARED_MEM_SIZE) {
1722 orig->ptr = orig->base; // set current ptr to out of boundary too
1725 orig->blockbase = orig->base;
1727 (unsigned int)(orig->blockbase-gcbaseva)/BAMBOO_SMEM_SIZE;
1729 unsigned int blocknum = 0;
1730 BLOCKINDEX(orig->base, &blocknum);
1731 if(bamboo_smemtbl[blocknum] == 0) {
1733 if(blocknum >= gcnumblock) {
1734 BAMBOO_EXIT(0xb012);
1738 goto innernextSBlock;
1740 // check the bamboo_smemtbl to decide the real bound
1741 orig->bound = orig->base + bamboo_smemtbl[blocknum];
1742 } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
1743 orig->sblockindex += 1;
1745 } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
1747 // check if this sblock should be skipped or have special start point
1748 int sbstart = gcsbstarttbl[orig->sblockindex];
1750 if((orig->sblockindex) >= gcsbstarttbl_len) {
1751 BAMBOO_EXIT(0xb013);
1756 GC_BAMBOO_DEBUGPRINT(0xecc2);
1757 orig->sblockindex += 1;
1758 orig->blockbase += BAMBOO_SMEM_SIZE;
1759 goto outernextSBlock;
1760 } else if((sbstart != 0) && (sbchanged)) {
1761 // the first time to access this SBlock
1762 GC_BAMBOO_DEBUGPRINT(0xecc3);
1763 // not start from the very beginning
1764 orig->blockbase = sbstart;
1765 } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
1767 // setup information for this sblock
1768 orig->blockbound = orig->blockbase+(unsigned int)*((int*)(orig->blockbase));
1769 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1770 orig->ptr = orig->blockbase + orig->offset;
1771 GC_BAMBOO_DEBUGPRINT(0xecc4);
1772 GC_BAMBOO_DEBUGPRINT_REG(orig->base);
1773 GC_BAMBOO_DEBUGPRINT_REG(orig->bound);
1774 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
1775 GC_BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1776 GC_BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1777 GC_BAMBOO_DEBUGPRINT_REG(orig->offset);
1778 if(orig->ptr >= orig->bound) {
1779 // met a lobj, move to next block
1780 goto innernextSBlock;
1784 } // bool nextSBlock(struct moveHelper * orig)
1786 // return false if there are no available data to compact
1787 inline bool initOrig_Dst(struct moveHelper * orig,
1788 struct moveHelper * to) {
1791 to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
1792 to->bound = BAMBOO_SMEM_SIZE_L;
1793 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1795 GC_BAMBOO_DEBUGPRINT(0xef01);
1796 GC_BAMBOO_DEBUGPRINT_REG(to->base);
1797 unsigned int tobase = to->base;
1798 to->ptr = tobase + to->offset;
1799 #ifdef GC_CACHE_ADAPT
1800 // initialize the gc_cache_revise_information
1801 gc_cache_revise_infomation.to_page_start_va = to->ptr;
1802 unsigned int toindex = (unsigned int)(tobase-gcbaseva)/(BAMBOO_PAGE_SIZE);
1803 gc_cache_revise_infomation.to_page_end_va = (BAMBOO_PAGE_SIZE)*
1805 gc_cache_revise_infomation.to_page_index = toindex;
1806 gc_cache_revise_infomation.orig_page_start_va = -1;
1807 #endif // GC_CACHE_ADAPT
1809 // init the orig ptr
1810 orig->numblocks = 0;
1811 orig->base = tobase;
1812 unsigned int blocknum = 0;
1813 BLOCKINDEX(orig->base, &blocknum);
1814 unsigned int origbase = orig->base;
1815 // check the bamboo_smemtbl to decide the real bound
1816 orig->bound = origbase + (unsigned int)bamboo_smemtbl[blocknum];
1818 if((orig->sblockindex) >= gcsbstarttbl_len) {
1819 BAMBOO_EXIT(0xb014);
1822 orig->blockbase = origbase;
1823 orig->sblockindex = (unsigned int)(origbase - gcbaseva) / BAMBOO_SMEM_SIZE;
1824 GC_BAMBOO_DEBUGPRINT(0xef02);
1825 GC_BAMBOO_DEBUGPRINT_REG(origbase);
1826 GC_BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
1827 GC_BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
1828 GC_BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
1830 int sbstart = gcsbstarttbl[orig->sblockindex];
1832 if((orig->sblockindex) >= gcsbstarttbl_len) {
1833 BAMBOO_EXIT(0xb015);
1837 GC_BAMBOO_DEBUGPRINT(0xef03);
1840 gcbaseva+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
1841 return nextSBlock(orig);
1842 } else if(sbstart != 0) {
1843 GC_BAMBOO_DEBUGPRINT(0xef04);
1844 orig->blockbase = sbstart;
1846 GC_BAMBOO_DEBUGPRINT(0xef05);
1847 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1848 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1849 orig->ptr = orig->blockbase + orig->offset;
1850 GC_BAMBOO_DEBUGPRINT(0xef06);
1851 GC_BAMBOO_DEBUGPRINT_REG(orig->base);
1854 } // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
1856 inline void nextBlock(struct moveHelper * to) {
1857 to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
1858 to->bound += BAMBOO_SMEM_SIZE;
1860 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1861 to->offset = BAMBOO_CACHE_LINE_SIZE;
1862 to->ptr = to->base + to->offset;
1863 } // void nextBlock(struct moveHelper * to)
1865 #ifdef GC_CACHE_ADAPT
1866 inline void samplingDataConvert(int current_ptr) {
1867 unsigned int tmp_factor =
1868 current_ptr-gc_cache_revise_infomation.to_page_start_va;
1869 int topage=gc_cache_revise_infomation.to_page_index;
1870 int oldpage = gc_cache_revise_infomation.orig_page_index;
1871 unsigned int * newtable=&gccachesamplingtbl_r[topage];
1872 unsigned int * oldtable=&gccachesamplingtbl[oldpage];
1874 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
1875 (*newtable) = ((*newtable)+(*oldtable)*tmp_factor);
1876 newtable=(unsigned int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
1877 oldtable=(unsigned int*) (((char *)oldtable)+size_cachesamplingtbl_local);
1879 } // inline void samplingDataConvert(int)
1881 inline void completePageConvert(struct moveHelper * orig,
1882 struct moveHelper * to,
1883 unsigned int current_ptr,
1885 unsigned int ptr = 0;
1889 tocompare = gc_cache_revise_infomation.to_page_end_va;
1892 tocompare = gc_cache_revise_infomation.orig_page_end_va;
1894 if(ptr >= tocompare) {
1895 // end of an orig/to page
1896 // compute the impact of this page for the new page
1897 samplingDataConvert(current_ptr);
1898 // prepare for an new orig page
1899 int tmp_index = (orig->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE);
1900 gc_cache_revise_infomation.orig_page_start_va = orig->ptr;
1901 gc_cache_revise_infomation.orig_page_end_va = gcbaseva +
1902 (BAMBOO_PAGE_SIZE)*(tmp_index+1);
1903 gc_cache_revise_infomation.orig_page_index = tmp_index;
1904 gc_cache_revise_infomation.to_page_start_va = to->ptr;
1906 gc_cache_revise_infomation.to_page_end_va = gcbaseva +
1907 (BAMBOO_PAGE_SIZE)*((to->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
1908 gc_cache_revise_infomation.to_page_index =
1909 (to->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE);
1912 } // inline void completePageConvert(...)
1913 #endif // GC_CACHE_ADAPT
1915 // endaddr does not contain spaces for headers
1916 inline bool moveobj(struct moveHelper * orig,
1917 struct moveHelper * to,
1918 unsigned int stopblock) {
1919 if(stopblock == 0) {
1923 GC_BAMBOO_DEBUGPRINT(0xe201);
1924 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
1925 GC_BAMBOO_DEBUGPRINT_REG(to->ptr);
1927 unsigned int bkptr = (unsigned int)(orig->ptr);
1929 if((unsigned int)(to->ptr) > (unsigned int)(orig->ptr)) {
1930 tprintf("Error to->ptr > orig->ptr: %x, %x \n", (int)(to->ptr), (int)(orig->ptr));
1931 BAMBOO_EXIT(0xb016);
1936 unsigned int size = 0;
1937 unsigned int isize = 0;
1939 /*while((*((char*)(orig->ptr))) == (char)(-2)) {
1940 orig->ptr = (unsigned int)((void*)(orig->ptr) + 1);
1942 #ifdef GC_CACHE_ADAPT
1943 completePageConvert(orig, to, to->ptr, false);
1945 unsigned int origptr = (unsigned int)(orig->ptr);
1946 unsigned int origbound = (unsigned int)orig->bound;
1947 unsigned int origblockbound = (unsigned int)orig->blockbound;
1948 if((origptr >= origbound) || (origptr == origblockbound)) {
1949 if(!nextSBlock(orig)) {
1950 // finished, no more data
1952 tprintf("AAAA %x \n", (int)(orig->ptr));
1958 GC_BAMBOO_DEBUGPRINT(0xe202);
1959 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1960 GC_BAMBOO_DEBUGPRINT(((int *)(origptr))[0]);
1961 // check the obj's type, size and mark flag
1962 type = ((int *)(origptr))[0];
1965 // end of this block, go to next one
1966 if(!nextSBlock(orig)) {
1967 // finished, no more data
1969 tprintf("BBBB %x \n", (int)(orig->ptr));
1974 } else if(type < NUMCLASSES) {
1976 size = classsize[type];
1979 struct ArrayObject *ao=(struct ArrayObject *)(origptr);
1980 unsigned int elementsize=classsize[type];
1981 unsigned int length=ao->___length___;
1982 size=(unsigned int)sizeof(struct ArrayObject)
1983 +(unsigned int)(length*elementsize);
1985 GC_BAMBOO_DEBUGPRINT(0xe203);
1986 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1987 GC_BAMBOO_DEBUGPRINT_REG(size);
1988 ALIGNSIZE(size, &isize); // no matter is the obj marked or not
1989 // should be able to across
1991 int sindex = OBJMAPPINGINDEX((unsigned int)bkptr);
1992 int eindex = OBJMAPPINGINDEX((unsigned int)(origptr));
1993 for(int tmpi = sindex+1; tmpi < eindex; tmpi++) {
1994 if((gcmappingtbl[tmpi] != 0) &&
1995 (hostcore(gcbaseva+bamboo_baseobjsize*tmpi)==BAMBOO_NUM_OF_CORE) &&
1996 (hostcore(gcbaseva+bamboo_baseobjsize*(tmpi+1))==BAMBOO_NUM_OF_CORE)) {
1997 tprintf("Error moveobj --: %x, %x, %x, %d, %x \n", (int)bkptr,
1998 (int)origptr, (int)(gcbaseva+bamboo_baseobjsize*tmpi),
1999 (int)gcmappingtbl[tmpi], (int)(*((char*)(bkptr))));
2000 BAMBOO_EXIT(0xb017);
2004 if(((int *)(origptr))[BAMBOOMARKBIT] == MARKED) {
2005 unsigned int totop = (unsigned int)to->top;
2006 unsigned int tobound = (unsigned int)to->bound;
2007 GC_BAMBOO_DEBUGPRINT(0xe204);
2010 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
2017 // marked obj, copy it to current heap top
2018 // check to see if remaining space is enough
2019 if((unsigned int)(totop + isize) > tobound) {
2020 // fill 0 indicating the end of this block
2021 BAMBOO_MEMSET_WH(to->ptr, '\0', tobound - totop);
2022 // fill the header of this block and then go to next block
2023 to->offset += tobound - totop;
2024 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2025 (*((int*)(to->base))) = to->offset;
2026 #ifdef GC_CACHE_ADAPT
2027 unsigned int tmp_ptr = to->ptr;
2028 #endif // GC_CACHE_ADAPT
2030 #ifdef GC_CACHE_ADAPT
2031 completePageConvert(orig, to, tmp_ptr, true);
2032 #endif // GC_CACHE_ADAPT
2033 if(stopblock == to->numblocks) {
2034 // already fulfilled the block
2036 tprintf("CCCC %x \n", (int)(orig->ptr));
2039 } // if(stopblock == to->numblocks)
2040 } // if(to->top + isize > to->bound)
2041 // set the mark field to 2, indicating that this obj has been moved
2042 // and need to be flushed
2043 ((int *)(origptr))[BAMBOOMARKBIT] = COMPACTED;
2044 unsigned int toptr = (unsigned int)to->ptr;
2047 // scan all pointers in ptr
2048 unsigned int * tt_pointer;
2049 tt_pointer=pointerarray[type];
2050 if (tt_pointer==0) {
2051 /* Array of primitives */
2053 } else if (((unsigned int)tt_pointer)==1) {
2054 /* Array of pointers */
2055 struct ArrayObject *ao=(struct ArrayObject *)(origptr);
2056 int tt_length=ao->___length___;
2058 for(tt_j=0; tt_j<tt_length; tt_j++) {
2060 ((void **)(((char *)&ao->___length___)+sizeof(int)))[tt_j];
2062 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2063 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2064 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2065 (int)origptr, (int)objptr, __LINE__, tt_j,
2066 ((int *)(origptr))[0], ((int *)(objptr))[0],
2067 ((int *)(objptr))[BAMBOOMARKBIT],
2068 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2069 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2070 BAMBOO_EXIT(0xb018);
2073 /* check the ArrayObject struct first*/
2075 tt_pointer=pointerarray[OBJECTTYPE];
2076 //handle object class
2077 unsigned int size=tt_pointer[0];
2079 for(i=1; i<=size; i++) {
2080 unsigned int offset=tt_pointer[i];
2081 void * objptr=*((void **)(((char *)ao)+offset));
2083 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2084 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2085 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2086 (int)origptr, (int)objptr, __LINE__, tt_j,
2087 ((int *)(origptr))[0], ((int *)(objptr))[0],
2088 ((int *)(objptr))[BAMBOOMARKBIT],
2089 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2090 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2091 BAMBOO_EXIT(0xb019);
2096 unsigned int tt_size=tt_pointer[0];
2098 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2099 unsigned int tt_offset=tt_pointer[tt_i];
2100 void * objptr=*((void **)(((char *)origptr)+tt_offset));
2102 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2103 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2104 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2105 (int)origptr, (int)objptr, __LINE__, tt_i,
2106 ((int *)(origptr))[0], ((int *)(objptr))[0],
2107 ((int *)(objptr))[BAMBOOMARKBIT],
2108 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2109 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2110 BAMBOO_EXIT(0xb01a);
2113 } // if (pointer==0) else if ... else ...
2115 if((unsigned int)(toptr) > (unsigned int)(origptr)) {
2116 tprintf("Error to->ptr > orig->ptr: %x, %x \n", (int)(toptr),
2118 BAMBOO_EXIT(0xb01b);
2121 if(toptr != origptr) {
2122 if((unsigned int)(origptr) < (unsigned int)(toptr+size)) {
2123 memmove(toptr, origptr, size);
2125 memcpy(toptr, origptr, size);
2127 // fill the remaining space with -2
2128 BAMBOO_MEMSET_WH((unsigned int)(toptr+size), -2, isize-size);
2131 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)] != 2)) {
2132 tprintf("Error moveobj: %x, %x, %d \n", (int)origptr,
2133 ((int *)(origptr))[BAMBOOMARKBIT],
2134 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)]);
2135 BAMBOO_EXIT(0xb01c);
2138 // store mapping info
2139 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)]=(unsigned int)toptr;
2141 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)] ==
2142 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)-1]) {
2143 tprintf("Error moveobj ++ : %x, %x, %d \n", (int)origptr, (int)toptr,
2144 OBJMAPPINGINDEX((unsigned int)origptr));
2145 BAMBOO_EXIT(0xb01d);
2147 // scan all pointers in ptr
2148 unsigned int * tt_pointer;
2149 tt_pointer=pointerarray[type];
2150 if (tt_pointer==0) {
2151 /* Array of primitives */
2153 } else if (((unsigned int)tt_pointer)==1) {
2154 /* Array of pointers */
2155 struct ArrayObject *ao=(struct ArrayObject *)(toptr);
2156 int tt_length=ao->___length___;
2158 for(tt_j=0; tt_j<tt_length; tt_j++) {
2160 ((void **)(((char *)&ao->___length___)+sizeof(int)))[tt_j];
2163 /* check the ArrayObject struct first*/
2165 tt_pointer=pointerarray[OBJECTTYPE];
2166 //handle object class
2167 unsigned int size=tt_pointer[0];
2169 for(i=1; i<=size; i++) {
2170 unsigned int offset=tt_pointer[i];
2171 void * objptr=*((void **)(((char *)ao)+offset));
2173 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0)) {
2174 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2175 (int)origptr, (int)objptr, __LINE__, tt_j,
2176 ((int *)(origptr))[0], ((int *)(objptr))[0],
2177 ((int *)(objptr))[BAMBOOMARKBIT],
2178 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2179 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2180 BAMBOO_EXIT(0xb01e);
2185 unsigned int tt_size=tt_pointer[0];
2187 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2188 unsigned int tt_offset=tt_pointer[tt_i];
2189 void * objptr=*((void **)(((char *)toptr)+tt_offset));
2191 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0)) {
2192 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2193 (int)origptr, (int)objptr, __LINE__, tt_i,
2194 ((int *)(origptr))[0], ((int *)(objptr))[0],
2195 ((int *)(objptr))[BAMBOOMARKBIT],
2196 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2197 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2198 BAMBOO_EXIT(0xb01f);
2201 } // if (pointer==0) else if ... else ...
2202 if(!ISSHAREDOBJ(toptr)) {
2203 tprintf("Error: %x, %x \n", (int)origptr, (int)toptr);
2204 BAMBOO_EXIT(0xb020);
2207 GC_BAMBOO_DEBUGPRINT(0xcdce);
2208 GC_BAMBOO_DEBUGPRINT_REG(origptr);
2209 GC_BAMBOO_DEBUGPRINT_REG(toptr);
2210 GC_BAMBOO_DEBUGPRINT_REG(isize);
2211 gccurr_heaptop -= isize;
2213 to->offset += isize;
2215 #ifdef GC_CACHE_ADAPT
2216 unsigned int tmp_ptr = to->ptr;
2217 #endif // GC_CACHE_ADAPT
2218 if(to->top == to->bound) {
2219 // fill the header of this block and then go to next block
2220 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2221 (*((int*)(to->base))) = to->offset;
2224 #ifdef GC_CACHE_ADAPT
2225 completePageConvert(orig, to, tmp_ptr, true);
2226 #endif // GC_CACHE_ADAPT
2230 // skip the whole obj
2231 int sindex = OBJMAPPINGINDEX((unsigned int)origptr);
2232 int eindex = OBJMAPPINGINDEX((unsigned int)(origptr+size));
2233 for(int tmpi = sindex; tmpi < eindex; tmpi++) {
2234 if((gcmappingtbl[tmpi] != 0) &&
2235 (hostcore(gcbaseva+bamboo_baseobjsize*tmpi)==BAMBOO_NUM_OF_CORE) &&
2236 (hostcore(gcbaseva+bamboo_baseobjsize*(tmpi+1))==BAMBOO_NUM_OF_CORE))
2238 tprintf("Error moveobj **: %x, %x, %x, %d, (%d, %d, %x) \n",
2239 (int)origptr, (int)(origptr+isize),
2240 (int)(gcbaseva+bamboo_baseobjsize*tmpi), gcmappingtbl[tmpi], type,
2241 isize, ((int *)(origptr))[BAMBOOMARKBIT]);
2242 BAMBOO_EXIT(0xb021);
2247 GC_BAMBOO_DEBUGPRINT(0xe205);
2250 orig->ptr += isize; // size;
2253 if(!ISSHAREDOBJ(orig->ptr) || !ISSHAREDOBJ(to->ptr)) {
2254 tprintf("Error moveobj out of boundary: %x, %x, %d, %d \n",
2255 (int)(orig->ptr), (int)(to->ptr), size, isize);
2256 BAMBOO_EXIT(0x2022);
2260 GC_BAMBOO_DEBUGPRINT_REG(isize);
2261 GC_BAMBOO_DEBUGPRINT_REG(size);
2262 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2263 GC_BAMBOO_DEBUGPRINT_REG(orig->bound);
2264 if(((unsigned int)(orig->ptr) > (unsigned int)(orig->bound))
2265 || ((unsigned int)(orig->ptr) == (unsigned int)(orig->blockbound))) {
2266 GC_BAMBOO_DEBUGPRINT(0xe206);
2267 if(!nextSBlock(orig)) {
2268 // finished, no more data
2270 tprintf("DDDD %x \n", (int)(orig->ptr));
2275 GC_BAMBOO_DEBUGPRINT(0xe207);
2276 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2278 } //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
2280 // should be invoked with interrupt closed
2281 inline int assignSpareMem_I(unsigned int sourcecore,
2282 unsigned int * requiredmem,
2283 unsigned int * tomove,
2284 unsigned int * startaddr) {
2286 BLOCKINDEX(gcloads[sourcecore], &b);
2287 unsigned int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
2288 : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
2289 unsigned int remain = boundptr - gcloads[sourcecore];
2290 unsigned int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
2291 *startaddr = gcloads[sourcecore];
2292 *tomove = gcfilledblocks[sourcecore] + 1;
2293 if(memneed < remain) {
2294 gcloads[sourcecore] += memneed;
2297 // next available block
2298 gcfilledblocks[sourcecore] += 1;
2299 unsigned int newbase = 0;
2300 BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
2301 gcloads[sourcecore] = newbase;
2302 return requiredmem-remain;
2304 } // int assignSpareMem_I(int ,int * , int * , int * )
2306 // should be invoked with interrupt closed
2307 inline bool gcfindSpareMem_I(unsigned int * startaddr,
2308 unsigned int * tomove,
2309 unsigned int * dstcore,
2310 unsigned int requiredmem,
2311 unsigned int requiredcore) {
2312 for(int k = 0; k < NUMCORES4GC; k++) {
2313 if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
2314 // check if this stopped core has enough mem
2315 assignSpareMem_I(k, requiredmem, tomove, startaddr);
2320 // if can not find spare mem right now, hold the request
2321 gcrequiredmems[requiredcore] = requiredmem;
2324 } //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
2326 inline bool compacthelper(struct moveHelper * orig,
2327 struct moveHelper * to,
2329 unsigned int * heaptopptr,
2330 bool * localcompact) {
2331 // scan over all objs in this block, compact the marked objs
2332 // loop stop when finishing either scanning all active objs or
2333 // fulfilled the gcstopblock
2334 GC_BAMBOO_DEBUGPRINT(0xe101);
2335 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2336 GC_BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2338 while((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2339 bool stop = moveobj(orig, to, gcblock2fill);
2345 tprintf("finish mark %x \n", (int)gcmarkedptrbound);
2347 #ifdef GC_CACHE_ADAPT
2348 // end of an to page, wrap up its information
2349 samplingDataConvert(to->ptr);
2350 #endif // GC_CACHE_ADAPT
2351 // if no objs have been compact, do nothing,
2352 // otherwise, fill the header of this block
2353 if(to->offset > (unsigned int)BAMBOO_CACHE_LINE_SIZE) {
2354 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2355 (*((int*)(to->base))) = to->offset;
2359 to->top -= BAMBOO_CACHE_LINE_SIZE;
2360 } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
2362 *heaptopptr = to->ptr;
2363 *filledblocks = to->numblocks;
2365 GC_BAMBOO_DEBUGPRINT(0xe102);
2366 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2367 GC_BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2368 GC_BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2369 GC_BAMBOO_DEBUGPRINT_REG(*filledblocks);
2370 GC_BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
2372 // send msgs to core coordinator indicating that the compact is finishing
2373 // send compact finish message to core coordinator
2374 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2375 gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
2376 gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
2377 if((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2378 GC_BAMBOO_DEBUGPRINT(0xe103);
2381 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2382 if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
2383 gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
2384 GC_BAMBOO_DEBUGPRINT(0xe104);
2387 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2388 GC_BAMBOO_DEBUGPRINT(0xe105);
2391 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2393 GC_BAMBOO_DEBUGPRINT(0xe106);
2394 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2399 if((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2400 GC_BAMBOO_DEBUGPRINT(0xe107);
2403 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2404 *filledblocks, *heaptopptr, gccurr_heaptop, false);
2406 GC_BAMBOO_DEBUGPRINT(0xe108);
2407 GC_BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2408 // finish compacting
2409 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2410 *filledblocks, *heaptopptr, 0, false);
2412 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
2414 if(orig->ptr < gcmarkedptrbound) {
2415 GC_BAMBOO_DEBUGPRINT(0xe109);
2416 // still have unpacked obj
2424 GC_BAMBOO_DEBUGPRINT(0xe10a);
2426 to->ptr = gcmovestartaddr;
2427 to->numblocks = gcblock2fill - 1;
2428 to->bound = (to->numblocks==0) ?
2429 BAMBOO_SMEM_SIZE_L :
2430 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2431 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2432 to->offset = to->ptr - to->base;
2433 to->top = (to->numblocks==0) ?
2434 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2436 to->offset = BAMBOO_CACHE_LINE_SIZE;
2437 to->ptr += to->offset; // for header
2438 to->top += to->offset;
2439 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2440 *localcompact = true;
2442 *localcompact = false;
2444 #ifdef GC_CACHE_ADAPT
2445 // initialize the gc_cache_revise_information
2446 gc_cache_revise_infomation.to_page_start_va = to->ptr;
2447 gc_cache_revise_infomation.to_page_end_va = gcbaseva +
2448 (BAMBOO_PAGE_SIZE)*((to->base-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2449 gc_cache_revise_infomation.to_page_index =
2450 (to->base-gcbaseva)/(BAMBOO_PAGE_SIZE);
2451 gc_cache_revise_infomation.orig_page_start_va = orig->ptr;
2452 gc_cache_revise_infomation.orig_page_end_va = gcbaseva +
2453 (BAMBOO_PAGE_SIZE)*((orig->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2454 gc_cache_revise_infomation.orig_page_index =
2455 (orig->blockbase-gcbaseva)/(BAMBOO_PAGE_SIZE);
2456 #endif // GC_CACHE_ADAPT
2459 GC_BAMBOO_DEBUGPRINT(0xe10b);
2461 } // void compacthelper()
2463 inline void compact() {
2464 if(COMPACTPHASE != gcphase) {
2465 BAMBOO_EXIT(0xb023);
2468 // initialize pointers for comapcting
2469 struct moveHelper * orig =
2470 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2471 struct moveHelper * to =
2472 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2473 if(!initOrig_Dst(orig, to)) {
2474 // no available data to compact
2475 // send compact finish msg to STARTUP core
2476 GC_BAMBOO_DEBUGPRINT(0xe001);
2477 GC_BAMBOO_DEBUGPRINT_REG(to->base);
2478 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2479 0, to->base, 0, false);
2484 #ifdef GC_CACHE_ADAPT
2485 gc_cache_revise_infomation.orig_page_start_va = orig->ptr;
2486 gc_cache_revise_infomation.orig_page_end_va = gcbaseva +
2487 (BAMBOO_PAGE_SIZE)*((orig->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2488 gc_cache_revise_infomation.orig_page_index =
2489 (orig->blockbase-gcbaseva)/(BAMBOO_PAGE_SIZE);
2490 #endif // GC_CACHE_ADAPT
2492 unsigned int filledblocks = 0;
2493 unsigned int heaptopptr = 0;
2494 bool localcompact = true;
2495 compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
2500 // if return NULL, means
2501 // 1. objptr is NULL
2502 // 2. objptr is not a shared obj
2503 // in these cases, remain the original value is OK
2505 inline void * flushObj(void * objptr, int linenum, void * ptr, int tt) {
2507 inline void * flushObj(void * objptr) {
2509 GC_BAMBOO_DEBUGPRINT(0xe401);
2510 if(objptr == NULL) {
2513 void * dstptr = NULL;
2514 if(ISSHAREDOBJ(objptr)) {
2515 GC_BAMBOO_DEBUGPRINT(0xe402);
2516 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2517 // a shared obj ptr, change to new address
2518 dstptr = gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)];
2519 GC_BAMBOO_DEBUGPRINT_REG(dstptr);
2521 if(ISSHAREDOBJ(dstptr) && ((unsigned int)(((int*)dstptr)[0]) >= (unsigned int)NUMTYPES)) {
2522 tprintf("Error flushObj ** : %x, %x, %d, %d, %d, %d, %x, %x, %x, %d, %x, %d %d \n",
2523 (int)objptr, (int)dstptr, ((int*)dstptr)[0], hostcore(objptr),
2524 hostcore(objptr)==BAMBOO_NUM_OF_CORE,
2525 OBJMAPPINGINDEX((unsigned int)objptr), (int)gcmappingtbl,
2526 &(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]),
2527 (int)gcbaseva, linenum, (int)ptr, ((int*)ptr)[0], tt);
2528 BAMBOO_EXIT(0xb024);
2532 if(!ISSHAREDOBJ(dstptr)) {
2534 tprintf("Error flushObj ++ : %x, %x, %d, %d, %d, %x, %x, %x, %d, %x, %d %d \n",
2535 (int)objptr, (int)dstptr, hostcore(objptr),
2536 hostcore(objptr)==BAMBOO_NUM_OF_CORE,
2537 OBJMAPPINGINDEX((unsigned int)objptr), (int)gcmappingtbl,
2538 &(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]),
2539 (int)gcbaseva, linenum, (int)ptr, ((int*)ptr)[0], tt);
2540 tprintf("gcmappingtbl: \n");
2541 int tmp = OBJMAPPINGINDEX((unsigned int)objptr) - 50;
2542 for(int jj = 0; jj < 100; jj+=10) {
2543 tprintf("%8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %d \n",
2544 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2545 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2546 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2547 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2548 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++], tmp);
2550 BAMBOO_EXIT(0xb025);
2553 GC_BAMBOO_DEBUGPRINT(0xe403);
2554 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2555 GC_BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
2556 // error! the obj is right on this core, but cannot find it
2557 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2558 tprintf("Error flushObj ++ : %x, %x, %d, %d, %x, %x, %x, %x\n",
2559 (int)objptr, (int)dstptr, hostcore(objptr),
2560 hostcore(objptr)==BAMBOO_NUM_OF_CORE,
2561 OBJMAPPINGINDEX((unsigned int)objptr), (int)gcmappingtbl,
2562 &(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]),
2564 BAMBOO_EXIT(0xb026);
2566 } // if(NULL == dstptr)
2567 } // if(ISSHAREDOBJ(objptr))
2570 tprintf("Error flushObj: %x \n", (int)objptr);
2571 BAMBOO_EXIT(0xb027);
2574 // if not a shared obj, return NULL to indicate no need to flush
2575 GC_BAMBOO_DEBUGPRINT(0xe404);
2577 } // void flushObj(void * objptr)
2579 inline void flushRuntimeObj(struct garbagelist * stackptr) {
2581 // flush current stack
2582 while(stackptr!=NULL) {
2583 for(i=0; i<stackptr->size; i++) {
2584 if(stackptr->array[i] != NULL) {
2586 void * dst = flushObj(stackptr->array[i],
2587 __LINE__, stackptr->array[i], i);
2589 void * dst = flushObj(stackptr->array[i]);
2592 stackptr->array[i] = dst;
2596 stackptr=stackptr->next;
2599 // flush static pointers global_defs_p
2600 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2601 struct garbagelist * staticptr=(struct garbagelist *)global_defs_p;
2602 for(i=0; i<staticptr->size; i++) {
2603 if(staticptr->array[i] != NULL) {
2605 void * dst = flushObj(staticptr->array[i],
2606 __LINE__, staticptr->array[i], i);
2608 void * dst = flushObj(staticptr->array[i]);
2611 staticptr->array[i] = dst;
2619 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
2620 for(i=0; i<NUMCLASSES; i++) {
2621 struct parameterwrapper ** queues =
2622 objectqueues[BAMBOO_NUM_OF_CORE][i];
2623 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
2624 for(j = 0; j < length; ++j) {
2625 struct parameterwrapper * parameter = queues[j];
2626 struct ObjectHash * set=parameter->objectset;
2627 struct ObjectNode * ptr=set->listhead;
2630 void * dst = flushObj((void *)ptr->key,
2631 __LINE__, (void *)ptr->key, 0);
2633 void * dst = flushObj((void *)ptr->key);
2640 ObjectHashrehash(set);
2645 // flush current task descriptor
2646 if(currtpd != NULL) {
2647 for(i=0; i<currtpd->numParameters; i++) {
2649 void * dst = flushObj(currtpd->parameterArray[i],
2650 __LINE__, currtpd->parameterArray[i], i);
2652 void * dst = flushObj(currtpd->parameterArray[i]);
2655 currtpd->parameterArray[i] = dst;
2660 // flush active tasks
2661 if(activetasks != NULL) {
2662 struct genpointerlist * ptr=activetasks->list;
2664 struct taskparamdescriptor *tpd=ptr->src;
2666 for(i=0; i<tpd->numParameters; i++) {
2668 void * dst = flushObj(tpd->parameterArray[i],
2669 __LINE__, tpd->parameterArray[i], i);
2671 void * dst = flushObj(tpd->parameterArray[i]);
2674 tpd->parameterArray[i] = dst;
2679 genrehash(activetasks);
2682 // flush cached transferred obj
2683 struct QueueItem * tmpobjptr = getHead(&objqueue);
2684 while(tmpobjptr != NULL) {
2685 struct transObjInfo * objInfo =
2686 (struct transObjInfo *)(tmpobjptr->objectptr);
2688 void * dst = flushObj(objInfo->objptr, __LINE__,
2689 objInfo->objptr, 0);
2691 void * dst = flushObj(objInfo->objptr);
2694 objInfo->objptr = dst;
2696 tmpobjptr = getNextQueueItem(tmpobjptr);
2699 // flush cached objs to be transferred
2700 struct QueueItem * item = getHead(totransobjqueue);
2701 while(item != NULL) {
2702 struct transObjInfo * totransobj =
2703 (struct transObjInfo *)(item->objectptr);
2705 void * dst = flushObj(totransobj->objptr, __LINE__,
2706 totransobj->objptr, 0);
2708 void * dst = flushObj(totransobj->objptr);
2711 totransobj->objptr = dst;
2713 item = getNextQueueItem(item);
2714 } // while(item != NULL)
2716 // enqueue lock related info
2717 for(i = 0; i < runtime_locklen; ++i) {
2719 void * dst = flushObj(runtime_locks[i].redirectlock,
2720 __LINE__, runtime_locks[i], i);
2722 void * dst = flushObj(runtime_locks[i].redirectlock);
2725 runtime_locks[i].redirectlock = (int)dst;
2727 if(runtime_locks[i].value != NULL) {
2729 void * dst=flushObj(runtime_locks[i].value,
2730 __LINE__, runtime_locks[i].value, i);
2732 void * dst=flushObj(runtime_locks[i].value);
2735 runtime_locks[i].value = (int)dst;
2742 // flush the bamboo_threadlocks
2743 if(bamboo_threadlocks != 0) {
2745 bamboo_threadlocks =
2746 (unsigned int)(flushObj((void *)bamboo_threadlocks,
2747 __LINE__, (void *)bamboo_threadlocks, 0));
2749 bamboo_threadlocks = (unsigned int)(flushObj((void *)bamboo_threadlocks));
2753 // flush the bamboo_current_thread
2754 if(bamboo_current_thread != 0) {
2756 bamboo_current_thread =
2757 (unsigned int)(flushObj((void *)bamboo_current_thread,
2758 __LINE__, (void *)bamboo_current_thread, 0));
2760 bamboo_current_thread =
2761 (unsigned int)(flushObj((void *)bamboo_current_thread));
2765 // flush global thread queue
2766 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2767 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
2768 if(thread_counter > 0) {
2769 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
2770 for(i = thread_counter; i > 0; i--) {
2772 bamboo_thread_queue[4+start] =
2773 (INTPTR)(flushObj((void *)bamboo_thread_queue[4+start
2774 ], __LINE__, (void *)bamboo_thread_queue, 0));
2776 bamboo_thread_queue[4+start] =
2777 (INTPTR)(flushObj((void *)bamboo_thread_queue[4+start]));
2779 start = (start+1)&bamboo_max_thread_num_mask;
2782 unlockthreadqueue();
2785 } // void flushRuntimeObj(struct garbagelist * stackptr)
2787 inline void flush(struct garbagelist * stackptr) {
2789 flushRuntimeObj(stackptr);
2792 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2793 bool hasItems = gc_moreItems_I();
2794 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2799 GC_BAMBOO_DEBUGPRINT(0xe301);
2800 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2801 void * ptr = gc_dequeue_I();
2803 unsigned int bkptr = (unsigned int)ptr;
2805 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2806 if(ISSHAREDOBJ(ptr)) {
2807 // should be a local shared obj and should have mapping info
2809 ptr = flushObj(ptr, __LINE__, ptr, 0);
2811 ptr = flushObj(ptr);
2813 GC_BAMBOO_DEBUGPRINT(0xe302);
2814 GC_BAMBOO_DEBUGPRINT_REG(ptr);
2816 BAMBOO_EXIT(0xb028);
2818 } // if(ISSHAREDOBJ(ptr))
2819 if((!ISSHAREDOBJ(ptr))||(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED)) {
2820 int type = ((int *)(ptr))[0];
2822 if((unsigned int)type >= (unsigned int)NUMTYPES) {
2823 tprintf("Error flushObj %x, %x, %d, %d \n", bkptr, (int)ptr, type,
2824 ((int *)(ptr))[BAMBOOMARKBIT]);
2825 BAMBOO_EXIT(0xb029);
2828 // scan all pointers in ptr
2829 unsigned int * pointer;
2830 pointer=pointerarray[type];
2831 GC_BAMBOO_DEBUGPRINT(0xe303);
2832 GC_BAMBOO_DEBUGPRINT_REG(pointer);
2834 /* Array of primitives */
2836 } else if (((unsigned int)pointer)==1) {
2837 GC_BAMBOO_DEBUGPRINT(0xe304);
2838 /* Array of pointers */
2839 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2840 int length=ao->___length___;
2842 for(j=0; j<length; j++) {
2843 GC_BAMBOO_DEBUGPRINT(0xe305);
2845 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2846 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2847 if(objptr != NULL) {
2849 void * dst = flushObj(objptr, __LINE__, ptr, j);
2851 void * dst = flushObj(objptr);
2854 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2858 /* check the ArrayObject struct first*/
2860 pointer=pointerarray[OBJECTTYPE];
2861 //handle object class
2862 unsigned int size=pointer[0];
2864 for(i=1; i<=size; i++) {
2865 unsigned int offset=pointer[i];
2866 void * objptr=*((void **)(((char *)ao)+offset));
2867 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2868 if(objptr != NULL) {
2870 void * dst = flushObj(objptr, __LINE__, ptr, j);
2872 void * dst = flushObj(objptr);
2875 *((void **)(((char *)ao)+offset)) = dst;
2881 GC_BAMBOO_DEBUGPRINT(0xe306);
2882 unsigned int size=pointer[0];
2884 for(i=1; i<=size; i++) {
2885 GC_BAMBOO_DEBUGPRINT(0xe307);
2886 unsigned int offset=pointer[i];
2887 void * objptr=*((void **)(((char *)ptr)+offset));
2888 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2889 if(objptr != NULL) {
2891 void * dst = flushObj(objptr, __LINE__, ptr, i);
2893 void * dst = flushObj(objptr);
2896 *((void **)(((char *)ptr)+offset)) = dst;
2899 } // for(i=1; i<=size; i++)
2900 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2901 // restore the mark field, indicating that this obj has been flushed
2902 if(ISSHAREDOBJ(ptr)) {
2903 ((int *)(ptr))[BAMBOOMARKBIT] = INIT;
2905 } //if((!ISSHAREDOBJ(ptr))||(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED))
2906 } // while(gc_moreItems())
2907 GC_BAMBOO_DEBUGPRINT(0xe308);
2909 // TODO bug here: the startup core contains all lobjs' info, thus all the
2910 // lobjs are flushed in sequence.
2912 while(gc_lobjmoreItems_I()) {
2913 GC_BAMBOO_DEBUGPRINT(0xe309);
2914 void * ptr = gc_lobjdequeue_I(NULL, NULL);
2916 ptr = flushObj(ptr, __LINE__, ptr, 0);
2918 ptr = flushObj(ptr);
2920 GC_BAMBOO_DEBUGPRINT(0xe30a);
2921 GC_BAMBOO_DEBUGPRINT_REG(ptr);
2922 GC_BAMBOO_DEBUGPRINT_REG(tptr);
2923 GC_BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2925 BAMBOO_EXIT(0xb02a);
2927 if(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED) {
2928 int type = ((int *)(ptr))[0];
2929 // scan all pointers in ptr
2930 unsigned int * pointer;
2931 pointer=pointerarray[type];
2932 GC_BAMBOO_DEBUGPRINT(0xe30b);
2933 GC_BAMBOO_DEBUGPRINT_REG(pointer);
2935 /* Array of primitives */
2937 } else if (((unsigned int)pointer)==1) {
2938 GC_BAMBOO_DEBUGPRINT(0xe30c);
2939 /* Array of pointers */
2940 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2941 int length=ao->___length___;
2943 for(j=0; j<length; j++) {
2944 GC_BAMBOO_DEBUGPRINT(0xe30d);
2946 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2947 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2948 if(objptr != NULL) {
2950 void * dst = flushObj(objptr, __LINE__, ptr, j);
2952 void * dst = flushObj(objptr);
2955 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2959 /* check the ArrayObject struct first*/
2961 pointer=pointerarray[OBJECTTYPE];
2962 //handle object class
2963 unsigned int size=pointer[0];
2965 for(i=1; i<=size; i++) {
2966 unsigned int offset=pointer[i];
2967 void * objptr=*((void **)(((char *)ao)+offset));
2968 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2969 if(objptr != NULL) {
2971 void * dst = flushObj(objptr, __LINE__, ptr, j);
2973 void * dst = flushObj(objptr);
2976 *((void **)(((char *)ao)+offset)) = dst;
2982 GC_BAMBOO_DEBUGPRINT(0xe30e);
2983 unsigned int size=pointer[0];
2985 for(i=1; i<=size; i++) {
2986 GC_BAMBOO_DEBUGPRINT(0xe30f);
2987 unsigned int offset=pointer[i];
2988 void * objptr=*((void **)(((char *)ptr)+offset));
2990 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2991 if(objptr != NULL) {
2993 void * dst = flushObj(objptr, __LINE__, ptr, i);
2995 void * dst = flushObj(objptr);
2998 *((void **)(((char *)ptr)+offset)) = dst;
3001 } // for(i=1; i<=size; i++)
3002 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
3003 // restore the mark field, indicating that this obj has been flushed
3004 ((int *)(ptr))[BAMBOOMARKBIT] = INIT;
3005 } // if(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED)
3006 } // while(gc_lobjmoreItems())
3007 GC_BAMBOO_DEBUGPRINT(0xe310);
3009 // send flush finish message to core coordinator
3010 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
3011 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3013 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
3015 GC_BAMBOO_DEBUGPRINT(0xe311);
3018 #ifdef GC_CACHE_ADAPT
3019 // prepare for cache adaption:
3020 // -- flush the shared heap
3021 // -- clean dtlb entries
3022 // -- change cache strategy
3023 void cacheAdapt_gc(bool isgccachestage) {
3024 // flush the shared heap
3025 BAMBOO_CACHE_FLUSH_L2();
3027 // clean the dtlb entries
3028 BAMBOO_CLEAN_DTLB();
3030 // change the cache strategy
3031 gccachestage = isgccachestage;
3032 } // cacheAdapt_gc(bool isgccachestage)
3034 // the master core decides how to adapt cache strategy for the mutator
3035 // according to collected statistic data
3037 // make all pages hfh
3038 int cacheAdapt_policy_h4h(){
3039 unsigned int page_index = 0;
3041 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3043 int * tmp_p = gccachepolicytbl+1;
3044 for(page_index = 0; page_index < page_num; page_index++) {
3045 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3046 bamboo_cache_policy_t policy = {0};
3047 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3048 *tmp_p = page_index;
3050 *tmp_p = policy.word;
3056 } // int cacheAdapt_policy_hfh()
3058 // make all pages local as non-cache-adaptable gc local mode
3059 int cacheAdapt_policy_local(){
3060 unsigned int page_index = 0;
3062 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3064 int * tmp_p = gccachepolicytbl+1;
3065 for(page_index = 0; page_index < page_num; page_index++) {
3066 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3067 bamboo_cache_policy_t policy = {0};
3068 unsigned int block = 0;
3069 BLOCKINDEX(page_sva, &block);
3070 unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
3071 // locally cache the page in the hotest core
3072 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3073 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3074 policy.lotar_x = bamboo_cpu2coords[2*coren]+1;
3075 policy.lotar_y = bamboo_cpu2coords[2*coren+1]+1;
3076 *tmp_p = page_index;
3078 *tmp_p = policy.word;
3084 } // int cacheAdapt_policy_local()
3086 int cacheAdapt_policy_hotest(){
3087 unsigned int page_index = 0;
3089 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3091 int * tmp_p = gccachepolicytbl+1;
3092 for(page_index = 0; page_index < page_num; page_index++) {
3093 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3094 bamboo_cache_policy_t policy = {0};
3095 unsigned int hotestcore = 0;
3096 unsigned int hotfreq = 0;
3098 unsigned int *local_tbl=&gccachesamplingtbl_r[page_index];
3099 for(int i = 0; i < NUMCORESACTIVE; i++) {
3100 unsigned int freq = *local_tbl;
3101 local_tbl=(unsigned int *)(
3102 ((char *)local_tbl)+size_cachesamplingtbl_local_r);
3104 // check the freqency, decide if this page is hot for the core
3105 if(hotfreq < freq) {
3111 // Decide the cache strategy for this page
3112 // If decide to adapt a new cache strategy, write into the shared block of
3113 // the gcsharedsamplingtbl. The mem recording information that has been
3114 // written is enough to hold the information.
3115 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3117 // this page has not been accessed, do not change its cache policy
3120 // locally cache the page in the hotest core
3121 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3122 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3123 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3124 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3125 *tmp_p = page_index;
3127 *tmp_p = policy.word;
3134 } // int cacheAdapt_policy_hotest()
3136 #define GC_CACHE_ADAPT_DOMINATE_THRESHOLD 50
3137 // cache the page on the core that accesses it the most if that core accesses
3138 // it more than (GC_CACHE_ADAPT_DOMINATE_THRESHOLD)% of the total. Otherwise,
3140 int cacheAdapt_policy_dominate(){
3141 unsigned int page_index = 0;
3143 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3145 int * tmp_p = gccachepolicytbl+1;
3146 for(page_index = 0; page_index < page_num; page_index++) {
3147 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3148 bamboo_cache_policy_t policy = {0};
3149 unsigned int hotestcore = 0;
3150 unsigned long long totalfreq = 0;
3151 unsigned int hotfreq = 0;
3153 unsigned int *local_tbl=&gccachesamplingtbl_r[page_index];
3154 for(int i = 0; i < NUMCORESACTIVE; i++) {
3155 unsigned int freq = *local_tbl;
3156 local_tbl=(unsigned int *)(
3157 ((char *)local_tbl)+size_cachesamplingtbl_local_r);
3159 // check the freqency, decide if this page is hot for the core
3160 if(hotfreq < freq) {
3166 // Decide the cache strategy for this page
3167 // If decide to adapt a new cache strategy, write into the shared block of
3169 // Format: page start va + cache policy
3171 // this page has not been accessed, do not change its cache policy
3175 (totalfreq*GC_CACHE_ADAPT_DOMINATE_THRESHOLD)/100/BAMBOO_PAGE_SIZE;
3176 hotfreq/=BAMBOO_PAGE_SIZE;
3177 if(hotfreq < totalfreq) {
3179 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3181 // locally cache the page in the hotest core
3182 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3183 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3184 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3185 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3187 *tmp_p = page_index;
3189 *tmp_p = policy.word;
3195 } // int cacheAdapt_policy_dominate()
3197 #define GC_CACHE_ADAPT_OVERLOAD_THRESHOLD 10
3199 void gc_quicksort(unsigned long long *array,
3205 int rightIdx = right;
3206 if((right-left+1) >= 1) {
3207 pivot = (left+right)/2;
3208 while((leftIdx <= pivot) && (rightIdx >= pivot)) {
3209 int pivotValue = array[pivot*3-offset];
3210 while((array[leftIdx*3-offset] > pivotValue) && (leftIdx <= pivot)) {
3213 while((array[rightIdx*3-offset] < pivotValue) && (rightIdx >= pivot)) {
3216 // swap [leftIdx] & [rightIdx]
3217 for(int k = 0; k < 3; k++) {
3218 unsigned long long tmp = array[3*rightIdx-k];
3219 array[3*rightIdx-k] = array[3*leftIdx-k];
3220 array[3*leftIdx-k] = tmp;
3224 if((leftIdx-1) == pivot) {
3225 pivot = rightIdx = rightIdx + 1;
3226 } else if((leftIdx+1) == pivot) {
3227 pivot = leftIdx = leftIdx-1;
3230 gc_quicksort(array, left, pivot-1, offset);
3231 gc_quicksort(array, pivot+1, right, offset);
3234 } // void gc_quicksort(...)
3236 // Every page cached on the core that accesses it the most.
3237 // Check to see if any core's pages total more accesses than threshold
3238 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD. If so, find the pages with the
3239 // most remote accesses and hash for home them until we get below
3240 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD
3241 int cacheAdapt_policy_overload(){
3242 unsigned int page_index = 0;
3244 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3246 int * tmp_p = gccachepolicytbl+1;
3247 unsigned long long workload[NUMCORESACTIVE];
3248 memset(workload, 0, NUMCORESACTIVE*sizeof(unsigned long long));
3249 unsigned long long total_workload = 0;
3250 unsigned long long core2heavypages[NUMCORESACTIVE][page_num*3+1];
3251 memset(core2heavypages,0,
3252 sizeof(unsigned long long)*(page_num*3+1)*NUMCORESACTIVE);
3253 for(page_index = 0; page_index < page_num; page_index++) {
3254 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3255 bamboo_cache_policy_t policy = {0};
3256 unsigned int hotestcore = 0;
3257 unsigned long long totalfreq = 0;
3258 unsigned int hotfreq = 0;
3260 unsigned int *local_tbl=&gccachesamplingtbl_r[page_index];
3261 for(int i = 0; i < NUMCORESACTIVE; i++) {
3262 unsigned int freq = *local_tbl;
3263 local_tbl=(unsigned int *)(
3264 ((char *)local_tbl)+size_cachesamplingtbl_local_r);
3266 // check the freqency, decide if this page is hot for the core
3267 if(hotfreq < freq) {
3272 // Decide the cache strategy for this page
3273 // If decide to adapt a new cache strategy, write into the shared block of
3274 // the gcsharedsamplingtbl. The mem recording information that has been
3275 // written is enough to hold the information.
3276 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3278 // this page has not been accessed, do not change its cache policy
3282 totalfreq/=BAMBOO_PAGE_SIZE;
3283 hotfreq/=BAMBOO_PAGE_SIZE;
3284 // locally cache the page in the hotest core
3285 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3286 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3287 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3288 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3289 *tmp_p = page_index;
3291 *tmp_p = policy.word;
3294 workload[hotestcore] += totalfreq;
3295 total_workload += totalfreq;
3296 // insert into core2heavypages using quicksort
3297 unsigned long long remoteaccess = totalfreq - hotfreq;
3298 int index = (int)core2heavypages[hotestcore][0];
3299 core2heavypages[hotestcore][3*index+3] = remoteaccess;
3300 core2heavypages[hotestcore][3*index+2] = totalfreq;
3301 core2heavypages[hotestcore][3*index+1] = (unsigned long long)(tmp_p-1);
3302 core2heavypages[hotestcore][0]++;
3305 unsigned long long workload_threshold =
3306 total_workload/GC_CACHE_ADAPT_OVERLOAD_THRESHOLD;
3307 // Check the workload of each core
3308 for(int i = 0; i < NUMCORESACTIVE; i++) {
3310 int index = (int)core2heavypages[i][0];
3311 if(workload[i] > workload_threshold) {
3312 // sort according to the remoteaccess
3313 gc_quicksort(&core2heavypages[i][0], 1, index, 0);
3314 while((workload[i] > workload_threshold) && (j<index*3)) {
3315 // hfh those pages with more remote accesses
3316 bamboo_cache_policy_t policy = {0};
3317 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3318 *((int*)core2heavypages[i][j]) = policy.word;
3319 workload[i] -= core2heavypages[i][j+1];
3326 } // int cacheAdapt_policy_overload()
3328 #define GC_CACHE_ADAPT_ACCESS_THRESHOLD 70
3329 #define GC_CACHE_ADAPT_CROWD_THRESHOLD 20
3330 // Every page cached on the core that accesses it the most.
3331 // Check to see if any core's pages total more accesses than threshold
3332 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD. If so, find the pages with the
3333 // most remote accesses and hash for home them until we get below
3334 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD.
3335 // Sort pages based on activity....
3336 // If more then GC_CACHE_ADAPT_ACCESS_THRESHOLD% of the accesses for a
3337 // core's pages are from more than GC_CACHE_ADAPT_CROWD_THRESHOLD pages,
3338 // then start hfh these pages(selecting the ones with the most remote
3339 // accesses first or fewest local accesses) until we get below
3340 // GC_CACHE_ADAPT_CROWD_THRESHOLD pages.
3341 int cacheAdapt_policy_crowd(){
3342 unsigned int page_index = 0;
3344 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3346 int * tmp_p = gccachepolicytbl+1;
3347 unsigned long long workload[NUMCORESACTIVE];
3348 memset(workload, 0, NUMCORESACTIVE*sizeof(unsigned long long));
3349 unsigned long long total_workload = 0;
3350 unsigned long long core2heavypages[NUMCORESACTIVE][page_num*3+1];
3351 memset(core2heavypages,0,
3352 sizeof(unsigned long long)*(page_num*3+1)*NUMCORESACTIVE);
3353 for(page_index = 0; page_index < page_num; page_index++) {
3354 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3355 bamboo_cache_policy_t policy = {0};
3356 unsigned int hotestcore = 0;
3357 unsigned long long totalfreq = 0;
3358 unsigned int hotfreq = 0;
3360 unsigned int *local_tbl=&gccachesamplingtbl_r[page_index];
3361 for(int i = 0; i < NUMCORESACTIVE; i++) {
3362 unsigned int freq = *local_tbl;
3363 local_tbl=(unsigned int *)(
3364 ((char *)local_tbl)+size_cachesamplingtbl_local_r);
3366 // check the freqency, decide if this page is hot for the core
3367 if(hotfreq < freq) {
3372 // Decide the cache strategy for this page
3373 // If decide to adapt a new cache strategy, write into the shared block of
3374 // the gcsharedsamplingtbl. The mem recording information that has been
3375 // written is enough to hold the information.
3376 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3378 // this page has not been accessed, do not change its cache policy
3381 totalfreq/=BAMBOO_PAGE_SIZE;
3382 hotfreq/=BAMBOO_PAGE_SIZE;
3383 // locally cache the page in the hotest core
3384 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3385 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3386 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3387 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3388 *tmp_p = page_index;
3390 *tmp_p = policy.word;
3393 workload[hotestcore] += totalfreq;
3394 total_workload += totalfreq;
3395 // insert into core2heavypages using quicksort
3396 unsigned long long remoteaccess = totalfreq - hotfreq;
3397 int index = (int)core2heavypages[hotestcore][0];
3398 core2heavypages[hotestcore][3*index+3] = remoteaccess;
3399 core2heavypages[hotestcore][3*index+2] = totalfreq;
3400 core2heavypages[hotestcore][3*index+1] = (unsigned long long)(tmp_p-1);
3401 core2heavypages[hotestcore][0]++;
3404 unsigned long long workload_threshold =
3405 total_workload / GC_CACHE_ADAPT_OVERLOAD_THRESHOLD;
3406 // Check the workload of each core
3407 for(int i = 0; i < NUMCORESACTIVE; i++) {
3409 int index = (int)core2heavypages[i][0];
3410 if(workload[i] > workload_threshold) {
3411 // sort according to the remoteaccess
3412 gc_quicksort(&core2heavypages[i][0], 1, index, 0);
3413 while((workload[i] > workload_threshold) && (j<index*3)) {
3414 // hfh those pages with more remote accesses
3415 bamboo_cache_policy_t policy = {0};
3416 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3417 *((int*)core2heavypages[i][j]) = policy.word;
3418 workload[i] -= core2heavypages[i][j+1];
3423 // Check if the accesses are crowded on few pages
3424 // sort according to the total access
3426 gc_quicksort(&core2heavypages[i][0], j/3+1, index, 1);
3427 unsigned long long threshold =
3428 GC_CACHE_ADAPT_ACCESS_THRESHOLD*workload[i]/100;
3429 int num_crowded = 0;
3430 unsigned long long t_workload = 0;
3432 t_workload += core2heavypages[i][j+num_crowded*3+1];
3434 } while(t_workload < threshold);
3435 // num_crowded <= GC_CACHE_ADAPT_CROWD_THRESHOLD and if there are enough
3436 // items, it is always == GC_CACHE_ADAPT_CROWD_THRESHOLD
3437 if(num_crowded > GC_CACHE_ADAPT_CROWD_THRESHOLD) {
3438 // need to hfh these pages
3439 // sort the pages according to remote access
3440 gc_quicksort(&core2heavypages[i][0], j/3+1, j/3+num_crowded, 0);
3441 // h4h those pages with more remote accesses
3442 bamboo_cache_policy_t policy = {0};
3443 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3444 *((int*)core2heavypages[i][j]) = policy.word;
3445 workload[i] -= core2heavypages[i][j+1];
3446 t_workload -= core2heavypages[i][j+1];
3448 threshold = GC_CACHE_ADAPT_ACCESS_THRESHOLD*workload[i]/100;
3454 } // int cacheAdapt_policy_overload()
3456 void cacheAdapt_master() {
3457 #ifdef GC_CACHE_ADAPT_SAMPLING_OUTPUT
3458 gc_output_cache_sampling_r();
3459 #endif // GC_CACHE_ADAPT_SAMPLING_OUTPUT
3461 // check the statistic data
3462 // for each page, decide the new cache strategy
3463 #ifdef GC_CACHE_ADAPT_POLICY1
3464 numchanged = cacheAdapt_policy_h4h();
3465 #elif defined GC_CACHE_ADAPT_POLICY2
3466 numchanged = cacheAdapt_policy_local();
3467 #elif defined GC_CACHE_ADAPT_POLICY3
3468 numchanged = cacheAdapt_policy_hotest();
3469 #elif defined GC_CACHE_ADAPT_POLICY4
3470 numchanged = cacheAdapt_policy_dominate();
3471 #elif defined GC_CACHE_ADAPT_POLICY5
3472 numchanged = cacheAdapt_policy_overload();
3473 #elif defined GC_CACHE_ADAPT_POLICY6
3474 numchanged = cacheAdapt_policy_crowd();
3476 *gccachepolicytbl = numchanged;
3479 // adapt the cache strategy for the mutator
3480 void cacheAdapt_mutator() {
3481 int numchanged = *gccachepolicytbl;
3482 // check the changes and adapt them
3483 int * tmp_p = gccachepolicytbl+1;
3484 while(numchanged--) {
3485 // read out the policy
3486 int page_index = *tmp_p;
3487 bamboo_cache_policy_t policy = (bamboo_cache_policy_t)(*(tmp_p+1));
3489 bamboo_adapt_cache_policy(page_index*(BAMBOO_PAGE_SIZE)+gcbaseva,
3490 policy, BAMBOO_PAGE_SIZE);
3496 void gc_output_cache_sampling() {
3497 unsigned int page_index = 0;
3499 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3500 for(page_index = 0; page_index < page_num; page_index++) {
3501 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3502 unsigned int block = 0;
3503 BLOCKINDEX(page_sva, &block);
3504 int coren = gc_block2core[block%(NUMCORES4GC*2)];
3505 tprintf("va: %x page_index: %d host: %d\n",
3506 (int)page_sva, page_index, coren);
3507 for(int i = 0; i < NUMCORESACTIVE; i++) {
3508 unsigned int * local_tbl = (unsigned int *)((void *)gccachesamplingtbl
3509 +size_cachesamplingtbl_local*i);
3510 unsigned int freq = local_tbl[page_index];
3511 printf("%8d ",freq);
3515 printf("=================\n");
3516 } // gc_output_cache_sampling
3518 void gc_output_cache_sampling_r() {
3519 unsigned int page_index = 0;
3521 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3522 for(page_index = 0; page_index < page_num; page_index++) {
3523 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3524 unsigned int block = 0;
3525 BLOCKINDEX(page_sva, &block);
3526 int coren = gc_block2core[block%(NUMCORES4GC*2)];
3527 tprintf("va: %x page_index: %d host: %d\n",
3528 (int)page_sva, page_index, coren);
3529 for(int i = 0; i < NUMCORESACTIVE; i++) {
3530 unsigned int * local_tbl = (unsigned int *)((void *)gccachesamplingtbl_r
3531 +size_cachesamplingtbl_local_r*i);
3532 unsigned int freq = local_tbl[page_index]/BAMBOO_PAGE_SIZE;
3533 printf("%8d ",freq);
3537 printf("=================\n");
3538 } // gc_output_cache_sampling
3539 #endif // GC_CACHE_ADAPT
3541 inline void gc_collect(struct garbagelist * stackptr) {
3542 // inform the master that this core is at a gc safe point and is ready to
3544 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
3545 self_numreceiveobjs, false);
3547 // core collector routine
3549 if(INITPHASE == gcphase) {
3553 #ifdef RAWPATH // TODO GC_DEBUG
3554 printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
3557 #ifdef GC_CACHE_ADAPT
3558 // prepare for cache adaption:
3559 cacheAdapt_gc(true);
3560 #endif // GC_CACHE_ADAPT
3561 //send init finish msg to core coordinator
3562 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
3565 if(MARKPHASE == gcphase) {
3569 #ifdef RAWPATH // TODO GC_DEBUG
3570 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
3571 udn_tile_coord_y());
3573 mark(true, stackptr);
3574 #ifdef RAWPATH // TODO GC_DEBUG
3575 printf("(%x,%x) Finish mark phase, start compact phase\n",
3576 udn_tile_coord_x(), udn_tile_coord_y());
3579 #ifdef RAWPATH // TODO GC_DEBUG
3580 printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
3581 udn_tile_coord_y());
3585 if(FLUSHPHASE == gcphase) {
3589 #ifdef RAWPATH // TODO GC_DEBUG
3590 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
3591 udn_tile_coord_y());
3594 // send the num of obj/liveobj/forwardobj to the startupcore
3595 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
3596 send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
3597 gc_num_liveobj, gc_num_forwardobj, false);
3600 #endif // GC_PROFLIE
3602 #ifdef RAWPATH // TODO GC_DEBUG
3603 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
3604 udn_tile_coord_y());
3607 #ifdef GC_CACHE_ADAPT
3609 if(PREFINISHPHASE == gcphase) {
3613 #ifdef RAWPATH // TODO GC_DEBUG
3614 printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
3615 udn_tile_coord_y());
3617 // cache adapt phase
3618 cacheAdapt_mutator();
3619 cacheAdapt_gc(false);
3620 //send init finish msg to core coordinator
3621 send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
3622 #ifdef RAWPATH // TODO GC_DEBUG
3623 printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
3624 udn_tile_coord_y());
3626 #ifdef GC_CACHE_SAMPLING
3627 // reset the sampling arrays
3628 bamboo_dtlb_sampling_reset();
3629 #endif // GC_CACHE_SAMPLING
3630 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
3631 // zero out the gccachesamplingtbl
3632 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
3633 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
3634 size_cachesamplingtbl_local_r);
3636 #endif // GC_CACHE_ADAPT
3638 // invalidate all shared mem pointers
3639 bamboo_cur_msp = NULL;
3640 bamboo_smem_size = 0;
3641 bamboo_smem_zero_top = NULL;
3644 if(FINISHPHASE == gcphase) {
3650 //gcprocessing = false;
3651 #ifdef RAWPATH // TODO GC_DEBUG
3652 printf("(%x,%x) Finish gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
3654 } // void gc_collect(struct garbagelist * stackptr)
3656 inline void gc_nocollect(struct garbagelist * stackptr) {
3657 // inform the master that this core is at a gc safe point and is ready to
3659 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
3660 self_numreceiveobjs, false);
3663 if(INITPHASE == gcphase) {
3667 #ifdef RAWPATH // TODO GC_DEBUG
3668 printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
3671 #ifdef GC_CACHE_ADAPT
3672 // prepare for cache adaption:
3673 cacheAdapt_gc(true);
3674 #endif // GC_CACHE_ADAPT
3675 //send init finish msg to core coordinator
3676 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
3679 if(MARKPHASE == gcphase) {
3683 #ifdef RAWPATH // TODO GC_DEBUG
3684 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
3685 udn_tile_coord_y());
3687 mark(true, stackptr);
3688 #ifdef RAWPATH // TODO GC_DEBUG
3689 printf("(%x,%x) Finish mark phase, wait for flush\n",
3690 udn_tile_coord_x(), udn_tile_coord_y());
3693 // non-gc core collector routine
3695 if(FLUSHPHASE == gcphase) {
3699 #ifdef RAWPATH // TODO GC_DEBUG
3700 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
3701 udn_tile_coord_y());
3704 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
3705 send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
3706 gc_num_liveobj, gc_num_forwardobj, false);
3709 #endif // GC_PROFLIE
3711 #ifdef RAWPATH // TODO GC_DEBUG
3712 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
3713 udn_tile_coord_y());
3716 #ifdef GC_CACHE_ADAPT
3718 if(PREFINISHPHASE == gcphase) {
3722 #ifdef RAWPATH // TODO GC_DEBUG
3723 printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
3724 udn_tile_coord_y());
3726 // cache adapt phase
3727 cacheAdapt_mutator();
3728 cacheAdapt_gc(false);
3729 //send init finish msg to core coordinator
3730 send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
3731 #ifdef RAWPATH // TODO GC_DEBUG
3732 printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
3733 udn_tile_coord_y());
3735 #ifdef GC_CACHE_SAMPLING
3736 // reset the sampling arrays
3737 bamboo_dtlb_sampling_reset();
3738 #endif // GC_CACHE_SAMPLING
3739 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
3740 // zero out the gccachesamplingtbl
3741 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
3742 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
3743 size_cachesamplingtbl_local_r);
3745 #endif // GC_CACHE_ADAPT
3747 // invalidate all shared mem pointers
3748 bamboo_cur_msp = NULL;
3749 bamboo_smem_size = 0;
3750 bamboo_smem_zero_top = NULL;
3753 if(FINISHPHASE == gcphase) {
3758 //gcprocessing = false;
3759 #ifdef RAWPATH // TODO GC_DEBUG
3760 printf("(%x,%x) Finish gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
3762 } // void gc_collect(struct garbagelist * stackptr)
3764 inline void gc_master(struct garbagelist * stackptr) {
3765 //tprintf("start GC !!!!!!!!!!!!! \n");
3767 gcphase = INITPHASE;
3769 waitconfirm = false;
3773 // Note: all cores need to init gc including non-gc cores
3774 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
3775 // send GC init messages to all cores
3776 send_msg_1(i, GCSTARTINIT, false);
3778 bool isfirst = true;
3779 bool allStall = false;
3781 #ifdef GC_CACHE_ADAPT
3782 // prepare for cache adaption:
3783 cacheAdapt_gc(true);
3784 #endif // GC_CACHE_ADAPT
3786 #ifdef RAWPATH // TODO GC_DEBUG
3787 printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
3788 udn_tile_coord_y());
3791 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3793 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3794 if(gc_checkAllCoreStatus_I()) {
3795 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3798 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3802 if(gc_profile_flag) {
3809 #ifdef GC_CACHE_ADAPT_POLICY_OUTPUT
3810 gc_output_cache_sampling();
3811 #endif // GC_CACHE_ADAPT
3812 #ifdef RAWPATH // TODO GC_DEBUG
3813 printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
3814 udn_tile_coord_y());
3816 // restore the gcstatus of all cores
3817 // Note: all cores have to do mark including non-gc cores
3818 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3819 for(i = 1; i < NUMCORESACTIVE; ++i) {
3820 gccorestatus[i] = 1;
3821 // send GC start messages to all cores
3822 send_msg_1(i, GCSTART, false);
3825 gcphase = MARKPHASE;
3827 while(MARKPHASE == gcphase) {
3828 mark(isfirst, stackptr);
3835 } // while(MARKPHASE == gcphase)
3836 // send msgs to all cores requiring large objs info
3837 // Note: only need to ask gc cores, non-gc cores do not host any objs
3838 numconfirm = NUMCORES4GC - 1;
3839 for(i = 1; i < NUMCORES4GC; ++i) {
3840 send_msg_1(i, GCLOBJREQUEST, false);
3842 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
3847 } // wait for responses
3848 // check the heaptop
3849 if(gcheaptop < gcmarkedptrbound) {
3850 gcheaptop = gcmarkedptrbound;
3854 if(gc_profile_flag) {
3861 #ifdef RAWPATH // TODO GC_DEBUG
3862 printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
3863 udn_tile_coord_y());
3865 // cache all large objs
3867 // no enough space to cache large objs
3868 BAMBOO_EXIT(0xb02b);
3870 // predict number of blocks to fill for each core
3871 unsigned int tmpheaptop = 0;
3872 int numpbc = loadbalance(&tmpheaptop);
3874 numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
3875 #ifdef RAWPATH // TODO GC_DEBUG
3876 printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
3877 udn_tile_coord_y());
3879 //int tmptopptr = 0;
3880 //BASEPTR(gctopcore, 0, &tmptopptr);
3882 //tmptopptr = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
3883 tmpheaptop = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
3884 GC_BAMBOO_DEBUGPRINT(0xabab);
3885 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
3886 for(i = 0; i < NUMCORES4GC; ++i) {
3887 unsigned int tmpcoreptr = 0;
3888 BASEPTR(i, numpbc, &tmpcoreptr);
3889 // init some data strutures for compact phase
3891 gcfilledblocks[i] = 0;
3892 gcrequiredmems[i] = 0;
3893 gccorestatus[i] = 1;
3894 //send start compact messages to all cores
3895 //TODO bug here, do not know if the direction is positive or negtive?
3896 if (tmpcoreptr < tmpheaptop) {
3897 gcstopblock[i] = numpbc + 1;
3898 if(i != STARTUPCORE) {
3899 send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
3901 gcblock2fill = numpbc+1;
3902 } // if(i != STARTUPCORE)
3904 gcstopblock[i] = numpbc;
3905 if(i != STARTUPCORE) {
3906 send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
3908 gcblock2fill = numpbc;
3909 } // if(i != STARTUPCORE)
3911 GC_BAMBOO_DEBUGPRINT(0xf000+i);
3912 GC_BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
3913 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
3920 if(gc_profile_flag) {
3929 bool finalcompact = false;
3930 // initialize pointers for comapcting
3931 struct moveHelper * orig =
3932 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3933 struct moveHelper * to =
3934 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3935 initOrig_Dst(orig, to);
3936 int filledblocks = 0;
3937 unsigned int heaptopptr = 0;
3938 bool finishcompact = false;
3939 bool iscontinue = true;
3940 bool localcompact = true;
3941 while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
3942 if((!finishcompact) && iscontinue) {
3943 GC_BAMBOO_DEBUGPRINT(0xeaa01);
3944 GC_BAMBOO_DEBUGPRINT_REG(numpbc);
3945 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3946 finishcompact = compacthelper(orig, to, &filledblocks,
3947 &heaptopptr, &localcompact);
3948 GC_BAMBOO_DEBUGPRINT(0xeaa02);
3949 GC_BAMBOO_DEBUGPRINT_REG(finishcompact);
3950 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3951 GC_BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
3952 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
3953 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
3956 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3957 if(gc_checkCoreStatus_I()) {
3958 // all cores have finished compacting
3959 // restore the gcstatus of all cores
3960 for(i = 0; i < NUMCORES4GC; ++i) {
3961 gccorestatus[i] = 1;
3963 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3966 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3967 // check if there are spare mem for pending move requires
3968 if(COMPACTPHASE == gcphase) {
3969 GC_BAMBOO_DEBUGPRINT(0xeaa03);
3970 resolvePendingMoveRequest();
3971 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3973 GC_BAMBOO_DEBUGPRINT(0xeaa04);
3976 } // if(gc_checkCoreStatus_I()) else ...
3979 GC_BAMBOO_DEBUGPRINT(0xeaa05);
3980 GC_BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
3981 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3982 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3983 to->ptr = gcmovestartaddr;
3984 to->numblocks = gcblock2fill - 1;
3985 to->bound = (to->numblocks==0) ?
3986 BAMBOO_SMEM_SIZE_L :
3987 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
3988 BASEPTR(gcdstcore, to->numblocks, &(to->base));
3989 to->offset = to->ptr - to->base;
3990 to->top = (to->numblocks==0) ?
3991 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
3993 to->offset = BAMBOO_CACHE_LINE_SIZE;
3994 to->ptr += to->offset; // for header
3995 to->top += to->offset;
3996 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
3997 localcompact = true;
3999 localcompact = false;
4003 } else if(!finishcompact) {
4007 } // while(COMPACTPHASE == gcphase)
4010 if(gc_profile_flag) {
4017 #ifdef RAWPATH // TODO GC_DEBUG
4018 printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
4019 udn_tile_coord_y());
4023 #ifdef RAWPATH // TODO GC_DEBUG
4024 printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
4025 udn_tile_coord_y());
4031 gcphase = FLUSHPHASE;
4032 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4033 // Note: all cores should flush their runtime data including non-gc
4035 for(i = 1; i < NUMCORESACTIVE; ++i) {
4036 // send start flush messages to all cores
4037 gccorestatus[i] = 1;
4038 send_msg_1(i, GCSTARTFLUSH, false);
4042 if(gc_profile_flag) {
4049 #ifdef RAWPATH // TODO GC_DEBUG
4050 printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
4051 udn_tile_coord_y());
4056 #ifdef GC_CACHE_ADAPT
4057 // now the master core need to decide the new cache strategy
4058 cacheAdapt_master();
4059 #endif // GC_CACHE_ADAPT
4061 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4062 while(FLUSHPHASE == gcphase) {
4063 // check the status of all cores
4064 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4065 if(gc_checkAllCoreStatus_I()) {
4066 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4069 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4070 } // while(FLUSHPHASE == gcphase)
4071 #ifdef RAWPATH // TODO GC_DEBUG
4072 printf("(%x,%x) Finish flush phase \n", udn_tile_coord_x(),
4073 udn_tile_coord_y());
4076 #ifdef GC_CACHE_ADAPT
4079 if(gc_profile_flag) {
4086 gcphase = PREFINISHPHASE;
4087 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4088 // Note: all cores should flush their runtime data including non-gc
4090 for(i = 1; i < NUMCORESACTIVE; ++i) {
4091 // send start flush messages to all cores
4092 gccorestatus[i] = 1;
4093 send_msg_1(i, GCSTARTPREF, false);
4095 #ifdef RAWPATH // TODO GC_DEBUG
4096 printf("(%x,%x) Start prefinish phase \n", udn_tile_coord_x(),
4097 udn_tile_coord_y());
4099 // cache adapt phase
4100 cacheAdapt_mutator();
4101 #ifdef GC_CACHE_ADAPT_OUTPUT
4102 bamboo_output_cache_policy();
4104 cacheAdapt_gc(false);
4106 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4107 while(PREFINISHPHASE == gcphase) {
4108 // check the status of all cores
4109 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4110 if(gc_checkAllCoreStatus_I()) {
4111 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4114 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4115 } // while(PREFINISHPHASE == gcphase)
4117 #ifdef GC_CACHE_SAMPLING
4118 // reset the sampling arrays
4119 bamboo_dtlb_sampling_reset();
4120 #endif // GC_CACHE_SAMPLING
4121 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4122 // zero out the gccachesamplingtbl
4123 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
4124 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
4125 size_cachesamplingtbl_local_r);
4126 BAMBOO_MEMSET_WH(gccachepolicytbl,0,size_cachepolicytbl);
4128 #endif // GC_CACHE_ADAPT
4130 gcphase = FINISHPHASE;
4132 // invalidate all shared mem pointers
4133 // put it here as it takes time to inform all the other cores to
4134 // finish gc and it might cause problem when some core resumes
4135 // mutator earlier than the other cores
4136 bamboo_cur_msp = NULL;
4137 bamboo_smem_size = 0;
4138 bamboo_smem_zero_top = NULL;
4142 if(gc_profile_flag) {
4149 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4150 for(i = 1; i < NUMCORESACTIVE; ++i) {
4151 // send gc finish messages to all cores
4152 send_msg_1(i, GCFINISH, false);
4153 gccorestatus[i] = 1;
4157 gcprocessing = false;
4158 #ifdef RAWPATH // TODO GC_DEBUG
4159 printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
4160 udn_tile_coord_y());
4162 //tprintf("finish GC ! \n");
4163 } // void gc_master(struct garbagelist * stackptr)
4165 inline bool gc(struct garbagelist * stackptr) {
4168 gcprocessing = false;
4172 #ifdef GC_CACHE_ADAPT
4173 #ifdef GC_CACHE_SAMPLING
4174 // disable the timer interrupt
4175 bamboo_mask_timer_intr();
4178 // core coordinator routine
4179 if(0 == BAMBOO_NUM_OF_CORE) {
4181 printf("(%x,%x) Check if can do gc or not\n", udn_tile_coord_x(),
4182 udn_tile_coord_y());
4184 bool isallstall = true;
4185 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4186 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4188 for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
4189 if(gccorestatus[ti] != 0) {
4195 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4196 // some of the cores are still executing the mutator and did not reach
4197 // some gc safe point, therefore it is not ready to do gc
4203 if(gc_profile_flag) {
4211 gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
4212 gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
4214 GC_BAMBOO_DEBUGPRINT(0xec04);
4215 for(int i = 0; i < NUMCORESACTIVE; ++i) {
4216 sumsendobj += gcnumsendobjs[0][i];
4217 GC_BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
4218 } // for(i = 1; i < NUMCORESACTIVE; ++i)
4219 GC_BAMBOO_DEBUGPRINT(0xec05);
4220 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
4221 for(int i = 0; i < NUMCORESACTIVE; ++i) {
4222 sumsendobj -= gcnumreceiveobjs[0][i];
4223 GC_BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
4224 } // for(i = 1; i < NUMCORESACTIVE; ++i)
4225 GC_BAMBOO_DEBUGPRINT(0xec06);
4226 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
4227 if(0 != sumsendobj) {
4228 // there were still some msgs on the fly, wait until there
4229 // are some update pregc information coming and check it again
4231 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4239 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4242 #ifdef RAWPATH // TODO GC_DEBUG
4243 printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
4245 // Zero out the remaining bamboo_cur_msp
4246 // Only zero out the first 4 bytes of the remaining memory
4247 // Move the operation here because for the GC_CACHE_ADAPT version,
4248 // we need to make sure during the gcinit phase the shared heap is not
4249 // touched. Otherwise, there would be problem when adapt the cache
4251 if((bamboo_cur_msp != 0)
4252 && (bamboo_smem_zero_top == bamboo_cur_msp)
4253 && (bamboo_smem_size > 0)) {
4254 *((int *)bamboo_cur_msp) = 0;
4256 #ifdef GC_FLUSH_DTLB
4257 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4258 BAMBOO_CLEAN_DTLB();
4259 gc_num_flush_dtlb++;
4262 #ifdef GC_CACHE_ADAPT
4263 #ifdef GC_CACHE_SAMPLING
4264 // get the sampling data
4265 bamboo_output_dtlb_sampling();
4266 #endif // GC_CACHE_SAMPLING
4267 #endif // GC_CACHE_ADAPT
4268 gcprocessing = true;
4269 gc_master(stackptr);
4270 } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
4271 // Zero out the remaining bamboo_cur_msp
4272 // Only zero out the first 4 bytes of the remaining memory
4273 // Move the operation here because for the GC_CACHE_ADAPT version,
4274 // we need to make sure during the gcinit phase the shared heap is not
4275 // touched. Otherwise, there would be problem when adapt the cache
4277 if((bamboo_cur_msp != 0)
4278 && (bamboo_smem_zero_top == bamboo_cur_msp)
4279 && (bamboo_smem_size > 0)) {
4280 *((int *)bamboo_cur_msp) = 0;
4282 #ifdef GC_FLUSH_DTLB
4283 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4284 BAMBOO_CLEAN_DTLB();
4285 gc_num_flush_dtlb++;
4288 #ifdef GC_CACHE_ADAPT
4289 #ifdef GC_CACHE_SAMPLING
4290 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4291 // get the sampling data
4292 bamboo_output_dtlb_sampling();
4294 #endif // GC_CACHE_SAMPLING
4295 #endif // GC_CACHE_ADAPT
4296 gcprocessing = true;
4297 gc_collect(stackptr);
4299 // Zero out the remaining bamboo_cur_msp
4300 // Only zero out the first 4 bytes of the remaining memory
4301 // Move the operation here because for the GC_CACHE_ADAPT version,
4302 // we need to make sure during the gcinit phase the shared heap is not
4303 // touched. Otherwise, there would be problem when adapt the cache
4305 if((bamboo_cur_msp != 0)
4306 && (bamboo_smem_zero_top == bamboo_cur_msp)
4307 && (bamboo_smem_size > 0)) {
4308 *((int *)bamboo_cur_msp) = 0;
4310 #ifdef GC_FLUSH_DTLB
4311 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4312 BAMBOO_CLEAN_DTLB();
4313 gc_num_flush_dtlb++;
4316 #ifdef GC_CACHE_ADAPT
4317 #ifdef GC_CACHE_SAMPLING
4318 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4319 // get the sampling data
4320 bamboo_output_dtlb_sampling();
4322 #endif // GC_CACHE_SAMPLING
4323 #endif // GC_CACHE_ADAPT
4324 // not a gc core, should wait for gcfinish msg
4325 gcprocessing = true;
4326 gc_nocollect(stackptr);
4328 #ifdef GC_CACHE_ADAPT
4329 #ifdef GC_CACHE_SAMPLING
4330 // enable the timer interrupt
4331 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING);
4332 bamboo_unmask_timer_intr();
4333 #endif // GC_CACHE_SAMPLING
4334 #endif // GC_CACHE_ADAPT
4337 } // void gc(struct garbagelist * stackptr)
4340 inline void gc_profileStart(void) {
4341 if(!gc_infoOverflow) {
4342 GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
4343 gc_infoArray[gc_infoIndex] = gcInfo;
4345 gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
4349 inline void gc_profileItem(void) {
4350 if(!gc_infoOverflow) {
4351 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
4352 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
4356 inline void gc_profileEnd(void) {
4357 if(!gc_infoOverflow) {
4358 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
4359 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
4360 gcInfo->time[gcInfo->index++] = gc_num_livespace;
4361 gcInfo->time[gcInfo->index++] = gc_num_freespace;
4362 gcInfo->time[gcInfo->index++] = gc_num_lobj;
4363 gcInfo->time[gcInfo->index++] = gc_num_lobjspace;
4364 gcInfo->time[gcInfo->index++] = gc_num_obj;
4365 gcInfo->time[gcInfo->index++] = gc_num_liveobj;
4366 gcInfo->time[gcInfo->index++] = gc_num_forwardobj;
4368 if(gc_infoIndex == GCINFOLENGTH) {
4369 gc_infoOverflow = true;
4370 //taskInfoIndex = 0;
4375 // output the profiling data
4376 void gc_outputProfileData() {
4379 unsigned long long totalgc = 0;
4381 #ifndef BAMBOO_MEMPROF
4382 BAMBOO_PRINT(0xdddd);
4384 // output task related info
4385 for(i= 0; i < gc_infoIndex; i++) {
4386 GCInfo * gcInfo = gc_infoArray[i];
4387 #ifdef BAMBOO_MEMPROF
4388 unsigned long long tmp=gcInfo->time[gcInfo->index-8]-gcInfo->time[0]; //0;
4390 unsigned long long tmp = 0;
4391 BAMBOO_PRINT(0xddda);
4392 for(j = 0; j < gcInfo->index - 7; j++) {
4393 BAMBOO_PRINT(gcInfo->time[j]);
4394 BAMBOO_PRINT(gcInfo->time[j]-tmp);
4395 BAMBOO_PRINT(0xdddb);
4396 tmp = gcInfo->time[j];
4398 tmp = (tmp-gcInfo->time[0]);
4399 BAMBOO_PRINT_REG(tmp);
4400 BAMBOO_PRINT(0xdddc);
4401 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 7]);
4402 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 6]);
4403 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 5]);
4404 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 4]);
4405 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 3]);
4406 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 2]);
4407 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 1]);
4408 BAMBOO_PRINT(0xddde);
4412 #ifndef BAMBOO_MEMPROF
4413 BAMBOO_PRINT(0xdddf);
4415 BAMBOO_PRINT_REG(totalgc);
4417 if(gc_infoOverflow) {
4418 BAMBOO_PRINT(0xefee);
4421 #ifndef BAMBOO_MEMPROF
4422 BAMBOO_PRINT(0xeeee);
4425 #endif // #ifdef GC_PROFILE