1 // BAMBOO_EXIT(0xb000);
2 // TODO: DO NOT support tag!!!
5 #include "multicoregarbage.h"
6 #include "multicoreruntime.h"
7 #include "runtime_arch.h"
8 #include "SimpleHash.h"
9 #include "GenericHashtable.h"
10 #include "ObjectHash.h"
11 #include "GCSharedHash.h"
15 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
16 extern int numqueues[][NUMCLASSES];
17 extern struct genhashtable * activetasks;
18 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
19 extern struct taskparamdescriptor *currtpd;
20 extern struct LockValue runtime_locks[MAXTASKPARAMS];
21 extern int runtime_locklen;
24 extern struct global_defs_t * global_defs_p;
27 extern unsigned int gcmem_mixed_threshold;
28 extern unsigned int gcmem_mixed_usedmem;
32 extern struct lockvector bamboo_threadlocks;
37 struct pointerblock *next;
40 struct pointerblock *gchead=NULL;
42 struct pointerblock *gctail=NULL;
44 struct pointerblock *gctail2=NULL;
46 struct pointerblock *gcspare=NULL;
48 #define NUMLOBJPTRS 20
50 struct lobjpointerblock {
51 void * lobjs[NUMLOBJPTRS];
52 int lengths[NUMLOBJPTRS];
53 int hosts[NUMLOBJPTRS];
54 struct lobjpointerblock *next;
55 struct lobjpointerblock *prev;
58 struct lobjpointerblock *gclobjhead=NULL;
59 int gclobjheadindex=0;
60 struct lobjpointerblock *gclobjtail=NULL;
61 int gclobjtailindex=0;
62 struct lobjpointerblock *gclobjtail2=NULL;
63 int gclobjtailindex2=0;
64 struct lobjpointerblock *gclobjspare=NULL;
67 typedef struct gc_cache_revise_info {
68 unsigned int orig_page_start_va;
69 unsigned int orig_page_end_va;
70 unsigned int orig_page_index;
71 unsigned int to_page_start_va;
72 unsigned int to_page_end_va;
73 unsigned int to_page_index;
74 unsigned int revised_sampling[NUMCORESACTIVE];
75 } gc_cache_revise_info_t;
76 gc_cache_revise_info_t gc_cache_revise_infomation;
77 #endif// GC_CACHE_ADAPT
80 // dump whole mem in blocks
81 inline void dumpSMem() {
89 printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
91 // reserved blocks for sblocktbl
92 printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
94 for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
95 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",
96 udn_tile_coord_x(), udn_tile_coord_y(),
97 *((int *)(i)), *((int *)(i + 4)),
98 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
99 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
100 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
101 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
102 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
103 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
104 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
106 sblock = gcreservedsb;
107 bool advanceblock = false;
109 for(i=gcbaseva; i<gcbaseva+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
110 advanceblock = false;
111 // computing sblock # and block #, core coordinate (x,y) also
112 if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
114 if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
115 if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
127 coren = gc_block2core[block%(NUMCORES4GC*2)];
129 // compute core coordinate
130 BAMBOO_COORDS(coren, &x, &y);
131 printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
132 udn_tile_coord_x(), udn_tile_coord_y(),
133 block, sblock++, x, y,
134 (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
137 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",
138 udn_tile_coord_x(), udn_tile_coord_y(),
139 *((int *)(i)), *((int *)(i + 4)),
140 *((int *)(i + 4*2)), *((int *)(i + 4*3)),
141 *((int *)(i + 4*4)), *((int *)(i + 4*5)),
142 *((int *)(i + 4*6)), *((int *)(i + 4*7)),
143 *((int *)(i + 4*8)), *((int *)(i + 4*9)),
144 *((int *)(i + 4*10)), *((int *)(i + 4*11)),
145 *((int *)(i + 4*12)), *((int *)(i + 4*13)),
146 *((int *)(i + 4*14)), *((int *)(i + 4*15)));
148 printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
152 // should be invoked with interruption closed
153 inline void gc_enqueue_I(void *ptr) {
154 GC_BAMBOO_DEBUGPRINT(0xe601);
155 GC_BAMBOO_DEBUGPRINT_REG(ptr);
156 if (gcheadindex==NUMPTRS) {
157 struct pointerblock * tmp;
162 tmp=RUNMALLOC_I(sizeof(struct pointerblock));
163 } // if (gcspare!=NULL)
167 } // if (gcheadindex==NUMPTRS)
168 gchead->ptrs[gcheadindex++]=ptr;
169 GC_BAMBOO_DEBUGPRINT(0xe602);
170 } // void gc_enqueue_I(void *ptr)
172 // dequeue and destroy the queue
173 inline void * gc_dequeue_I() {
174 if (gctailindex==NUMPTRS) {
175 struct pointerblock *tmp=gctail;
182 } // if (gcspare!=NULL)
183 } // if (gctailindex==NUMPTRS)
184 return gctail->ptrs[gctailindex++];
185 } // void * gc_dequeue()
187 // dequeue and do not destroy the queue
188 inline void * gc_dequeue2_I() {
189 if (gctailindex2==NUMPTRS) {
190 struct pointerblock *tmp=gctail2;
191 gctail2=gctail2->next;
193 } // if (gctailindex2==NUMPTRS)
194 return gctail2->ptrs[gctailindex2++];
195 } // void * gc_dequeue2()
197 inline int gc_moreItems_I() {
198 if ((gchead==gctail)&&(gctailindex==gcheadindex))
201 } // int gc_moreItems()
203 inline int gc_moreItems2_I() {
204 if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
207 } // int gc_moreItems2()
209 // should be invoked with interruption closed
210 // enqueue a large obj: start addr & length
211 inline void gc_lobjenqueue_I(void *ptr,
214 GC_BAMBOO_DEBUGPRINT(0xe901);
215 if (gclobjheadindex==NUMLOBJPTRS) {
216 struct lobjpointerblock * tmp;
217 if (gclobjspare!=NULL) {
221 tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
222 } // if (gclobjspare!=NULL)
223 gclobjhead->next=tmp;
224 tmp->prev = gclobjhead;
227 } // if (gclobjheadindex==NUMLOBJPTRS)
228 gclobjhead->lobjs[gclobjheadindex]=ptr;
229 gclobjhead->lengths[gclobjheadindex]=length;
230 gclobjhead->hosts[gclobjheadindex++]=host;
231 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
232 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
233 GC_BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
234 } // void gc_lobjenqueue_I(void *ptr...)
236 // dequeue and destroy the queue
237 inline void * gc_lobjdequeue_I(unsigned int * length,
238 unsigned int * host) {
239 if (gclobjtailindex==NUMLOBJPTRS) {
240 struct lobjpointerblock *tmp=gclobjtail;
241 gclobjtail=gclobjtail->next;
243 gclobjtail->prev = NULL;
244 if (gclobjspare!=NULL) {
250 } // if (gclobjspare!=NULL)
251 } // if (gclobjtailindex==NUMLOBJPTRS)
253 *length = gclobjtail->lengths[gclobjtailindex];
256 *host = (unsigned int)(gclobjtail->hosts[gclobjtailindex]);
258 return gclobjtail->lobjs[gclobjtailindex++];
259 } // void * gc_lobjdequeue()
261 inline int gc_lobjmoreItems_I() {
262 if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
265 } // int gc_lobjmoreItems()
267 // dequeue and don't destroy the queue
268 inline void gc_lobjdequeue2_I() {
269 if (gclobjtailindex2==NUMLOBJPTRS) {
270 gclobjtail2=gclobjtail2->next;
274 } // if (gclobjtailindex2==NUMLOBJPTRS)
275 } // void * gc_lobjdequeue2()
277 inline int gc_lobjmoreItems2_I() {
278 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
281 } // int gc_lobjmoreItems2()
283 // 'reversly' dequeue and don't destroy the queue
284 inline void gc_lobjdequeue3_I() {
285 if (gclobjtailindex2==0) {
286 gclobjtail2=gclobjtail2->prev;
287 gclobjtailindex2=NUMLOBJPTRS-1;
290 } // if (gclobjtailindex2==NUMLOBJPTRS)
291 } // void * gc_lobjdequeue3()
293 inline int gc_lobjmoreItems3_I() {
294 if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
297 } // int gc_lobjmoreItems3()
299 inline void gc_lobjqueueinit4_I() {
300 gclobjtail2 = gclobjtail;
301 gclobjtailindex2 = gclobjtailindex;
302 } // void gc_lobjqueueinit2()
304 inline void * gc_lobjdequeue4_I(unsigned int * length,
305 unsigned int * host) {
306 if (gclobjtailindex2==NUMLOBJPTRS) {
307 gclobjtail2=gclobjtail2->next;
309 } // if (gclobjtailindex==NUMLOBJPTRS)
311 *length = gclobjtail2->lengths[gclobjtailindex2];
314 *host = (unsigned int)(gclobjtail2->hosts[gclobjtailindex2]);
316 return gclobjtail2->lobjs[gclobjtailindex2++];
317 } // void * gc_lobjdequeue()
319 inline int gc_lobjmoreItems4_I() {
320 if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
323 } // int gc_lobjmoreItems(
325 unsigned int gccurr_heapbound = 0;
327 inline void gettype_size(void * ptr,
329 unsigned int * tsize) {
330 int type = ((int *)ptr)[0];
331 unsigned int size = 0;
332 if(type < NUMCLASSES) {
334 size = classsize[type];
337 struct ArrayObject *ao=(struct ArrayObject *)ptr;
338 unsigned int elementsize=classsize[type];
339 unsigned int length=ao->___length___;
340 size=sizeof(struct ArrayObject)+length*elementsize;
341 } // if(type < NUMCLASSES)
346 inline bool isLarge(void * ptr,
348 unsigned int * tsize) {
349 GC_BAMBOO_DEBUGPRINT(0xe701);
350 GC_BAMBOO_DEBUGPRINT_REG(ptr);
351 // check if a pointer is referring to a large object
352 gettype_size(ptr, ttype, tsize);
353 GC_BAMBOO_DEBUGPRINT(*tsize);
354 unsigned int bound = (BAMBOO_SMEM_SIZE);
355 if(((unsigned int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
356 bound = (BAMBOO_SMEM_SIZE_L);
358 if((((unsigned int)ptr-gcbaseva)%(bound))==0) {
359 // ptr is a start of a block
360 GC_BAMBOO_DEBUGPRINT(0xe702);
361 GC_BAMBOO_DEBUGPRINT(1);
364 if((bound-(((unsigned int)ptr-gcbaseva)%bound)) < (*tsize)) {
365 // it acrosses the boundary of current block
366 GC_BAMBOO_DEBUGPRINT(0xe703);
367 GC_BAMBOO_DEBUGPRINT(1);
370 GC_BAMBOO_DEBUGPRINT(0);
372 } // bool isLarge(void * ptr, int * ttype, int * tsize)
374 inline unsigned int hostcore(void * ptr) {
375 // check the host core of ptr
376 unsigned int host = 0;
377 RESIDECORE(ptr, &host);
378 GC_BAMBOO_DEBUGPRINT(0xedd0);
379 GC_BAMBOO_DEBUGPRINT_REG(ptr);
380 GC_BAMBOO_DEBUGPRINT_REG(host);
382 } // int hostcore(void * ptr)
384 inline void cpu2coords(unsigned int coren,
387 *x = bamboo_cpu2coords[2*coren];
388 *y = bamboo_cpu2coords[2*coren+1];
389 } // void cpu2coords(...)
391 inline bool isLocal(void * ptr) {
392 // check if a pointer is in shared heap on this core
393 return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
394 } // bool isLocal(void * ptr)
396 inline bool gc_checkCoreStatus_I() {
397 bool allStall = true;
398 for(int i = 0; i < NUMCORES4GC; ++i) {
399 if(gccorestatus[i] != 0) {
402 } // if(gccorestatus[i] != 0)
403 } // for(i = 0; i < NUMCORES4GC; ++i)
407 inline bool gc_checkAllCoreStatus_I() {
408 bool allStall = true;
409 for(int i = 0; i < NUMCORESACTIVE; ++i) {
410 if(gccorestatus[i] != 0) {
413 } // if(gccorestatus[i] != 0)
414 } // for(i = 0; i < NUMCORESACTIVE; ++i)
418 inline void checkMarkStatue() {
419 GC_BAMBOO_DEBUGPRINT(0xee01);
422 (waitconfirm && (numconfirm == 0))) {
423 GC_BAMBOO_DEBUGPRINT(0xee02);
424 unsigned int entry_index = 0;
427 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
430 entry_index = gcnumsrobjs_index;
432 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
433 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
434 gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
435 gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
436 // check the status of all cores
437 bool allStall = gc_checkAllCoreStatus_I();
438 GC_BAMBOO_DEBUGPRINT(0xee03);
440 GC_BAMBOO_DEBUGPRINT(0xee04);
443 GC_BAMBOO_DEBUGPRINT(0xee05);
444 // the first time found all cores stall
445 // send out status confirm msg to all other cores
446 // reset the corestatus array too
447 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
449 numconfirm = NUMCORESACTIVE - 1;
450 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
451 for(i = 1; i < NUMCORESACTIVE; ++i) {
453 // send mark phase finish confirm request msg to core i
454 send_msg_1(i, GCMARKCONFIRM, false);
455 } // for(i = 1; i < NUMCORESACTIVE; ++i)
458 // check if the sum of send objs and receive obj are the same
459 // yes->check if the info is the latest; no->go on executing
460 unsigned int sumsendobj = 0;
461 for(i = 0; i < NUMCORESACTIVE; ++i) {
462 sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
463 } // for(i = 0; i < NUMCORESACTIVE; ++i)
464 GC_BAMBOO_DEBUGPRINT(0xee06);
465 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
466 for(i = 0; i < NUMCORESACTIVE; ++i) {
467 sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
468 } // for(i = 0; i < NUMCORESACTIVE; ++i)
469 GC_BAMBOO_DEBUGPRINT(0xee07);
470 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
471 if(0 == sumsendobj) {
472 // Check if there are changes of the numsendobjs or numreceiveobjs on
474 bool ischanged = false;
475 for(i = 0; i < NUMCORESACTIVE; ++i) {
476 if((gcnumsendobjs[0][i] != gcnumsendobjs[1][i]) ||
477 (gcnumreceiveobjs[0][i] != gcnumreceiveobjs[1][i]) ) {
481 } // for(i = 0; i < NUMCORESACTIVE; ++i)
482 GC_BAMBOO_DEBUGPRINT(0xee08);
483 GC_BAMBOO_DEBUGPRINT_REG(ischanged);
485 GC_BAMBOO_DEBUGPRINT(0xee09);
486 // all the core status info are the latest
488 gcphase = COMPACTPHASE;
489 // restore the gcstatus for all cores
490 for(i = 0; i < NUMCORESACTIVE; ++i) {
492 } // for(i = 0; i < NUMCORESACTIVE; ++i)
494 // There were changes between phase 1 and phase 2, can not decide
495 // whether the mark phase has been finished
497 // As it fails in phase 2, flip the entries
498 gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
501 // There were changes between phase 1 and phase 2, can not decide
502 // whether the mark phase has been finished
504 // As it fails in phase 2, flip the entries
505 gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
506 } // if(0 == sumsendobj) else ...
507 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
508 } // if(!gcwaitconfirm) else()
510 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
512 } // if((!waitconfirm)...
513 GC_BAMBOO_DEBUGPRINT(0xee0a);
514 } // void checkMarkStatue()
516 inline void initGC() {
518 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
519 for(i = 0; i < NUMCORES4GC; ++i) {
521 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
522 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
524 gcrequiredmems[i] = 0;
525 gcfilledblocks[i] = 0;
527 } // for(i = 0; i < NUMCORES4GC; ++i)
528 for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
530 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
531 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
537 // initialize the gcmappingtbl
538 BAMBOO_MEMSET_WH(gcmappingtbl, 0, bamboo_rmsp_size);
540 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
541 gcself_numsendobjs = 0;
542 gcself_numreceiveobjs = 0;
543 gcmarkedptrbound = 0;
554 gcheadindex=gctailindex=gctailindex2 = 0;
555 gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
557 gctailindex = gctailindex2 = gcheadindex;
558 gctail = gctail2 = gchead;
561 // initialize the large obj queues
562 if (gclobjhead==NULL) {
565 gclobjtailindex2 = 0;
566 gclobjhead=gclobjtail=gclobjtail2=
567 RUNMALLOC(sizeof(struct lobjpointerblock));
569 gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
570 gclobjtail = gclobjtail2 = gclobjhead;
572 gclobjhead->next = gclobjhead->prev = NULL;
574 freeMGCHash(gcforwardobjtbl);
575 gcforwardobjtbl = allocateMGCHash(20, 3);
578 gc_num_livespace = 0;
579 gc_num_freespace = 0;
581 gc_num_lobjspace = 0;
583 gc_num_forwardobj = 0;
584 gc_num_profiles = NUMCORESACTIVE - 1;
588 // compute load balance for all cores
589 inline int loadbalance(unsigned int * heaptop) {
590 // compute load balance
593 // get the total loads
594 unsigned int tloads = gcloads[STARTUPCORE];
595 for(i = 1; i < NUMCORES4GC; i++) {
596 tloads += gcloads[i];
598 *heaptop = gcbaseva + tloads;
600 GC_BAMBOO_DEBUGPRINT(0xdddd);
601 GC_BAMBOO_DEBUGPRINT_REG(tloads);
602 GC_BAMBOO_DEBUGPRINT_REG(*heaptop);
604 BLOCKINDEX(*heaptop, &b);
605 unsigned int numbpc = (unsigned int)b/(unsigned int)(NUMCORES4GC);// num of blocks per core
606 GC_BAMBOO_DEBUGPRINT_REG(b);
607 GC_BAMBOO_DEBUGPRINT_REG(numbpc);
609 RESIDECORE(heaptop, &gctopcore);
610 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
612 } // void loadbalance(int * heaptop)
614 inline bool cacheLObjs() {
615 // check the total mem size need for large objs
616 unsigned long long sumsize = 0;
617 unsigned int size = 0;
618 GC_BAMBOO_DEBUGPRINT(0xe801);
619 gclobjtail2 = gclobjtail;
620 gclobjtailindex2 = gclobjtailindex;
621 unsigned int tmp_lobj = 0;
622 unsigned int tmp_len = 0;
623 unsigned int tmp_host = 0;
624 // compute total mem size required and sort the lobjs in ascending order
625 // TODO USE QUICK SORT INSTEAD?
626 while(gc_lobjmoreItems2_I()) {
628 tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
629 tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
630 tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
634 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
641 GC_BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
642 GC_BAMBOO_DEBUGPRINT_REG(tmp_len);
643 GC_BAMBOO_DEBUGPRINT_REG(sumsize);
644 unsigned int i = gclobjtailindex2-1;
645 struct lobjpointerblock * tmp_block = gclobjtail2;
646 // find the place to insert
649 if(tmp_block->prev == NULL) {
652 if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
653 tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
654 tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
655 tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
656 tmp_block = tmp_block->prev;
660 } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
662 if(tmp_block->lobjs[i-1] > tmp_lobj) {
663 tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
664 tmp_block->lengths[i] = tmp_block->lengths[i-1];
665 tmp_block->hosts[i] = tmp_block->hosts[i-1];
669 } // if(tmp_block->lobjs[i-1] < tmp_lobj)
670 } // if(i ==0 ) else {}
673 if(i != gclobjtailindex2 - 1) {
674 tmp_block->lobjs[i] = tmp_lobj;
675 tmp_block->lengths[i] = tmp_len;
676 tmp_block->hosts[i] = tmp_host;
678 } // while(gc_lobjmoreItems2())
682 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
684 gc_num_lobjspace = sumsize;
689 // check if there are enough space to cache these large objs
690 unsigned int dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
691 if((unsigned long long)gcheaptop > (unsigned long long)dst) {
692 // do not have enough room to cache large objs
693 GC_BAMBOO_DEBUGPRINT(0xe802);
694 GC_BAMBOO_DEBUGPRINT_REG(dst);
695 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
696 GC_BAMBOO_DEBUGPRINT_REG(sumsize);
699 GC_BAMBOO_DEBUGPRINT(0xe803);
700 GC_BAMBOO_DEBUGPRINT_REG(dst);
701 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
703 gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
704 // cache the largeObjs to the top of the shared heap
705 dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
706 while(gc_lobjmoreItems3_I()) {
708 size = gclobjtail2->lengths[gclobjtailindex2];
709 // set the mark field to , indicating that this obj has been moved
710 // and need to be flushed
711 ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[BAMBOOMARKBIT] = COMPACTED;
713 if((unsigned int)dst <
714 (unsigned int)(gclobjtail2->lobjs[gclobjtailindex2]+size)) {
715 memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
717 memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
719 GC_BAMBOO_DEBUGPRINT(0x804);
720 GC_BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
721 GC_BAMBOO_DEBUGPRINT(dst);
722 GC_BAMBOO_DEBUGPRINT_REG(size);
723 GC_BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
724 GC_BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
727 } // void cacheLObjs()
729 // update the bmmboo_smemtbl to record current shared mem usage
730 void updateSmemTbl(unsigned int coren,
731 unsigned int localtop) {
732 unsigned int ltopcore = 0;
733 unsigned int bound = BAMBOO_SMEM_SIZE_L;
734 BLOCKINDEX(localtop, <opcore);
735 if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
736 bound = BAMBOO_SMEM_SIZE;
738 unsigned int load = (unsigned int)(localtop-gcbaseva)%(unsigned int)bound;
741 unsigned int toset = 0;
743 toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
745 if(toset >= gcnumblock) {
746 tprintf("ltopcore: %d, localtop: %x, toset: %d, gcnumblock: %d (%d, %d) \n", ltopcore, localtop, toset, gcnumblock, i, j);
750 if(toset < ltopcore) {
751 bamboo_smemtbl[toset]=
752 (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
754 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
756 } else if(toset == ltopcore) {
757 bamboo_smemtbl[toset] = load;
759 gcmem_mixed_usedmem += bamboo_smemtbl[toset];
771 } // void updateSmemTbl(int, int)
773 inline void moveLObjs() {
774 GC_BAMBOO_DEBUGPRINT(0xea01);
776 // update the gcmem_mixed_usedmem
777 gcmem_mixed_usedmem = 0;
779 // zero out the smemtbl
780 BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
781 // find current heap top
782 // flush all gcloads to indicate the real heap top on one core
783 // previous it represents the next available ptr on a core
784 if(((unsigned int)gcloads[0] > (unsigned int)(gcbaseva+BAMBOO_SMEM_SIZE_L))
785 && (((unsigned int)gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
786 // edge of a block, check if this is exactly the heaptop
787 BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
788 gcloads[0]+=(gcfilledblocks[0]>1 ?
789 (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
791 updateSmemTbl(0, gcloads[0]);
792 GC_BAMBOO_DEBUGPRINT(0xea02);
793 GC_BAMBOO_DEBUGPRINT_REG(gcloads[0]);
794 GC_BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
795 for(int i = 1; i < NUMCORES4GC; i++) {
796 unsigned int tmptop = 0;
797 GC_BAMBOO_DEBUGPRINT(0xf000+i);
798 GC_BAMBOO_DEBUGPRINT_REG(gcloads[i]);
799 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
800 if((gcfilledblocks[i] > 0)
801 && (((unsigned int)gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
802 // edge of a block, check if this is exactly the heaptop
803 BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
805 (gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
808 updateSmemTbl(i, gcloads[i]);
809 GC_BAMBOO_DEBUGPRINT_REG(gcloads[i]);
810 } // for(int i = 1; i < NUMCORES4GC; i++) {
812 // find current heap top
814 // a bug here: when using local allocation, directly move large objects
815 // to the highest free chunk might not be memory efficient
816 unsigned int tmpheaptop = 0;
817 unsigned int size = 0;
818 unsigned int bound = 0;
820 for(i = gcnumblock-1; i >= 0; i--) {
821 if(bamboo_smemtbl[i] > 0) {
826 tmpheaptop = gcbaseva;
828 tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
829 (BAMBOO_SMEM_SIZE_L*i) :
830 (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
833 // move large objs from gcheaptop to tmpheaptop
834 // write the header first
835 unsigned int tomove = gcbaseva+(BAMBOO_SHARED_MEM_SIZE)-gcheaptop;
837 gcmem_mixed_usedmem += tomove;
839 GC_BAMBOO_DEBUGPRINT(0xea03);
840 GC_BAMBOO_DEBUGPRINT_REG(tomove);
841 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
842 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
843 // flush the sbstartbl
844 BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
845 (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-(unsigned int)gcreservedsb)
846 *sizeof(unsigned int));
848 gcheaptop = tmpheaptop;
850 // check how many blocks it acrosses
851 unsigned int remain = tmpheaptop-gcbaseva;
852 unsigned int sb = remain/BAMBOO_SMEM_SIZE+(unsigned int)gcreservedsb;//number of the sblock
853 unsigned int b = 0; // number of the block
854 BLOCKINDEX(tmpheaptop, &b);
855 // check the remaining space in this block
856 bound = (BAMBOO_SMEM_SIZE);
857 if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
858 bound = (BAMBOO_SMEM_SIZE_L);
860 remain = bound - remain%bound;
862 GC_BAMBOO_DEBUGPRINT(0xea04);
864 unsigned int isize = 0;
865 unsigned int host = 0;
866 unsigned int ptr = 0;
867 unsigned int base = tmpheaptop;
868 unsigned int cpysize = 0;
869 remain -= BAMBOO_CACHE_LINE_SIZE;
870 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
871 gc_lobjqueueinit4_I();
872 while(gc_lobjmoreItems4_I()) {
873 ptr = (unsigned int)(gc_lobjdequeue4_I(&size, &host));
874 ALIGNSIZE(size, &isize);
876 // this object acrosses blocks
878 // close current block, fill its header
879 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
880 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
881 bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE;//add the size of header
883 if(b >= gcnumblock) {
890 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
891 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
893 remain -= BAMBOO_CACHE_LINE_SIZE;
894 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
895 BLOCKINDEX(tmpheaptop, &b);
896 sb = (unsigned int)(tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE)
900 // move the large obj
901 if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
902 memmove(tmpheaptop, gcheaptop, size);
904 //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
905 memcpy(tmpheaptop, gcheaptop, size);
907 // fill the remaining space with -2 padding
908 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
909 GC_BAMBOO_DEBUGPRINT(0xea05);
910 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
911 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
912 GC_BAMBOO_DEBUGPRINT_REG(size);
913 GC_BAMBOO_DEBUGPRINT_REG(isize);
914 GC_BAMBOO_DEBUGPRINT_REG(base);
917 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] != 3)) {
918 tprintf("Error moveLobj: %x %x \n",
919 (int)ptr, ((int *)(ptr))[BAMBOOMARKBIT] );
923 // cache the mapping info
924 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] =
925 (unsigned int)tmpheaptop;
927 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] ==
928 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)-1]) {
929 tprintf("Error moveobj ^^ : %x, %x, %d \n", (int)ptr,
930 (int)tmpheaptop, OBJMAPPINGINDEX((unsigned int)ptr));
934 GC_BAMBOO_DEBUGPRINT(0xcdca);
935 GC_BAMBOO_DEBUGPRINT_REG(ptr);
936 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
939 // set the gcsbstarttbl and bamboo_smemtbl
940 unsigned int tmpsbs=1+(unsigned int)(isize-remain-1)/BAMBOO_SMEM_SIZE;
941 for(int k = 1; k < tmpsbs; k++) {
942 gcsbstarttbl[sb+k] = -1;
944 if((sb+k) >= gcsbstarttbl_len) {
950 bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
951 BLOCKINDEX(tmpheaptop-1, &tmpsbs);
952 for(; b < tmpsbs; b++) {
953 bamboo_smemtbl[b] = bound;
955 if(b >= gcnumblock) {
959 if(b==NUMCORES4GC-1) {
960 bound = BAMBOO_SMEM_SIZE;
963 if(((unsigned int)(isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
964 gcsbstarttbl[sb] = -1;
965 remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
966 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
967 bamboo_smemtbl[b] = bound;
969 gcsbstarttbl[sb] = (int)tmpheaptop;
970 remain = tmpheaptop-gcbaseva;
971 bamboo_smemtbl[b] = remain%bound;
972 remain = bound - bamboo_smemtbl[b];
973 } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
975 if(sb >= gcsbstarttbl_len) {
978 if(b >= gcnumblock) {
983 // close current block and fill the header
984 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
985 *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
988 if(remain == BAMBOO_CACHE_LINE_SIZE) {
989 // fill with 0 in case
990 BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
992 remain -= BAMBOO_CACHE_LINE_SIZE;
993 tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
996 // move the large obj
997 if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
998 memmove(tmpheaptop, gcheaptop, size);
1000 memcpy(tmpheaptop, gcheaptop, size);
1002 // fill the remaining space with -2 padding
1003 BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
1004 GC_BAMBOO_DEBUGPRINT(0xea06);
1005 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1006 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1007 GC_BAMBOO_DEBUGPRINT_REG(size);
1008 GC_BAMBOO_DEBUGPRINT_REG(isize);
1013 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] != 3)) {
1014 tprintf("Error moveLobj: %x %x \n", (int)ptr,
1015 ((int *)(ptr))[BAMBOOMARKBIT] );
1016 BAMBOO_EXIT(0xb009);
1019 // cache the mapping info
1020 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] =
1021 (unsigned int)tmpheaptop;
1023 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)] ==
1024 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)-1]) {
1025 tprintf("Error moveobj ?? : %x, %x, %d \n", (int)ptr,
1026 (int)tmpheaptop, OBJMAPPINGINDEX((unsigned int)ptr));
1027 BAMBOO_EXIT(0xb00a);
1029 if(!ISSHAREDOBJ(tmpheaptop)) {
1030 tprintf("Error: %x, %x \n", (int)ptr, (int)tmpheaptop);
1031 BAMBOO_EXIT(0xb00b);
1034 GC_BAMBOO_DEBUGPRINT(0xcdcc);
1035 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1036 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
1037 GC_BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
1038 tmpheaptop += isize;
1040 // update bamboo_smemtbl
1041 bamboo_smemtbl[b] += isize;
1043 if(b >= gcnumblock) {
1044 BAMBOO_EXIT(0xb00c);
1047 } // if(remain < isize) else ...
1048 } // while(gc_lobjmoreItems())
1050 // close current block, fill the header
1051 BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
1052 *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
1053 bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;//add the size of the header
1055 if(b >= gcnumblock) {
1056 BAMBOO_EXIT(0xb00d);
1060 tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
1062 gcheaptop = tmpheaptop;
1064 } // if(tomove == 0)
1066 GC_BAMBOO_DEBUGPRINT(0xea07);
1067 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1069 bamboo_free_block = 0;
1070 unsigned int tbound = 0;
1072 tbound = (bamboo_free_block<NUMCORES4GC) ?
1073 BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1074 if(bamboo_smemtbl[bamboo_free_block] == tbound) {
1075 bamboo_free_block++;
1077 // the first non-full partition
1082 if(bamboo_free_block >= gcnumblock) {
1083 BAMBOO_EXIT(0xb00e);
1089 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
1091 // check how many live space there are
1092 gc_num_livespace = 0;
1093 for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
1094 gc_num_livespace += bamboo_smemtbl[tmpi];
1096 gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace;
1101 GC_BAMBOO_DEBUGPRINT(0xea08);
1102 GC_BAMBOO_DEBUGPRINT_REG(gcheaptop);
1103 } // void moveLObjs()
1105 inline void markObj(void * objptr) {
1106 if(objptr == NULL) {
1109 if(ISSHAREDOBJ(objptr)) {
1110 unsigned int host = hostcore(objptr);
1111 if(BAMBOO_NUM_OF_CORE == host) {
1113 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1114 if(((int *)objptr)[BAMBOOMARKBIT] == INIT) {
1115 // this is the first time that this object is discovered,
1116 // set the flag as DISCOVERED
1117 ((int *)objptr)[BAMBOOMARKBIT] = DISCOVERED;
1118 BAMBOO_CACHE_FLUSH_LINE(objptr);
1119 gc_enqueue_I(objptr);
1122 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]=1;
1125 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1127 GC_BAMBOO_DEBUGPRINT(0xbbbb);
1128 GC_BAMBOO_DEBUGPRINT_REG(host);
1129 GC_BAMBOO_DEBUGPRINT_REG(objptr);
1130 // check if this obj has been forwarded
1131 if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
1132 // send a msg to host informing that objptr is active
1133 send_msg_2(host, GCMARKEDOBJ, objptr, false);
1136 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
1138 gc_num_forwardobj++;
1142 #endif // GC_PROFILE
1143 gcself_numsendobjs++;
1144 MGCHashadd(gcforwardobjtbl, (int)objptr);
1149 tprintf("Non shared pointer to be marked %x \n", (int)objptr);
1150 BAMBOO_EXIT(0xb00f);
1152 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1153 gc_enqueue_I(objptr);
1154 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1155 } // if(ISSHAREDOBJ(objptr))
1156 } // void markObj(void * objptr)
1158 // enqueue root objs
1159 inline void tomark(struct garbagelist * stackptr) {
1160 if(MARKPHASE != gcphase) {
1161 GC_BAMBOO_DEBUGPRINT_REG(gcphase);
1162 BAMBOO_EXIT(0xb010);
1164 gcbusystatus = true;
1169 // enqueue current stack
1170 while(stackptr!=NULL) {
1171 GC_BAMBOO_DEBUGPRINT(0xe501);
1172 GC_BAMBOO_DEBUGPRINT_REG(stackptr->size);
1173 GC_BAMBOO_DEBUGPRINT_REG(stackptr->next);
1174 GC_BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
1175 for(i=0; i<stackptr->size; i++) {
1176 if(stackptr->array[i] != NULL) {
1177 markObj(stackptr->array[i]);
1180 stackptr=stackptr->next;
1182 GC_BAMBOO_DEBUGPRINT(0xe502);
1184 // enqueue static pointers global_defs_p
1185 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1186 struct garbagelist * staticptr=(struct garbagelist *)global_defs_p;
1187 while(staticptr != NULL) {
1188 for(i=0; i<staticptr->size; i++) {
1189 if(staticptr->array[i] != NULL) {
1190 markObj(staticptr->array[i]);
1193 staticptr = staticptr->next;
1196 GC_BAMBOO_DEBUGPRINT(0xe503);
1199 // enqueue objectsets
1200 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1201 for(i=0; i<NUMCLASSES; i++) {
1202 struct parameterwrapper ** queues =
1203 objectqueues[BAMBOO_NUM_OF_CORE][i];
1204 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
1205 for(j = 0; j < length; ++j) {
1206 struct parameterwrapper * parameter = queues[j];
1207 struct ObjectHash * set=parameter->objectset;
1208 struct ObjectNode * ptr=set->listhead;
1210 markObj((void *)ptr->key);
1217 // euqueue current task descriptor
1218 if(currtpd != NULL) {
1219 GC_BAMBOO_DEBUGPRINT(0xe504);
1220 for(i=0; i<currtpd->numParameters; i++) {
1221 markObj(currtpd->parameterArray[i]);
1225 GC_BAMBOO_DEBUGPRINT(0xe505);
1226 // euqueue active tasks
1227 if(activetasks != NULL) {
1228 struct genpointerlist * ptr=activetasks->list;
1230 struct taskparamdescriptor *tpd=ptr->src;
1232 for(i=0; i<tpd->numParameters; i++) {
1233 markObj(tpd->parameterArray[i]);
1239 GC_BAMBOO_DEBUGPRINT(0xe506);
1240 // enqueue cached transferred obj
1241 struct QueueItem * tmpobjptr = getHead(&objqueue);
1242 while(tmpobjptr != NULL) {
1243 struct transObjInfo * objInfo =
1244 (struct transObjInfo *)(tmpobjptr->objectptr);
1245 markObj(objInfo->objptr);
1246 tmpobjptr = getNextQueueItem(tmpobjptr);
1249 GC_BAMBOO_DEBUGPRINT(0xe507);
1250 // enqueue cached objs to be transferred
1251 struct QueueItem * item = getHead(totransobjqueue);
1252 while(item != NULL) {
1253 struct transObjInfo * totransobj =
1254 (struct transObjInfo *)(item->objectptr);
1255 markObj(totransobj->objptr);
1256 item = getNextQueueItem(item);
1257 } // while(item != NULL)
1259 GC_BAMBOO_DEBUGPRINT(0xe508);
1260 // enqueue lock related info
1261 for(i = 0; i < runtime_locklen; ++i) {
1262 markObj((void *)(runtime_locks[i].redirectlock));
1263 if(runtime_locks[i].value != NULL) {
1264 markObj((void *)(runtime_locks[i].value));
1267 GC_BAMBOO_DEBUGPRINT(0xe509);
1271 // enqueue global thread queue
1272 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1274 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
1275 if(thread_counter > 0) {
1276 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
1277 for(i = thread_counter; i > 0; i--) {
1278 markObj((void *)bamboo_thread_queue[4+start]);
1279 start = (start+1)&bamboo_max_thread_num_mask;
1284 // enqueue the bamboo_threadlocks
1285 for(i = 0; i < bamboo_threadlocks.index; i++) {
1286 markObj((void *)(bamboo_threadlocks.locks[i].object));
1289 // enqueue the bamboo_current_thread
1290 if(bamboo_current_thread != 0) {
1291 markObj((void *)bamboo_current_thread);
1294 GC_BAMBOO_DEBUGPRINT(0xe50a);
1296 } // void tomark(struct garbagelist * stackptr)
1298 inline void mark(bool isfirst,
1299 struct garbagelist * stackptr) {
1300 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed01);
1302 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed02);
1303 // enqueue root objs
1305 gccurr_heaptop = 0; // record the size of all active objs in this core
1306 // aligned but does not consider block boundaries
1307 gcmarkedptrbound = 0;
1309 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed03);
1310 unsigned int isize = 0;
1311 bool checkfield = true;
1312 bool sendStall = false;
1314 while(MARKPHASE == gcphase) {
1315 if(BAMBOO_NUM_OF_CORE == 0) GC_BAMBOO_DEBUGPRINT(0xed04);
1317 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1318 bool hasItems = gc_moreItems2_I();
1319 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1320 GC_BAMBOO_DEBUGPRINT(0xed05);
1325 gcbusystatus = true;
1327 void * ptr = gc_dequeue2_I();
1329 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1330 unsigned int size = 0;
1331 unsigned int isize = 0;
1332 unsigned int type = 0;
1333 // check if it is a shared obj
1334 if(ISSHAREDOBJ(ptr)) {
1335 // a shared obj, check if it is a local obj on this core
1336 unsigned int host = hostcore(ptr);
1337 bool islocal = (host == BAMBOO_NUM_OF_CORE);
1339 bool isnotmarked = (((int *)ptr)[BAMBOOMARKBIT] == DISCOVERED);
1340 if(isLarge(ptr, &type, &size) && isnotmarked) {
1341 // ptr is a large object and not marked or enqueued
1342 GC_BAMBOO_DEBUGPRINT(0xecec);
1343 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1344 GC_BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
1345 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1346 gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
1348 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1350 ((int *)ptr)[BAMBOOMARKBIT] = MARKED;
1351 BAMBOO_CACHE_FLUSH_LINE(ptr);
1354 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=3;
1356 } else if(isnotmarked) {
1357 // ptr is an unmarked active object on this core
1358 ALIGNSIZE(size, &isize);
1359 gccurr_heaptop += isize;
1360 GC_BAMBOO_DEBUGPRINT(0xaaaa);
1361 GC_BAMBOO_DEBUGPRINT_REG(ptr);
1362 GC_BAMBOO_DEBUGPRINT_REG(isize);
1363 GC_BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
1365 ((int *)ptr)[BAMBOOMARKBIT] = MARKED;
1366 BAMBOO_CACHE_FLUSH_LINE(ptr);
1369 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=2;
1372 if((unsigned int)(ptr + size) > (unsigned int)gcmarkedptrbound) {
1373 gcmarkedptrbound = (unsigned int)(ptr + size);
1374 } // if(ptr + size > gcmarkedptrbound)
1376 // ptr is not an active obj or has been marked
1378 } // if(isLarge(ptr, &type, &size)) else ...
1382 tprintf("Error mark: %x, %d, %d \n", (int)ptr, BAMBOO_NUM_OF_CORE,
1384 BAMBOO_EXIT(0xb011);
1386 #endif /* can never reach here
1388 // check if this obj has been forwarded
1389 if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
1390 // send a msg to host informing that ptr is active
1391 send_msg_2(host, GCMARKEDOBJ, ptr, false);
1392 gcself_numsendobjs++;
1393 MGCHashadd(gcforwardobjtbl, (int)ptr);
1396 }// if(isLocal(ptr)) else ...*/
1397 } // if(ISSHAREDOBJ(ptr))
1398 GC_BAMBOO_DEBUGPRINT(0xed06);
1401 // scan all pointers in ptr
1402 unsigned int * pointer;
1403 pointer=pointerarray[type];
1405 /* Array of primitives */
1407 } else if (((unsigned int)pointer)==1) {
1408 /* Array of pointers */
1409 struct ArrayObject *ao=(struct ArrayObject *) ptr;
1410 int length=ao->___length___;
1412 for(j=0; j<length; j++) {
1414 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
1418 unsigned int size=pointer[0];
1420 for(i=1; i<=size; i++) {
1421 unsigned int offset=pointer[i];
1422 void * objptr=*((void **)(((char *)ptr)+offset));
1425 } // if (pointer==0) else if ... else ...
1427 pointer=pointerarray[OBJECTTYPE];
1428 //handle object class
1429 unsigned int size=pointer[0];
1431 for(i=1; i<=size; i++) {
1432 unsigned int offset=pointer[i];
1433 void * objptr=*((void **)(((char *)ptr)+offset));
1438 } // while(gc_moreItems2())
1439 GC_BAMBOO_DEBUGPRINT(0xed07);
1440 gcbusystatus = false;
1441 // send mark finish msg to core coordinator
1442 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1443 GC_BAMBOO_DEBUGPRINT(0xed08);
1444 int entry_index = 0;
1447 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1450 entry_index = gcnumsrobjs_index;
1452 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
1453 gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
1454 gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numreceiveobjs;
1455 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
1458 GC_BAMBOO_DEBUGPRINT(0xed09);
1459 send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
1460 gcself_numsendobjs, gcself_numreceiveobjs, false);
1463 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
1464 GC_BAMBOO_DEBUGPRINT(0xed0a);
1466 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1467 GC_BAMBOO_DEBUGPRINT(0xed0b);
1470 } // while(MARKPHASE == gcphase)
1475 inline void compact2Heaptophelper_I(unsigned int coren,
1477 unsigned int* numblocks,
1478 unsigned int* remain) {
1480 unsigned int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
1481 if(STARTUPCORE == coren) {
1483 gcmovestartaddr = *p;
1484 gcdstcore = gctopcore;
1485 gcblock2fill = *numblocks + 1;
1487 send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
1489 GC_BAMBOO_DEBUGPRINT_REG(coren);
1490 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1491 GC_BAMBOO_DEBUGPRINT_REG(*p);
1492 GC_BAMBOO_DEBUGPRINT_REG(*numblocks+1);
1493 if(memneed < *remain) {
1494 GC_BAMBOO_DEBUGPRINT(0xd104);
1496 gcrequiredmems[coren] = 0;
1497 gcloads[gctopcore] += memneed;
1498 *remain = *remain - memneed;
1500 GC_BAMBOO_DEBUGPRINT(0xd105);
1501 // next available block
1503 gcfilledblocks[gctopcore] += 1;
1504 unsigned int newbase = 0;
1505 BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
1506 gcloads[gctopcore] = newbase;
1507 gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
1508 gcstopblock[gctopcore]++;
1509 gctopcore = NEXTTOPCORE(gctopblock);
1511 *numblocks = gcstopblock[gctopcore];
1512 *p = gcloads[gctopcore];
1514 *remain=(b<NUMCORES4GC) ?
1515 ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
1516 : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
1517 GC_BAMBOO_DEBUGPRINT(0xd106);
1518 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1519 GC_BAMBOO_DEBUGPRINT_REG(*p);
1520 GC_BAMBOO_DEBUGPRINT_REG(b);
1521 GC_BAMBOO_DEBUGPRINT_REG(*remain);
1522 } // if(memneed < remain)
1524 } // void compact2Heaptophelper_I(int, int*, int*, int*)
1526 inline void compact2Heaptop() {
1527 // no cores with spare mem and some cores are blocked with pending move
1528 // find the current heap top and make them move to the heap top
1530 unsigned int numblocks = gcfilledblocks[gctopcore];
1531 p = gcloads[gctopcore];
1534 unsigned int remain = (b<NUMCORES4GC) ?
1535 ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
1536 : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
1537 // check if the top core finishes
1538 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1539 if(gccorestatus[gctopcore] != 0) {
1540 GC_BAMBOO_DEBUGPRINT(0xd101);
1541 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1542 // let the top core finishes its own work first
1543 compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
1544 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1547 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1549 GC_BAMBOO_DEBUGPRINT(0xd102);
1550 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1551 GC_BAMBOO_DEBUGPRINT_REG(p);
1552 GC_BAMBOO_DEBUGPRINT_REG(b);
1553 GC_BAMBOO_DEBUGPRINT_REG(remain);
1554 for(int i = 0; i < NUMCORES4GC; i++) {
1555 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1556 if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
1557 GC_BAMBOO_DEBUGPRINT(0xd103);
1558 compact2Heaptophelper_I(i, &p, &numblocks, &remain);
1559 if(gccorestatus[gctopcore] != 0) {
1560 GC_BAMBOO_DEBUGPRINT(0xd101);
1561 GC_BAMBOO_DEBUGPRINT_REG(gctopcore);
1562 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1563 // the top core is not free now
1566 } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
1567 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1568 } // for(i = 0; i < NUMCORES4GC; i++)
1569 GC_BAMBOO_DEBUGPRINT(0xd106);
1570 } // void compact2Heaptop()
1572 inline void resolvePendingMoveRequest() {
1573 GC_BAMBOO_DEBUGPRINT(0xeb01);
1574 GC_BAMBOO_DEBUGPRINT(0xeeee);
1575 for(int k = 0; k < NUMCORES4GC; k++) {
1576 GC_BAMBOO_DEBUGPRINT(0xf000+k);
1577 GC_BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
1578 GC_BAMBOO_DEBUGPRINT_REG(gcloads[k]);
1579 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
1580 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
1582 GC_BAMBOO_DEBUGPRINT(0xffff);
1585 bool nosparemem = true;
1586 bool haspending = false;
1587 bool hasrunning = false;
1588 bool noblock = false;
1589 unsigned int dstcore = 0; // the core who need spare mem
1590 unsigned int sourcecore = 0; // the core who has spare mem
1591 for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
1593 // check if there are cores with spare mem
1594 if(gccorestatus[i] == 0) {
1595 // finished working, check if it still have spare mem
1596 if(gcfilledblocks[i] < gcstopblock[i]) {
1597 // still have spare mem
1600 } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
1605 if(gccorestatus[j] != 0) {
1606 // not finished, check if it has pending move requests
1607 if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
1612 } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
1613 } // if(gccorestatus[i] == 0) else ...
1615 } // if(!haspending)
1616 if(!nosparemem && haspending) {
1618 unsigned int tomove = 0;
1619 unsigned int startaddr = 0;
1620 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1621 gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
1622 gcrequiredmems[dstcore],
1625 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1626 GC_BAMBOO_DEBUGPRINT(0xeb02);
1627 GC_BAMBOO_DEBUGPRINT_REG(sourcecore);
1628 GC_BAMBOO_DEBUGPRINT_REG(dstcore);
1629 GC_BAMBOO_DEBUGPRINT_REG(startaddr);
1630 GC_BAMBOO_DEBUGPRINT_REG(tomove);
1631 if(STARTUPCORE == dstcore) {
1632 GC_BAMBOO_DEBUGPRINT(0xeb03);
1633 gcdstcore = sourcecore;
1635 gcmovestartaddr = startaddr;
1636 gcblock2fill = tomove;
1638 GC_BAMBOO_DEBUGPRINT(0xeb04);
1639 send_msg_4(dstcore, GCMOVESTART, sourcecore,
1640 startaddr, tomove, false);
1647 } // for(i = 0; i < NUMCORES4GC; i++)
1648 GC_BAMBOO_DEBUGPRINT(0xcccc);
1649 GC_BAMBOO_DEBUGPRINT_REG(hasrunning);
1650 GC_BAMBOO_DEBUGPRINT_REG(haspending);
1651 GC_BAMBOO_DEBUGPRINT_REG(noblock);
1653 if(!hasrunning && !noblock) {
1654 gcphase = SUBTLECOMPACTPHASE;
1658 } // void resovePendingMoveRequest()
1661 unsigned int numblocks; // block num for heap
1662 unsigned int base; // base virtual address of current heap block
1663 unsigned int ptr; // virtual address of current heap top
1664 unsigned int offset; // offset in current heap block
1665 unsigned int blockbase; // virtual address of current small block to check
1666 unsigned int blockbound; // bound virtual address of current small blcok
1667 unsigned int sblockindex; // index of the small blocks
1668 unsigned int top; // real size of current heap block to check
1669 unsigned int bound; // bound size of current heap block to check
1670 }; // struct moveHelper
1672 // If out of boundary of valid shared memory, return false, else return true
1673 inline bool nextSBlock(struct moveHelper * orig) {
1674 orig->blockbase = orig->blockbound;
1676 bool sbchanged = false;
1677 unsigned int origptr = orig->ptr;
1678 unsigned int blockbase = orig->blockbase;
1679 unsigned int blockbound = orig->blockbound;
1680 unsigned int bound = orig->bound;
1681 GC_BAMBOO_DEBUGPRINT(0xecc0);
1682 GC_BAMBOO_DEBUGPRINT_REG(blockbase);
1683 GC_BAMBOO_DEBUGPRINT_REG(blockbound);
1684 GC_BAMBOO_DEBUGPRINT_REG(bound);
1685 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1687 // check if across a big block
1688 // TODO now do not zero out the whole memory, maybe the last two conditions
1690 if((blockbase>=bound)||(origptr>=bound)
1691 ||((origptr!=NULL)&&(*((int*)origptr))==0)||((*((int*)blockbase))==0)) {
1693 // end of current heap block, jump to next one
1695 GC_BAMBOO_DEBUGPRINT(0xecc1);
1696 GC_BAMBOO_DEBUGPRINT_REG(orig->numblocks);
1697 BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
1698 GC_BAMBOO_DEBUGPRINT(orig->base);
1699 if(orig->base >= gcbaseva + BAMBOO_SHARED_MEM_SIZE) {
1701 orig->ptr = orig->base; // set current ptr to out of boundary too
1704 orig->blockbase = orig->base;
1706 (unsigned int)(orig->blockbase-gcbaseva)/BAMBOO_SMEM_SIZE;
1708 unsigned int blocknum = 0;
1709 BLOCKINDEX(orig->base, &blocknum);
1710 if(bamboo_smemtbl[blocknum] == 0) {
1712 if(blocknum >= gcnumblock) {
1713 BAMBOO_EXIT(0xb012);
1717 goto innernextSBlock;
1719 // check the bamboo_smemtbl to decide the real bound
1720 orig->bound = orig->base + bamboo_smemtbl[blocknum];
1721 } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
1722 orig->sblockindex += 1;
1724 } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
1726 // check if this sblock should be skipped or have special start point
1727 int sbstart = gcsbstarttbl[orig->sblockindex];
1729 if((orig->sblockindex) >= gcsbstarttbl_len) {
1730 BAMBOO_EXIT(0xb013);
1735 GC_BAMBOO_DEBUGPRINT(0xecc2);
1736 orig->sblockindex += 1;
1737 orig->blockbase += BAMBOO_SMEM_SIZE;
1738 goto outernextSBlock;
1739 } else if((sbstart != 0) && (sbchanged)) {
1740 // the first time to access this SBlock
1741 GC_BAMBOO_DEBUGPRINT(0xecc3);
1742 // not start from the very beginning
1743 orig->blockbase = sbstart;
1744 } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
1746 // setup information for this sblock
1747 orig->blockbound = orig->blockbase+(unsigned int)*((int*)(orig->blockbase));
1748 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1749 orig->ptr = orig->blockbase + orig->offset;
1750 GC_BAMBOO_DEBUGPRINT(0xecc4);
1751 GC_BAMBOO_DEBUGPRINT_REG(orig->base);
1752 GC_BAMBOO_DEBUGPRINT_REG(orig->bound);
1753 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
1754 GC_BAMBOO_DEBUGPRINT_REG(orig->blockbound);
1755 GC_BAMBOO_DEBUGPRINT_REG(orig->blockbase);
1756 GC_BAMBOO_DEBUGPRINT_REG(orig->offset);
1757 if(orig->ptr >= orig->bound) {
1758 // met a lobj, move to next block
1759 goto innernextSBlock;
1763 } // bool nextSBlock(struct moveHelper * orig)
1765 // return false if there are no available data to compact
1766 inline bool initOrig_Dst(struct moveHelper * orig,
1767 struct moveHelper * to) {
1770 to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
1771 to->bound = BAMBOO_SMEM_SIZE_L;
1772 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1774 GC_BAMBOO_DEBUGPRINT(0xef01);
1775 GC_BAMBOO_DEBUGPRINT_REG(to->base);
1776 unsigned int tobase = to->base;
1777 to->ptr = tobase + to->offset;
1778 #ifdef GC_CACHE_ADAPT
1779 // initialize the gc_cache_revise_information
1780 gc_cache_revise_infomation.to_page_start_va = to->ptr;
1781 unsigned int toindex = (unsigned int)(tobase-gcbaseva)/(BAMBOO_PAGE_SIZE);
1782 gc_cache_revise_infomation.to_page_end_va = (BAMBOO_PAGE_SIZE)*
1784 gc_cache_revise_infomation.to_page_index = toindex;
1785 gc_cache_revise_infomation.orig_page_start_va = -1;
1786 #endif // GC_CACHE_ADAPT
1788 // init the orig ptr
1789 orig->numblocks = 0;
1790 orig->base = tobase;
1791 unsigned int blocknum = 0;
1792 BLOCKINDEX(orig->base, &blocknum);
1793 unsigned int origbase = orig->base;
1794 // check the bamboo_smemtbl to decide the real bound
1795 orig->bound = origbase + (unsigned int)bamboo_smemtbl[blocknum];
1797 if((orig->sblockindex) >= gcsbstarttbl_len) {
1798 BAMBOO_EXIT(0xb014);
1801 orig->blockbase = origbase;
1802 orig->sblockindex = (unsigned int)(origbase - gcbaseva) / BAMBOO_SMEM_SIZE;
1803 GC_BAMBOO_DEBUGPRINT(0xef02);
1804 GC_BAMBOO_DEBUGPRINT_REG(origbase);
1805 GC_BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
1806 GC_BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
1807 GC_BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
1809 int sbstart = gcsbstarttbl[orig->sblockindex];
1811 if((orig->sblockindex) >= gcsbstarttbl_len) {
1812 BAMBOO_EXIT(0xb015);
1816 GC_BAMBOO_DEBUGPRINT(0xef03);
1819 gcbaseva+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
1820 return nextSBlock(orig);
1821 } else if(sbstart != 0) {
1822 GC_BAMBOO_DEBUGPRINT(0xef04);
1823 orig->blockbase = sbstart;
1825 GC_BAMBOO_DEBUGPRINT(0xef05);
1826 orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
1827 orig->offset = BAMBOO_CACHE_LINE_SIZE;
1828 orig->ptr = orig->blockbase + orig->offset;
1829 GC_BAMBOO_DEBUGPRINT(0xef06);
1830 GC_BAMBOO_DEBUGPRINT_REG(orig->base);
1833 } // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
1835 inline void nextBlock(struct moveHelper * to) {
1836 to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
1837 to->bound += BAMBOO_SMEM_SIZE;
1839 BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
1840 to->offset = BAMBOO_CACHE_LINE_SIZE;
1841 to->ptr = to->base + to->offset;
1842 } // void nextBlock(struct moveHelper * to)
1844 #ifdef GC_CACHE_ADAPT
1845 inline void samplingDataConvert(unsigned int current_ptr) {
1846 unsigned int tmp_factor =
1847 current_ptr-gc_cache_revise_infomation.to_page_start_va;
1848 unsigned int topage=gc_cache_revise_infomation.to_page_index;
1849 unsigned int oldpage = gc_cache_revise_infomation.orig_page_index;
1850 int * newtable=&gccachesamplingtbl_r[topage];
1851 int * oldtable=&gccachesamplingtbl[oldpage];
1853 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
1854 (*newtable) = ((*newtable)+(*oldtable)*tmp_factor);
1855 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
1856 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
1858 } // inline void samplingDataConvert(int)
1860 inline void completePageConvert(struct moveHelper * orig,
1861 struct moveHelper * to,
1862 unsigned int current_ptr,
1864 unsigned int ptr = 0;
1865 unsigned int tocompare = 0;
1868 tocompare = gc_cache_revise_infomation.to_page_end_va;
1871 tocompare = gc_cache_revise_infomation.orig_page_end_va;
1873 if((unsigned int)ptr >= (unsigned int)tocompare) {
1874 // end of an orig/to page
1875 // compute the impact of this page for the new page
1876 samplingDataConvert(current_ptr);
1877 // prepare for an new orig page
1878 unsigned int tmp_index =
1879 (unsigned int)((unsigned int)orig->ptr-gcbaseva)/(BAMBOO_PAGE_SIZE);
1880 gc_cache_revise_infomation.orig_page_start_va = orig->ptr;
1881 gc_cache_revise_infomation.orig_page_end_va = gcbaseva +
1882 (BAMBOO_PAGE_SIZE)*(unsigned int)(tmp_index+1);
1883 gc_cache_revise_infomation.orig_page_index = tmp_index;
1884 gc_cache_revise_infomation.to_page_start_va = to->ptr;
1886 gc_cache_revise_infomation.to_page_end_va = gcbaseva+(BAMBOO_PAGE_SIZE)
1887 *(((unsigned int)(to->ptr)-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
1888 gc_cache_revise_infomation.to_page_index =
1889 ((unsigned int)(to->ptr)-gcbaseva)/(BAMBOO_PAGE_SIZE);
1892 } // inline void completePageConvert(...)
1893 #endif // GC_CACHE_ADAPT
1895 // endaddr does not contain spaces for headers
1896 inline bool moveobj(struct moveHelper * orig,
1897 struct moveHelper * to,
1898 unsigned int stopblock) {
1899 if(stopblock == 0) {
1903 GC_BAMBOO_DEBUGPRINT(0xe201);
1904 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
1905 GC_BAMBOO_DEBUGPRINT_REG(to->ptr);
1907 unsigned int bkptr = (unsigned int)(orig->ptr);
1909 if((unsigned int)(to->ptr) > (unsigned int)(orig->ptr)) {
1910 tprintf("Error to->ptr > orig->ptr: %x, %x \n", (int)(to->ptr), (int)(orig->ptr));
1911 BAMBOO_EXIT(0xb016);
1916 unsigned int size = 0;
1917 unsigned int isize = 0;
1919 /*while((*((char*)(orig->ptr))) == (char)(-2)) {
1920 orig->ptr = (unsigned int)((void*)(orig->ptr) + 1);
1922 #ifdef GC_CACHE_ADAPT
1923 completePageConvert(orig, to, to->ptr, false);
1925 unsigned int origptr = (unsigned int)(orig->ptr);
1926 unsigned int origbound = (unsigned int)orig->bound;
1927 unsigned int origblockbound = (unsigned int)orig->blockbound;
1928 if((origptr >= origbound) || (origptr == origblockbound)) {
1929 if(!nextSBlock(orig)) {
1930 // finished, no more data
1932 tprintf("AAAA %x \n", (int)(orig->ptr));
1938 GC_BAMBOO_DEBUGPRINT(0xe202);
1939 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1940 GC_BAMBOO_DEBUGPRINT(((int *)(origptr))[0]);
1941 // check the obj's type, size and mark flag
1942 type = ((int *)(origptr))[0];
1945 // end of this block, go to next one
1946 if(!nextSBlock(orig)) {
1947 // finished, no more data
1949 tprintf("BBBB %x \n", (int)(orig->ptr));
1954 } else if(type < NUMCLASSES) {
1956 size = classsize[type];
1959 struct ArrayObject *ao=(struct ArrayObject *)(origptr);
1960 unsigned int elementsize=classsize[type];
1961 unsigned int length=ao->___length___;
1962 size=(unsigned int)sizeof(struct ArrayObject)
1963 +(unsigned int)(length*elementsize);
1965 GC_BAMBOO_DEBUGPRINT(0xe203);
1966 GC_BAMBOO_DEBUGPRINT_REG(origptr);
1967 GC_BAMBOO_DEBUGPRINT_REG(size);
1968 ALIGNSIZE(size, &isize); // no matter is the obj marked or not
1969 // should be able to across
1971 int sindex = OBJMAPPINGINDEX((unsigned int)bkptr);
1972 int eindex = OBJMAPPINGINDEX((unsigned int)(origptr));
1973 for(int tmpi = sindex+1; tmpi < eindex; tmpi++) {
1974 if((gcmappingtbl[tmpi] != 0) &&
1975 (hostcore(gcbaseva+bamboo_baseobjsize*tmpi)==BAMBOO_NUM_OF_CORE) &&
1976 (hostcore(gcbaseva+bamboo_baseobjsize*(tmpi+1))==BAMBOO_NUM_OF_CORE)) {
1977 tprintf("Error moveobj --: %x, %x, %x, %d, %x \n", (int)bkptr,
1978 (int)origptr, (int)(gcbaseva+bamboo_baseobjsize*tmpi),
1979 (int)gcmappingtbl[tmpi], (int)(*((char*)(bkptr))));
1980 BAMBOO_EXIT(0xb017);
1984 if(((int *)(origptr))[BAMBOOMARKBIT] == MARKED) {
1985 unsigned int totop = (unsigned int)to->top;
1986 unsigned int tobound = (unsigned int)to->bound;
1987 GC_BAMBOO_DEBUGPRINT(0xe204);
1990 if((STARTUPCORE != BAMBOO_NUM_OF_CORE) || gc_profile_flag) {
1997 // marked obj, copy it to current heap top
1998 // check to see if remaining space is enough
1999 if((unsigned int)(totop + isize) > tobound) {
2000 // fill 0 indicating the end of this block
2001 BAMBOO_MEMSET_WH(to->ptr, '\0', tobound - totop);
2002 // fill the header of this block and then go to next block
2003 to->offset += tobound - totop;
2004 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2005 (*((int*)(to->base))) = to->offset;
2006 #ifdef GC_CACHE_ADAPT
2007 unsigned int tmp_ptr = to->ptr;
2008 #endif // GC_CACHE_ADAPT
2010 #ifdef GC_CACHE_ADAPT
2011 completePageConvert(orig, to, tmp_ptr, true);
2012 #endif // GC_CACHE_ADAPT
2013 if(stopblock == to->numblocks) {
2014 // already fulfilled the block
2016 tprintf("CCCC %x \n", (int)(orig->ptr));
2019 } // if(stopblock == to->numblocks)
2020 } // if(to->top + isize > to->bound)
2021 // set the mark field to 2, indicating that this obj has been moved
2022 // and need to be flushed
2023 ((int *)(origptr))[BAMBOOMARKBIT] = COMPACTED;
2024 unsigned int toptr = (unsigned int)to->ptr;
2027 // scan all pointers in ptr
2028 unsigned int * tt_pointer;
2029 tt_pointer=pointerarray[type];
2030 if (tt_pointer==0) {
2031 /* Array of primitives */
2033 } else if (((unsigned int)tt_pointer)==1) {
2034 /* Array of pointers */
2035 struct ArrayObject *ao=(struct ArrayObject *)(origptr);
2036 int tt_length=ao->___length___;
2038 for(tt_j=0; tt_j<tt_length; tt_j++) {
2040 ((void **)(((char *)&ao->___length___)+sizeof(int)))[tt_j];
2042 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2043 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2044 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2045 (int)origptr, (int)objptr, __LINE__, tt_j,
2046 ((int *)(origptr))[0], ((int *)(objptr))[0],
2047 ((int *)(objptr))[BAMBOOMARKBIT],
2048 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2049 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2050 BAMBOO_EXIT(0xb018);
2054 unsigned int tt_size=tt_pointer[0];
2056 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2057 unsigned int tt_offset=tt_pointer[tt_i];
2058 void * objptr=*((void **)(((char *)origptr)+tt_offset));
2060 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2061 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2062 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2063 (int)origptr, (int)objptr, __LINE__, tt_i,
2064 ((int *)(origptr))[0], ((int *)(objptr))[0],
2065 ((int *)(objptr))[BAMBOOMARKBIT],
2066 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2067 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2068 BAMBOO_EXIT(0xb019);
2071 } // if (pointer==0) else if ... else ...
2073 tt_pointer=pointerarray[OBJECTTYPE];
2074 //handle object class
2075 unsigned int tt_size=tt_pointer[0];
2077 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2078 unsigned int tt_offset=tt_pointer[i];
2079 void * objptr=*((void **)(((char *)origptr)+tt_offset));
2081 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2082 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2083 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2084 (int)origptr, (int)objptr, __LINE__, tt_i,
2085 ((int *)(origptr))[0], ((int *)(objptr))[0],
2086 ((int *)(objptr))[BAMBOOMARKBIT],
2087 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2088 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2089 BAMBOO_EXIT(0xb01a);
2094 if((unsigned int)(toptr) > (unsigned int)(origptr)) {
2095 tprintf("Error to->ptr > orig->ptr: %x, %x \n", (int)(toptr),
2097 BAMBOO_EXIT(0xb01b);
2100 if(toptr != origptr) {
2101 if((unsigned int)(origptr) < (unsigned int)(toptr+size)) {
2102 memmove(toptr, origptr, size);
2104 memcpy(toptr, origptr, size);
2106 // fill the remaining space with -2
2107 BAMBOO_MEMSET_WH((unsigned int)(toptr+size), -2, isize-size);
2110 if((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)] != 2)) {
2111 tprintf("Error moveobj: %x, %x, %d \n", (int)origptr,
2112 ((int *)(origptr))[BAMBOOMARKBIT],
2113 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)]);
2114 BAMBOO_EXIT(0xb01c);
2117 // store mapping info
2118 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)]=(unsigned int)toptr;
2120 if(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)] ==
2121 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)origptr)-1]) {
2122 tprintf("Error moveobj ++ : %x, %x, %d \n", (int)origptr, (int)toptr,
2123 OBJMAPPINGINDEX((unsigned int)origptr));
2124 BAMBOO_EXIT(0xb01d);
2126 // scan all pointers in ptr
2127 unsigned int * tt_pointer;
2128 tt_pointer=pointerarray[type];
2129 if (tt_pointer==0) {
2130 /* Array of primitives */
2132 } else if (((unsigned int)tt_pointer)==1) {
2133 /* Array of pointers */
2134 struct ArrayObject *ao=(struct ArrayObject *)(toptr);
2135 int tt_length=ao->___length___;
2137 for(tt_j=0; tt_j<tt_length; tt_j++) {
2139 ((void **)(((char *)&ao->___length___)+sizeof(int)))[tt_j];
2141 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0)) {
2142 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2143 (int)origptr, (int)objptr, __LINE__, tt_i,
2144 ((int *)(origptr))[0], ((int *)(objptr))[0],
2145 ((int *)(objptr))[BAMBOOMARKBIT],
2146 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2147 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2148 BAMBOO_EXIT(0xb01e);
2152 unsigned int tt_size=tt_pointer[0];
2154 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2155 unsigned int tt_offset=tt_pointer[tt_i];
2156 void * objptr=*((void **)(((char *)toptr)+tt_offset));
2158 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0)) {
2159 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2160 (int)origptr, (int)objptr, __LINE__, tt_i,
2161 ((int *)(origptr))[0], ((int *)(objptr))[0],
2162 ((int *)(objptr))[BAMBOOMARKBIT],
2163 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2164 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2165 BAMBOO_EXIT(0xb01f);
2168 } // if (pointer==0) else if ... else ...
2170 tt_pointer=pointerarray[OBJECTTYPE];
2171 //handle object class
2172 unsigned int tt_size=tt_pointer[0];
2174 for(tt_i=1; tt_i<=tt_size; tt_i++) {
2175 unsigned int tt_offset=tt_pointer[i];
2176 void * objptr=*((void **)(((char *)origptr)+tt_offset));
2178 ((gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 0) ||
2179 (gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)] == 1))) {
2180 tprintf("Error moveobj, missing live obj ++: %x, %x, %d, %d, %d, %d, %d, %d, %d, %d \n",
2181 (int)origptr, (int)objptr, __LINE__, tt_i,
2182 ((int *)(origptr))[0], ((int *)(objptr))[0],
2183 ((int *)(objptr))[BAMBOOMARKBIT],
2184 gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)],
2185 hostcore(objptr), BAMBOO_NUM_OF_CORE);
2186 BAMBOO_EXIT(0xb020);
2190 if(!ISSHAREDOBJ(toptr)) {
2191 tprintf("Error: %x, %x \n", (int)origptr, (int)toptr);
2192 BAMBOO_EXIT(0xb021);
2195 GC_BAMBOO_DEBUGPRINT(0xcdce);
2196 GC_BAMBOO_DEBUGPRINT_REG(origptr);
2197 GC_BAMBOO_DEBUGPRINT_REG(toptr);
2198 GC_BAMBOO_DEBUGPRINT_REG(isize);
2199 gccurr_heaptop -= isize;
2201 to->offset += isize;
2203 #ifdef GC_CACHE_ADAPT
2204 unsigned int tmp_ptr = to->ptr;
2205 #endif // GC_CACHE_ADAPT
2206 if(to->top == to->bound) {
2207 // fill the header of this block and then go to next block
2208 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2209 (*((int*)(to->base))) = to->offset;
2212 #ifdef GC_CACHE_ADAPT
2213 completePageConvert(orig, to, tmp_ptr, true);
2214 #endif // GC_CACHE_ADAPT
2218 // skip the whole obj
2219 int sindex = OBJMAPPINGINDEX((unsigned int)origptr);
2220 int eindex = OBJMAPPINGINDEX((unsigned int)(origptr+size));
2221 for(int tmpi = sindex; tmpi < eindex; tmpi++) {
2222 if((gcmappingtbl[tmpi] != 0) &&
2223 (hostcore(gcbaseva+bamboo_baseobjsize*tmpi)==BAMBOO_NUM_OF_CORE) &&
2224 (hostcore(gcbaseva+bamboo_baseobjsize*(tmpi+1))==BAMBOO_NUM_OF_CORE))
2226 tprintf("Error moveobj **: %x, %x, %x, %d, (%d, %d, %x) \n",
2227 (int)origptr, (int)(origptr+isize),
2228 (int)(gcbaseva+bamboo_baseobjsize*tmpi), gcmappingtbl[tmpi], type,
2229 isize, ((int *)(origptr))[BAMBOOMARKBIT]);
2230 BAMBOO_EXIT(0xb022);
2235 GC_BAMBOO_DEBUGPRINT(0xe205);
2238 orig->ptr += isize; // size;
2241 if(!ISSHAREDOBJ(orig->ptr) || !ISSHAREDOBJ(to->ptr)) {
2242 tprintf("Error moveobj out of boundary: %x, %x, %d, %d \n",
2243 (int)(orig->ptr), (int)(to->ptr), size, isize);
2244 BAMBOO_EXIT(0x2022);
2248 GC_BAMBOO_DEBUGPRINT_REG(isize);
2249 GC_BAMBOO_DEBUGPRINT_REG(size);
2250 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2251 GC_BAMBOO_DEBUGPRINT_REG(orig->bound);
2252 if(((unsigned int)(orig->ptr) > (unsigned int)(orig->bound))
2253 || ((unsigned int)(orig->ptr) == (unsigned int)(orig->blockbound))) {
2254 GC_BAMBOO_DEBUGPRINT(0xe206);
2255 if(!nextSBlock(orig)) {
2256 // finished, no more data
2258 tprintf("DDDD %x \n", (int)(orig->ptr));
2263 GC_BAMBOO_DEBUGPRINT(0xe207);
2264 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2266 } //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
2268 // should be invoked with interrupt closed
2269 inline int assignSpareMem_I(unsigned int sourcecore,
2270 unsigned int * requiredmem,
2271 unsigned int * tomove,
2272 unsigned int * startaddr) {
2274 BLOCKINDEX(gcloads[sourcecore], &b);
2275 unsigned int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
2276 : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
2277 unsigned int remain = boundptr - gcloads[sourcecore];
2278 unsigned int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
2279 *startaddr = gcloads[sourcecore];
2280 *tomove = gcfilledblocks[sourcecore] + 1;
2281 if(memneed < remain) {
2282 gcloads[sourcecore] += memneed;
2285 // next available block
2286 gcfilledblocks[sourcecore] += 1;
2287 unsigned int newbase = 0;
2288 BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
2289 gcloads[sourcecore] = newbase;
2290 return requiredmem-remain;
2292 } // int assignSpareMem_I(int ,int * , int * , int * )
2294 // should be invoked with interrupt closed
2295 inline bool gcfindSpareMem_I(unsigned int * startaddr,
2296 unsigned int * tomove,
2297 unsigned int * dstcore,
2298 unsigned int requiredmem,
2299 unsigned int requiredcore) {
2300 for(int k = 0; k < NUMCORES4GC; k++) {
2301 if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
2302 // check if this stopped core has enough mem
2303 assignSpareMem_I(k, requiredmem, tomove, startaddr);
2308 // if can not find spare mem right now, hold the request
2309 gcrequiredmems[requiredcore] = requiredmem;
2312 } //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
2314 inline bool compacthelper(struct moveHelper * orig,
2315 struct moveHelper * to,
2317 unsigned int * heaptopptr,
2318 bool * localcompact) {
2319 // scan over all objs in this block, compact the marked objs
2320 // loop stop when finishing either scanning all active objs or
2321 // fulfilled the gcstopblock
2322 GC_BAMBOO_DEBUGPRINT(0xe101);
2323 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
2324 GC_BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2326 while((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2327 bool stop = moveobj(orig, to, gcblock2fill);
2333 tprintf("finish mark %x \n", (int)gcmarkedptrbound);
2335 #ifdef GC_CACHE_ADAPT
2336 // end of an to page, wrap up its information
2337 samplingDataConvert(to->ptr);
2338 #endif // GC_CACHE_ADAPT
2339 // if no objs have been compact, do nothing,
2340 // otherwise, fill the header of this block
2341 if(to->offset > (unsigned int)BAMBOO_CACHE_LINE_SIZE) {
2342 BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
2343 (*((int*)(to->base))) = to->offset;
2347 to->top -= BAMBOO_CACHE_LINE_SIZE;
2348 } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
2350 *heaptopptr = to->ptr;
2351 *filledblocks = to->numblocks;
2353 GC_BAMBOO_DEBUGPRINT(0xe102);
2354 GC_BAMBOO_DEBUGPRINT_REG(orig->ptr);
2355 GC_BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
2356 GC_BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2357 GC_BAMBOO_DEBUGPRINT_REG(*filledblocks);
2358 GC_BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
2360 // send msgs to core coordinator indicating that the compact is finishing
2361 // send compact finish message to core coordinator
2362 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2363 gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
2364 gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
2365 if((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2366 GC_BAMBOO_DEBUGPRINT(0xe103);
2369 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2370 if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
2371 gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
2372 GC_BAMBOO_DEBUGPRINT(0xe104);
2375 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2376 GC_BAMBOO_DEBUGPRINT(0xe105);
2379 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2381 GC_BAMBOO_DEBUGPRINT(0xe106);
2382 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2387 if((unsigned int)(orig->ptr) < (unsigned int)gcmarkedptrbound) {
2388 GC_BAMBOO_DEBUGPRINT(0xe107);
2391 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2392 *filledblocks, *heaptopptr, gccurr_heaptop, false);
2394 GC_BAMBOO_DEBUGPRINT(0xe108);
2395 GC_BAMBOO_DEBUGPRINT_REG(*heaptopptr);
2396 // finish compacting
2397 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2398 *filledblocks, *heaptopptr, 0, false);
2400 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
2402 if(orig->ptr < gcmarkedptrbound) {
2403 GC_BAMBOO_DEBUGPRINT(0xe109);
2404 // still have unpacked obj
2412 GC_BAMBOO_DEBUGPRINT(0xe10a);
2414 to->ptr = gcmovestartaddr;
2415 to->numblocks = gcblock2fill - 1;
2416 to->bound = (to->numblocks==0) ?
2417 BAMBOO_SMEM_SIZE_L :
2418 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
2419 BASEPTR(gcdstcore, to->numblocks, &(to->base));
2420 to->offset = to->ptr - to->base;
2421 to->top = (to->numblocks==0) ?
2422 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
2424 to->offset = BAMBOO_CACHE_LINE_SIZE;
2425 to->ptr += to->offset; // for header
2426 to->top += to->offset;
2427 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
2428 *localcompact = true;
2430 *localcompact = false;
2432 #ifdef GC_CACHE_ADAPT
2433 // initialize the gc_cache_revise_information
2434 gc_cache_revise_infomation.to_page_start_va = (unsigned int)to->ptr;
2435 gc_cache_revise_infomation.to_page_end_va = gcbaseva+(BAMBOO_PAGE_SIZE)
2436 *(((unsigned int)(to->base)-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2437 gc_cache_revise_infomation.to_page_index =
2438 ((unsigned int)(to->base)-gcbaseva)/(BAMBOO_PAGE_SIZE);
2439 gc_cache_revise_infomation.orig_page_start_va = orig->ptr;
2440 gc_cache_revise_infomation.orig_page_end_va = gcbaseva+(BAMBOO_PAGE_SIZE)
2441 *(((unsigned int)(orig->ptr)-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2442 gc_cache_revise_infomation.orig_page_index =
2443 ((unsigned int)(orig->blockbase)-gcbaseva)/(BAMBOO_PAGE_SIZE);
2444 #endif // GC_CACHE_ADAPT
2447 GC_BAMBOO_DEBUGPRINT(0xe10b);
2449 } // void compacthelper()
2451 inline void compact() {
2452 if(COMPACTPHASE != gcphase) {
2453 BAMBOO_EXIT(0xb023);
2456 // initialize pointers for comapcting
2457 struct moveHelper * orig =
2458 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2459 struct moveHelper * to =
2460 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
2461 if(!initOrig_Dst(orig, to)) {
2462 // no available data to compact
2463 // send compact finish msg to STARTUP core
2464 GC_BAMBOO_DEBUGPRINT(0xe001);
2465 GC_BAMBOO_DEBUGPRINT_REG(to->base);
2466 send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
2467 0, to->base, 0, false);
2472 #ifdef GC_CACHE_ADAPT
2473 gc_cache_revise_infomation.orig_page_start_va = (unsigned int)orig->ptr;
2474 gc_cache_revise_infomation.orig_page_end_va = gcbaseva+(BAMBOO_PAGE_SIZE)
2475 *(((unsigned int)(orig->ptr)-gcbaseva)/(BAMBOO_PAGE_SIZE)+1);
2476 gc_cache_revise_infomation.orig_page_index =
2477 ((unsigned int)(orig->blockbase)-gcbaseva)/(BAMBOO_PAGE_SIZE);
2478 #endif // GC_CACHE_ADAPT
2480 unsigned int filledblocks = 0;
2481 unsigned int heaptopptr = 0;
2482 bool localcompact = true;
2483 compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
2488 // if return NULL, means
2489 // 1. objptr is NULL
2490 // 2. objptr is not a shared obj
2491 // in these cases, remain the original value is OK
2493 inline void * flushObj(void * objptr, int linenum, void * ptr, int tt) {
2495 inline void * flushObj(void * objptr) {
2497 GC_BAMBOO_DEBUGPRINT(0xe401);
2498 if(objptr == NULL) {
2501 void * dstptr = NULL;
2502 if(ISSHAREDOBJ(objptr)) {
2503 GC_BAMBOO_DEBUGPRINT(0xe402);
2504 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2505 // a shared obj ptr, change to new address
2506 dstptr = gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)];
2507 GC_BAMBOO_DEBUGPRINT_REG(dstptr);
2509 if(ISSHAREDOBJ(dstptr) && ((unsigned int)(((int*)dstptr)[0]) >= (unsigned int)NUMTYPES)) {
2510 tprintf("Error flushObj ** : %x, %x, %d, %d, %d, %d, %x, %x, %x, %d, %x, %d %d \n",
2511 (int)objptr, (int)dstptr, ((int*)dstptr)[0], hostcore(objptr),
2512 hostcore(objptr)==BAMBOO_NUM_OF_CORE,
2513 OBJMAPPINGINDEX((unsigned int)objptr), (int)gcmappingtbl,
2514 &(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]),
2515 (int)gcbaseva, linenum, (int)ptr, ((int*)ptr)[0], tt);
2516 BAMBOO_EXIT(0xb024);
2520 if(!ISSHAREDOBJ(dstptr)) {
2522 tprintf("Error flushObj ++ : %x, %x, %d, %d, %d, %x, %x, %x, %d, %x, %d %d \n",
2523 (int)objptr, (int)dstptr, 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 tprintf("gcmappingtbl: \n");
2529 int tmp = OBJMAPPINGINDEX((unsigned int)objptr) - 50;
2530 for(int jj = 0; jj < 100; jj+=10) {
2531 tprintf("%8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %8x, %d \n",
2532 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2533 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2534 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2535 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++],
2536 (int)gcmappingtbl[tmp++], (int)gcmappingtbl[tmp++], tmp);
2538 BAMBOO_EXIT(0xb025);
2541 GC_BAMBOO_DEBUGPRINT(0xe403);
2542 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2543 GC_BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
2544 // error! the obj is right on this core, but cannot find it
2545 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2546 tprintf("Error flushObj ++ : %x, %x, %d, %d, %x, %x, %x, %x\n",
2547 (int)objptr, (int)dstptr, hostcore(objptr),
2548 hostcore(objptr)==BAMBOO_NUM_OF_CORE,
2549 OBJMAPPINGINDEX((unsigned int)objptr), (int)gcmappingtbl,
2550 &(gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)]),
2552 BAMBOO_EXIT(0xb026);
2554 } // if(NULL == dstptr)
2555 } // if(ISSHAREDOBJ(objptr))
2558 tprintf("Error flushObj: %x \n", (int)objptr);
2559 BAMBOO_EXIT(0xb027);
2562 // if not a shared obj, return NULL to indicate no need to flush
2563 GC_BAMBOO_DEBUGPRINT(0xe404);
2565 } // void flushObj(void * objptr)
2567 inline void flushRuntimeObj(struct garbagelist * stackptr) {
2569 // flush current stack
2570 while(stackptr!=NULL) {
2571 for(i=0; i<stackptr->size; i++) {
2572 if(stackptr->array[i] != NULL) {
2574 void * dst = flushObj(stackptr->array[i],
2575 __LINE__, stackptr->array[i], i);
2577 void * dst = flushObj(stackptr->array[i]);
2580 stackptr->array[i] = dst;
2584 stackptr=stackptr->next;
2587 // flush static pointers global_defs_p
2588 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2589 struct garbagelist * staticptr=(struct garbagelist *)global_defs_p;
2590 for(i=0; i<staticptr->size; i++) {
2591 if(staticptr->array[i] != NULL) {
2593 void * dst = flushObj(staticptr->array[i],
2594 __LINE__, staticptr->array[i], i);
2596 void * dst = flushObj(staticptr->array[i]);
2599 staticptr->array[i] = dst;
2607 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
2608 for(i=0; i<NUMCLASSES; i++) {
2609 struct parameterwrapper ** queues =
2610 objectqueues[BAMBOO_NUM_OF_CORE][i];
2611 int length = numqueues[BAMBOO_NUM_OF_CORE][i];
2612 for(j = 0; j < length; ++j) {
2613 struct parameterwrapper * parameter = queues[j];
2614 struct ObjectHash * set=parameter->objectset;
2615 struct ObjectNode * ptr=set->listhead;
2618 void * dst = flushObj((void *)ptr->key,
2619 __LINE__, (void *)ptr->key, 0);
2621 void * dst = flushObj((void *)ptr->key);
2628 ObjectHashrehash(set);
2633 // flush current task descriptor
2634 if(currtpd != NULL) {
2635 for(i=0; i<currtpd->numParameters; i++) {
2637 void * dst = flushObj(currtpd->parameterArray[i],
2638 __LINE__, currtpd->parameterArray[i], i);
2640 void * dst = flushObj(currtpd->parameterArray[i]);
2643 currtpd->parameterArray[i] = dst;
2648 // flush active tasks
2649 if(activetasks != NULL) {
2650 struct genpointerlist * ptr=activetasks->list;
2652 struct taskparamdescriptor *tpd=ptr->src;
2654 for(i=0; i<tpd->numParameters; i++) {
2656 void * dst = flushObj(tpd->parameterArray[i],
2657 __LINE__, tpd->parameterArray[i], i);
2659 void * dst = flushObj(tpd->parameterArray[i]);
2662 tpd->parameterArray[i] = dst;
2667 genrehash(activetasks);
2670 // flush cached transferred obj
2671 struct QueueItem * tmpobjptr = getHead(&objqueue);
2672 while(tmpobjptr != NULL) {
2673 struct transObjInfo * objInfo =
2674 (struct transObjInfo *)(tmpobjptr->objectptr);
2676 void * dst = flushObj(objInfo->objptr, __LINE__,
2677 objInfo->objptr, 0);
2679 void * dst = flushObj(objInfo->objptr);
2682 objInfo->objptr = dst;
2684 tmpobjptr = getNextQueueItem(tmpobjptr);
2687 // flush cached objs to be transferred
2688 struct QueueItem * item = getHead(totransobjqueue);
2689 while(item != NULL) {
2690 struct transObjInfo * totransobj =
2691 (struct transObjInfo *)(item->objectptr);
2693 void * dst = flushObj(totransobj->objptr, __LINE__,
2694 totransobj->objptr, 0);
2696 void * dst = flushObj(totransobj->objptr);
2699 totransobj->objptr = dst;
2701 item = getNextQueueItem(item);
2702 } // while(item != NULL)
2704 // enqueue lock related info
2705 for(i = 0; i < runtime_locklen; ++i) {
2707 void * dst = flushObj(runtime_locks[i].redirectlock,
2708 __LINE__, runtime_locks[i].redirectlock, i);
2710 void * dst = flushObj(runtime_locks[i].redirectlock);
2713 runtime_locks[i].redirectlock = (int)dst;
2715 if(runtime_locks[i].value != NULL) {
2717 void * dst=flushObj(runtime_locks[i].value,
2718 __LINE__, runtime_locks[i].value, i);
2720 void * dst=flushObj(runtime_locks[i].value);
2723 runtime_locks[i].value = (int)dst;
2730 // flush the bamboo_threadlocks
2731 for(i = 0; i < bamboo_threadlocks.index; i++) {
2733 void * dst = flushObj((void *)(bamboo_threadlocks.locks[i].object),
2734 __LINE__, (void *)(bamboo_threadlocks.locks[i].object), i);
2736 void * dst = flushObj((void *)(bamboo_threadlocks.locks[i].object));
2739 bamboo_threadlocks.locks[i].object = (struct ___Object___ *)dst;
2743 // flush the bamboo_current_thread
2744 if(bamboo_current_thread != 0) {
2746 bamboo_current_thread =
2747 (unsigned int)(flushObj((void *)bamboo_current_thread,
2748 __LINE__, (void *)bamboo_current_thread, 0));
2750 bamboo_current_thread =
2751 (unsigned int)(flushObj((void *)bamboo_current_thread));
2755 // flush global thread queue
2756 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2757 unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
2758 if(thread_counter > 0) {
2759 unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
2760 for(i = thread_counter; i > 0; i--) {
2762 bamboo_thread_queue[4+start] =
2763 (INTPTR)(flushObj((void *)bamboo_thread_queue[4+start
2764 ], __LINE__, (void *)bamboo_thread_queue, 0));
2766 bamboo_thread_queue[4+start] =
2767 (INTPTR)(flushObj((void *)bamboo_thread_queue[4+start]));
2769 start = (start+1)&bamboo_max_thread_num_mask;
2772 unlockthreadqueue();
2775 } // void flushRuntimeObj(struct garbagelist * stackptr)
2777 inline void flush(struct garbagelist * stackptr) {
2779 flushRuntimeObj(stackptr);
2782 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2783 bool hasItems = gc_moreItems_I();
2784 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2789 GC_BAMBOO_DEBUGPRINT(0xe301);
2790 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2791 void * ptr = gc_dequeue_I();
2793 unsigned int bkptr = (unsigned int)ptr;
2795 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2796 if(ISSHAREDOBJ(ptr)) {
2797 // should be a local shared obj and should have mapping info
2799 ptr = flushObj(ptr, __LINE__, ptr, 0);
2801 ptr = flushObj(ptr);
2803 GC_BAMBOO_DEBUGPRINT(0xe302);
2804 GC_BAMBOO_DEBUGPRINT_REG(ptr);
2806 BAMBOO_EXIT(0xb028);
2808 } // if(ISSHAREDOBJ(ptr))
2809 if((!ISSHAREDOBJ(ptr))||(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED)) {
2810 int type = ((int *)(ptr))[0];
2812 if((unsigned int)type >= (unsigned int)NUMTYPES) {
2813 tprintf("Error flushObj %x, %x, %d, %d \n", bkptr, (int)ptr, type,
2814 ((int *)(ptr))[BAMBOOMARKBIT]);
2815 BAMBOO_EXIT(0xb029);
2818 // scan all pointers in ptr
2819 unsigned int * pointer;
2820 pointer=pointerarray[type];
2821 GC_BAMBOO_DEBUGPRINT(0xe303);
2822 GC_BAMBOO_DEBUGPRINT_REG(pointer);
2824 /* Array of primitives */
2826 } else if (((unsigned int)pointer)==1) {
2827 GC_BAMBOO_DEBUGPRINT(0xe304);
2828 /* Array of pointers */
2829 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2830 int length=ao->___length___;
2832 for(j=0; j<length; j++) {
2833 GC_BAMBOO_DEBUGPRINT(0xe305);
2835 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2836 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2837 if(objptr != NULL) {
2839 void * dst = flushObj(objptr, __LINE__, ptr, j);
2841 void * dst = flushObj(objptr);
2844 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2849 GC_BAMBOO_DEBUGPRINT(0xe306);
2850 unsigned int size=pointer[0];
2852 for(i=1; i<=size; i++) {
2853 GC_BAMBOO_DEBUGPRINT(0xe307);
2854 unsigned int offset=pointer[i];
2855 void * objptr=*((void **)(((char *)ptr)+offset));
2856 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2857 if(objptr != NULL) {
2859 void * dst = flushObj(objptr, __LINE__, ptr, i);
2861 void * dst = flushObj(objptr);
2864 *((void **)(((char *)ptr)+offset)) = dst;
2867 } // for(i=1; i<=size; i++)
2868 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2870 pointer=pointerarray[OBJECTTYPE];
2871 //handle object class
2872 unsigned int size=pointer[0];
2874 for(i=1; i<=size; i++) {
2875 unsigned int offset=pointer[i];
2876 void * objptr=*((void **)(((char *)ptr)+offset));
2877 if(objptr != NULL) {
2879 void * dst = flushObj(objptr, __LINE__, ptr, i);
2881 void * dst = flushObj(objptr);
2884 *((void **)(((char *)ptr)+offset)) = dst;
2889 // restore the mark field, indicating that this obj has been flushed
2890 if(ISSHAREDOBJ(ptr)) {
2891 ((int *)(ptr))[BAMBOOMARKBIT] = INIT;
2893 } //if((!ISSHAREDOBJ(ptr))||(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED))
2894 } // while(gc_moreItems())
2895 GC_BAMBOO_DEBUGPRINT(0xe308);
2897 // TODO bug here: the startup core contains all lobjs' info, thus all the
2898 // lobjs are flushed in sequence.
2900 while(gc_lobjmoreItems_I()) {
2901 GC_BAMBOO_DEBUGPRINT(0xe309);
2902 void * ptr = gc_lobjdequeue_I(NULL, NULL);
2904 ptr = flushObj(ptr, __LINE__, ptr, 0);
2906 ptr = flushObj(ptr);
2908 GC_BAMBOO_DEBUGPRINT(0xe30a);
2909 GC_BAMBOO_DEBUGPRINT_REG(ptr);
2910 GC_BAMBOO_DEBUGPRINT_REG(tptr);
2911 GC_BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
2913 BAMBOO_EXIT(0xb02a);
2915 if(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED) {
2916 int type = ((int *)(ptr))[0];
2917 // scan all pointers in ptr
2918 unsigned int * pointer;
2919 pointer=pointerarray[type];
2920 GC_BAMBOO_DEBUGPRINT(0xe30b);
2921 GC_BAMBOO_DEBUGPRINT_REG(pointer);
2923 /* Array of primitives */
2925 } else if (((unsigned int)pointer)==1) {
2926 GC_BAMBOO_DEBUGPRINT(0xe30c);
2927 /* Array of pointers */
2928 struct ArrayObject *ao=(struct ArrayObject *) ptr;
2929 int length=ao->___length___;
2931 for(j=0; j<length; j++) {
2932 GC_BAMBOO_DEBUGPRINT(0xe30d);
2934 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
2935 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2936 if(objptr != NULL) {
2938 void * dst = flushObj(objptr, __LINE__, ptr, j);
2940 void * dst = flushObj(objptr);
2943 ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
2948 GC_BAMBOO_DEBUGPRINT(0xe30e);
2949 unsigned int size=pointer[0];
2951 for(i=1; i<=size; i++) {
2952 GC_BAMBOO_DEBUGPRINT(0xe30f);
2953 unsigned int offset=pointer[i];
2954 void * objptr=*((void **)(((char *)ptr)+offset));
2956 GC_BAMBOO_DEBUGPRINT_REG(objptr);
2957 if(objptr != NULL) {
2959 void * dst = flushObj(objptr, __LINE__, ptr, i);
2961 void * dst = flushObj(objptr);
2964 *((void **)(((char *)ptr)+offset)) = dst;
2967 } // for(i=1; i<=size; i++)
2968 } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
2970 pointer=pointerarray[OBJECTTYPE];
2971 //handle object class
2972 unsigned int size=pointer[0];
2974 for(i=1; i<=size; i++) {
2975 unsigned int offset=pointer[i];
2976 void * objptr=*((void **)(((char *)ptr)+offset));
2977 if(objptr != NULL) {
2979 void * dst = flushObj(objptr, __LINE__, ptr, i);
2981 void * dst = flushObj(objptr);
2984 *((void **)(((char *)ptr)+offset)) = dst;
2989 // restore the mark field, indicating that this obj has been flushed
2990 ((int *)(ptr))[BAMBOOMARKBIT] = INIT;
2991 } // if(((int *)(ptr))[BAMBOOMARKBIT] == COMPACTED)
2992 } // while(gc_lobjmoreItems())
2993 GC_BAMBOO_DEBUGPRINT(0xe310);
2995 // send flush finish message to core coordinator
2996 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2997 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
2999 send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
3001 GC_BAMBOO_DEBUGPRINT(0xe311);
3004 #ifdef GC_CACHE_ADAPT
3005 // prepare for cache adaption:
3006 // -- flush the shared heap
3007 // -- clean dtlb entries
3008 // -- change cache strategy
3009 void cacheAdapt_gc(bool isgccachestage) {
3010 // flush the shared heap
3011 BAMBOO_CACHE_FLUSH_L2();
3013 // clean the dtlb entries
3014 BAMBOO_CLEAN_DTLB();
3016 // change the cache strategy
3017 gccachestage = isgccachestage;
3018 } // cacheAdapt_gc(bool isgccachestage)
3020 // the master core decides how to adapt cache strategy for the mutator
3021 // according to collected statistic data
3023 // make all pages hfh
3024 int cacheAdapt_policy_h4h(){
3025 unsigned int page_index = 0;
3027 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3028 unsigned int numchanged = 0;
3029 int * tmp_p = gccachepolicytbl+1;
3030 for(page_index = 0; page_index < page_num; page_index++) {
3031 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3032 bamboo_cache_policy_t policy = {0};
3033 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3034 *tmp_p = page_index;
3036 *tmp_p = policy.word;
3042 } // int cacheAdapt_policy_hfh()
3044 // make all pages local as non-cache-adaptable gc local mode
3045 int cacheAdapt_policy_local(){
3046 unsigned int page_index = 0;
3048 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3049 unsigned int numchanged = 0;
3050 int * tmp_p = gccachepolicytbl+1;
3051 for(page_index = 0; page_index < page_num; page_index++) {
3052 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3053 bamboo_cache_policy_t policy = {0};
3054 unsigned int block = 0;
3055 BLOCKINDEX(page_sva, &block);
3056 unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
3057 // locally cache the page in the hotest core
3058 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3059 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3060 policy.lotar_x = bamboo_cpu2coords[2*coren]+1;
3061 policy.lotar_y = bamboo_cpu2coords[2*coren+1]+1;
3062 *tmp_p = page_index;
3064 *tmp_p = policy.word;
3070 } // int cacheAdapt_policy_local()
3072 int cacheAdapt_policy_hotest(){
3073 unsigned int page_index = 0;
3075 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3076 unsigned int numchanged = 0;
3077 int * tmp_p = gccachepolicytbl+1;
3078 for(page_index = 0; page_index < page_num; page_index++) {
3079 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3080 bamboo_cache_policy_t policy = {0};
3081 unsigned int hotestcore = 0;
3082 unsigned int hotfreq = 0;
3084 int *local_tbl=&gccachesamplingtbl_r[page_index];
3085 for(int i = 0; i < NUMCORESACTIVE; i++) {
3086 int freq = *local_tbl;
3087 local_tbl=(int *)(((char *)local_tbl)+size_cachesamplingtbl_local_r);
3089 // check the freqency, decide if this page is hot for the core
3090 if(hotfreq < freq) {
3096 // Decide the cache strategy for this page
3097 // If decide to adapt a new cache strategy, write into the shared block of
3098 // the gcsharedsamplingtbl. The mem recording information that has been
3099 // written is enough to hold the information.
3100 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3102 // this page has not been accessed, do not change its cache policy
3105 // locally cache the page in the hotest core
3106 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3107 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3108 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3109 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3110 *tmp_p = page_index;
3112 *tmp_p = policy.word;
3119 } // int cacheAdapt_policy_hotest()
3121 #define GC_CACHE_ADAPT_DOMINATE_THRESHOLD 50
3122 // cache the page on the core that accesses it the most if that core accesses
3123 // it more than (GC_CACHE_ADAPT_DOMINATE_THRESHOLD)% of the total. Otherwise,
3125 int cacheAdapt_policy_dominate(){
3126 unsigned int page_index = 0;
3128 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3129 unsigned int numchanged = 0;
3130 int * tmp_p = gccachepolicytbl+1;
3131 for(page_index = 0; page_index < page_num; page_index++) {
3132 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3133 bamboo_cache_policy_t policy = {0};
3134 unsigned int hotestcore = 0;
3135 unsigned long long totalfreq = 0;
3136 unsigned int hotfreq = 0;
3138 int *local_tbl=&gccachesamplingtbl_r[page_index];
3139 for(int i = 0; i < NUMCORESACTIVE; i++) {
3140 int freq = *local_tbl;
3141 local_tbl=(int *)(((char *)local_tbl)+size_cachesamplingtbl_local_r);
3143 // check the freqency, decide if this page is hot for the core
3144 if(hotfreq < freq) {
3150 // Decide the cache strategy for this page
3151 // If decide to adapt a new cache strategy, write into the shared block of
3153 // Format: page start va + cache policy
3155 // this page has not been accessed, do not change its cache policy
3159 (totalfreq*GC_CACHE_ADAPT_DOMINATE_THRESHOLD)/100/BAMBOO_PAGE_SIZE;
3160 hotfreq/=BAMBOO_PAGE_SIZE;
3161 if(hotfreq < totalfreq) {
3163 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3165 // locally cache the page in the hotest core
3166 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3167 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3168 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3169 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3171 *tmp_p = page_index;
3173 *tmp_p = policy.word;
3179 } // int cacheAdapt_policy_dominate()
3181 #define GC_CACHE_ADAPT_OVERLOAD_THRESHOLD 10
3183 void gc_quicksort(unsigned long long *array,
3186 unsigned int offset) {
3187 unsigned int pivot = 0;;
3188 unsigned int leftIdx = left;
3189 unsigned int rightIdx = right;
3190 if((right-left+1) >= 1) {
3191 pivot = (left+right)/2;
3192 while((leftIdx <= pivot) && (rightIdx >= pivot)) {
3193 unsigned long long pivotValue = array[pivot*3-offset];
3194 while((array[leftIdx*3-offset] > pivotValue) && (leftIdx <= pivot)) {
3197 while((array[rightIdx*3-offset] < pivotValue) && (rightIdx >= pivot)) {
3200 // swap [leftIdx] & [rightIdx]
3201 for(int k = 0; k < 3; k++) {
3202 unsigned long long tmp = array[3*rightIdx-k];
3203 array[3*rightIdx-k] = array[3*leftIdx-k];
3204 array[3*leftIdx-k] = tmp;
3208 if((leftIdx-1) == pivot) {
3209 pivot = rightIdx = rightIdx + 1;
3210 } else if((leftIdx+1) == pivot) {
3211 pivot = leftIdx = leftIdx-1;
3214 gc_quicksort(array, left, pivot-1, offset);
3215 gc_quicksort(array, pivot+1, right, offset);
3218 } // void gc_quicksort(...)
3220 // Every page cached on the core that accesses it the most.
3221 // Check to see if any core's pages total more accesses than threshold
3222 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD. If so, find the pages with the
3223 // most remote accesses and hash for home them until we get below
3224 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD
3225 int cacheAdapt_policy_overload(){
3226 unsigned int page_index = 0;
3228 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3229 unsigned int numchanged = 0;
3230 int * tmp_p = gccachepolicytbl+1;
3231 unsigned long long workload[NUMCORESACTIVE];
3232 memset(workload, 0, NUMCORESACTIVE*sizeof(unsigned long long));
3233 unsigned long long total_workload = 0;
3234 unsigned long long core2heavypages[NUMCORESACTIVE][page_num*3+1];
3235 memset(core2heavypages,0,
3236 sizeof(unsigned long long)*(page_num*3+1)*NUMCORESACTIVE);
3237 for(page_index = 0; page_index < page_num; page_index++) {
3238 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3239 bamboo_cache_policy_t policy = {0};
3240 unsigned int hotestcore = 0;
3241 unsigned long long totalfreq = 0;
3242 unsigned int hotfreq = 0;
3244 int *local_tbl=&gccachesamplingtbl_r[page_index];
3245 for(int i = 0; i < NUMCORESACTIVE; i++) {
3246 int freq = *local_tbl;
3247 local_tbl=(int *)(((char *)local_tbl)+size_cachesamplingtbl_local_r);
3249 // check the freqency, decide if this page is hot for the core
3250 if(hotfreq < freq) {
3255 // Decide the cache strategy for this page
3256 // If decide to adapt a new cache strategy, write into the shared block of
3257 // the gcsharedsamplingtbl. The mem recording information that has been
3258 // written is enough to hold the information.
3259 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3261 // this page has not been accessed, do not change its cache policy
3265 totalfreq/=BAMBOO_PAGE_SIZE;
3266 hotfreq/=BAMBOO_PAGE_SIZE;
3267 // locally cache the page in the hotest core
3268 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3269 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3270 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3271 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3272 *tmp_p = page_index;
3274 *tmp_p = policy.word;
3277 workload[hotestcore] += totalfreq;
3278 total_workload += totalfreq;
3279 // insert into core2heavypages using quicksort
3280 unsigned long long remoteaccess = totalfreq - hotfreq;
3281 unsigned int index = (unsigned int)core2heavypages[hotestcore][0];
3282 core2heavypages[hotestcore][3*index+3] = remoteaccess;
3283 core2heavypages[hotestcore][3*index+2] = totalfreq;
3284 core2heavypages[hotestcore][3*index+1] = (unsigned long long)(tmp_p-1);
3285 core2heavypages[hotestcore][0]++;
3288 unsigned long long workload_threshold =
3289 total_workload/GC_CACHE_ADAPT_OVERLOAD_THRESHOLD;
3290 // Check the workload of each core
3291 for(int i = 0; i < NUMCORESACTIVE; i++) {
3293 unsigned int index = (unsigned int)core2heavypages[i][0];
3294 if(workload[i] > workload_threshold) {
3295 // sort according to the remoteaccess
3296 gc_quicksort(&core2heavypages[i][0], 1, index, 0);
3297 while((workload[i] > workload_threshold) && (j<index*3)) {
3298 // hfh those pages with more remote accesses
3299 bamboo_cache_policy_t policy = {0};
3300 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3301 *((unsigned int*)core2heavypages[i][j]) = policy.word;
3302 workload[i] -= core2heavypages[i][j+1];
3309 } // int cacheAdapt_policy_overload()
3311 #define GC_CACHE_ADAPT_ACCESS_THRESHOLD 70
3312 #define GC_CACHE_ADAPT_CROWD_THRESHOLD 20
3313 // Every page cached on the core that accesses it the most.
3314 // Check to see if any core's pages total more accesses than threshold
3315 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD. If so, find the pages with the
3316 // most remote accesses and hash for home them until we get below
3317 // GC_CACHE_ADAPT_OVERLOAD_THRESHOLD.
3318 // Sort pages based on activity....
3319 // If more then GC_CACHE_ADAPT_ACCESS_THRESHOLD% of the accesses for a
3320 // core's pages are from more than GC_CACHE_ADAPT_CROWD_THRESHOLD pages,
3321 // then start hfh these pages(selecting the ones with the most remote
3322 // accesses first or fewest local accesses) until we get below
3323 // GC_CACHE_ADAPT_CROWD_THRESHOLD pages.
3324 int cacheAdapt_policy_crowd(){
3325 unsigned int page_index = 0;
3327 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3328 unsigned int numchanged = 0;
3329 int * tmp_p = gccachepolicytbl+1;
3330 unsigned long long workload[NUMCORESACTIVE];
3331 memset(workload, 0, NUMCORESACTIVE*sizeof(unsigned long long));
3332 unsigned long long total_workload = 0;
3333 unsigned long long core2heavypages[NUMCORESACTIVE][page_num*3+1];
3334 memset(core2heavypages,0,
3335 sizeof(unsigned long long)*(page_num*3+1)*NUMCORESACTIVE);
3336 for(page_index = 0; page_index < page_num; page_index++) {
3337 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3338 bamboo_cache_policy_t policy = {0};
3339 unsigned int hotestcore = 0;
3340 unsigned long long totalfreq = 0;
3341 unsigned int hotfreq = 0;
3343 int *local_tbl=&gccachesamplingtbl_r[page_index];
3344 for(int i = 0; i < NUMCORESACTIVE; i++) {
3345 int freq = *local_tbl;
3346 local_tbl=(int *)(((char *)local_tbl)+size_cachesamplingtbl_local_r);
3348 // check the freqency, decide if this page is hot for the core
3349 if(hotfreq < freq) {
3354 // Decide the cache strategy for this page
3355 // If decide to adapt a new cache strategy, write into the shared block of
3356 // the gcsharedsamplingtbl. The mem recording information that has been
3357 // written is enough to hold the information.
3358 // Format: page start va + cache strategy(hfh/(host core+[x,y]))
3360 // this page has not been accessed, do not change its cache policy
3363 totalfreq/=BAMBOO_PAGE_SIZE;
3364 hotfreq/=BAMBOO_PAGE_SIZE;
3365 // locally cache the page in the hotest core
3366 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
3367 policy.cache_mode = BAMBOO_CACHE_MODE_COORDS;
3368 policy.lotar_x = bamboo_cpu2coords[2*hotestcore]+1;
3369 policy.lotar_y = bamboo_cpu2coords[2*hotestcore+1]+1;
3370 *tmp_p = page_index;
3372 *tmp_p = policy.word;
3375 workload[hotestcore] += totalfreq;
3376 total_workload += totalfreq;
3377 // insert into core2heavypages using quicksort
3378 unsigned long long remoteaccess = totalfreq - hotfreq;
3379 unsigned int index = (unsigned int)core2heavypages[hotestcore][0];
3380 core2heavypages[hotestcore][3*index+3] = remoteaccess;
3381 core2heavypages[hotestcore][3*index+2] = totalfreq;
3382 core2heavypages[hotestcore][3*index+1] = (unsigned long long)(tmp_p-1);
3383 core2heavypages[hotestcore][0]++;
3386 unsigned long long workload_threshold =
3387 total_workload / GC_CACHE_ADAPT_OVERLOAD_THRESHOLD;
3388 // Check the workload of each core
3389 for(int i = 0; i < NUMCORESACTIVE; i++) {
3391 unsigned int index = (unsigned int)core2heavypages[i][0];
3392 if(workload[i] > workload_threshold) {
3393 // sort according to the remoteaccess
3394 gc_quicksort(&core2heavypages[i][0], 1, index, 0);
3395 while((workload[i] > workload_threshold) && (j<index*3)) {
3396 // hfh those pages with more remote accesses
3397 bamboo_cache_policy_t policy = {0};
3398 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3399 *((unsigned int*)core2heavypages[i][j]) = policy.word;
3400 workload[i] -= core2heavypages[i][j+1];
3405 // Check if the accesses are crowded on few pages
3406 // sort according to the total access
3408 gc_quicksort(&core2heavypages[i][0], j/3+1, index, 1);
3409 unsigned long long threshold =
3410 GC_CACHE_ADAPT_ACCESS_THRESHOLD*workload[i]/100;
3411 int num_crowded = 0;
3412 unsigned long long t_workload = 0;
3414 t_workload += core2heavypages[i][j+num_crowded*3+1];
3416 } while(t_workload < threshold);
3417 // num_crowded <= GC_CACHE_ADAPT_CROWD_THRESHOLD and if there are enough
3418 // items, it is always == GC_CACHE_ADAPT_CROWD_THRESHOLD
3419 if(num_crowded > GC_CACHE_ADAPT_CROWD_THRESHOLD) {
3420 // need to hfh these pages
3421 // sort the pages according to remote access
3422 gc_quicksort(&core2heavypages[i][0], j/3+1, j/3+num_crowded, 0);
3423 // h4h those pages with more remote accesses
3424 bamboo_cache_policy_t policy = {0};
3425 policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
3426 *((unsigned int*)core2heavypages[i][j]) = policy.word;
3427 workload[i] -= core2heavypages[i][j+1];
3428 t_workload -= core2heavypages[i][j+1];
3430 threshold = GC_CACHE_ADAPT_ACCESS_THRESHOLD*workload[i]/100;
3436 } // int cacheAdapt_policy_overload()
3438 void cacheAdapt_master() {
3439 #ifdef GC_CACHE_ADAPT_SAMPLING_OUTPUT
3440 gc_output_cache_sampling_r();
3441 #endif // GC_CACHE_ADAPT_SAMPLING_OUTPUT
3442 unsigned int numchanged = 0;
3443 // check the statistic data
3444 // for each page, decide the new cache strategy
3445 #ifdef GC_CACHE_ADAPT_POLICY1
3446 numchanged = cacheAdapt_policy_h4h();
3447 #elif defined GC_CACHE_ADAPT_POLICY2
3448 numchanged = cacheAdapt_policy_local();
3449 #elif defined GC_CACHE_ADAPT_POLICY3
3450 numchanged = cacheAdapt_policy_hotest();
3451 #elif defined GC_CACHE_ADAPT_POLICY4
3452 numchanged = cacheAdapt_policy_dominate();
3453 #elif defined GC_CACHE_ADAPT_POLICY5
3454 numchanged = cacheAdapt_policy_overload();
3455 #elif defined GC_CACHE_ADAPT_POLICY6
3456 numchanged = cacheAdapt_policy_crowd();
3458 *gccachepolicytbl = numchanged;
3461 // adapt the cache strategy for the mutator
3462 void cacheAdapt_mutator() {
3463 int numchanged = *gccachepolicytbl;
3464 // check the changes and adapt them
3465 int * tmp_p = gccachepolicytbl+1;
3466 while(numchanged--) {
3467 // read out the policy
3468 int page_index = *tmp_p;
3469 bamboo_cache_policy_t policy = (bamboo_cache_policy_t)(*(tmp_p+1));
3471 bamboo_adapt_cache_policy(page_index*(BAMBOO_PAGE_SIZE)+gcbaseva,
3472 policy, BAMBOO_PAGE_SIZE);
3478 void gc_output_cache_sampling() {
3479 unsigned int page_index = 0;
3481 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3482 for(page_index = 0; page_index < page_num; page_index++) {
3483 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3484 unsigned int block = 0;
3485 BLOCKINDEX(page_sva, &block);
3486 unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
3487 tprintf("va: %x page_index: %d host: %d\n",
3488 (int)page_sva, page_index, coren);
3489 for(int i = 0; i < NUMCORESACTIVE; i++) {
3490 int * local_tbl = (int *)((void *)gccachesamplingtbl
3491 +size_cachesamplingtbl_local*i);
3492 int freq = local_tbl[page_index];
3493 printf("%8d ",freq);
3497 printf("=================\n");
3498 } // gc_output_cache_sampling
3500 void gc_output_cache_sampling_r() {
3501 unsigned int page_index = 0;
3503 unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
3504 for(page_index = 0; page_index < page_num; page_index++) {
3505 page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
3506 unsigned int block = 0;
3507 BLOCKINDEX(page_sva, &block);
3508 unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
3509 tprintf("va: %x page_index: %d host: %d\n",
3510 (int)page_sva, page_index, coren);
3511 for(int i = 0; i < NUMCORESACTIVE; i++) {
3512 int * local_tbl = (int *)((void *)gccachesamplingtbl_r
3513 +size_cachesamplingtbl_local_r*i);
3514 int freq = local_tbl[page_index]/BAMBOO_PAGE_SIZE;
3515 printf("%8d ",freq);
3519 printf("=================\n");
3520 } // gc_output_cache_sampling
3521 #endif // GC_CACHE_ADAPT
3523 inline void gc_collect(struct garbagelist * stackptr) {
3524 // inform the master that this core is at a gc safe point and is ready to
3526 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
3527 self_numreceiveobjs, false);
3529 // core collector routine
3531 if(INITPHASE == gcphase) {
3535 #ifdef RAWPATH // TODO GC_DEBUG
3536 printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
3539 #ifdef GC_CACHE_ADAPT
3540 // prepare for cache adaption:
3541 cacheAdapt_gc(true);
3542 #endif // GC_CACHE_ADAPT
3543 //send init finish msg to core coordinator
3544 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
3547 if(MARKPHASE == gcphase) {
3551 #ifdef RAWPATH // TODO GC_DEBUG
3552 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
3553 udn_tile_coord_y());
3555 mark(true, stackptr);
3556 #ifdef RAWPATH // TODO GC_DEBUG
3557 printf("(%x,%x) Finish mark phase, start compact phase\n",
3558 udn_tile_coord_x(), udn_tile_coord_y());
3561 #ifdef RAWPATH // TODO GC_DEBUG
3562 printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
3563 udn_tile_coord_y());
3567 if(FLUSHPHASE == gcphase) {
3571 #ifdef RAWPATH // TODO GC_DEBUG
3572 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
3573 udn_tile_coord_y());
3576 // send the num of obj/liveobj/forwardobj to the startupcore
3577 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
3578 send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
3579 gc_num_liveobj, gc_num_forwardobj, false);
3582 #endif // GC_PROFLIE
3584 #ifdef RAWPATH // TODO GC_DEBUG
3585 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
3586 udn_tile_coord_y());
3589 #ifdef GC_CACHE_ADAPT
3591 if(PREFINISHPHASE == gcphase) {
3595 #ifdef RAWPATH // TODO GC_DEBUG
3596 printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
3597 udn_tile_coord_y());
3599 // cache adapt phase
3600 cacheAdapt_mutator();
3601 cacheAdapt_gc(false);
3602 //send init finish msg to core coordinator
3603 send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
3604 #ifdef RAWPATH // TODO GC_DEBUG
3605 printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
3606 udn_tile_coord_y());
3608 #ifdef GC_CACHE_SAMPLING
3609 // reset the sampling arrays
3610 bamboo_dtlb_sampling_reset();
3611 #endif // GC_CACHE_SAMPLING
3612 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
3613 // zero out the gccachesamplingtbl
3614 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
3615 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
3616 size_cachesamplingtbl_local_r);
3618 #endif // GC_CACHE_ADAPT
3620 // invalidate all shared mem pointers
3621 bamboo_cur_msp = NULL;
3622 bamboo_smem_size = 0;
3623 bamboo_smem_zero_top = NULL;
3626 if(FINISHPHASE == gcphase) {
3631 #ifdef RAWPATH // TODO GC_DEBUG
3632 printf("(%x,%x) Finish gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
3634 } // void gc_collect(struct garbagelist * stackptr)
3636 inline void gc_nocollect(struct garbagelist * stackptr) {
3637 // inform the master that this core is at a gc safe point and is ready to
3639 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
3640 self_numreceiveobjs, false);
3643 if(INITPHASE == gcphase) {
3647 #ifdef RAWPATH // TODO GC_DEBUG
3648 printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
3651 #ifdef GC_CACHE_ADAPT
3652 // prepare for cache adaption:
3653 cacheAdapt_gc(true);
3654 #endif // GC_CACHE_ADAPT
3655 //send init finish msg to core coordinator
3656 send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
3659 if(MARKPHASE == gcphase) {
3663 #ifdef RAWPATH // TODO GC_DEBUG
3664 printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
3665 udn_tile_coord_y());
3667 mark(true, stackptr);
3668 #ifdef RAWPATH // TODO GC_DEBUG
3669 printf("(%x,%x) Finish mark phase, wait for flush\n",
3670 udn_tile_coord_x(), udn_tile_coord_y());
3673 // non-gc core collector routine
3675 if(FLUSHPHASE == gcphase) {
3679 #ifdef RAWPATH // TODO GC_DEBUG
3680 printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
3681 udn_tile_coord_y());
3684 if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
3685 send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
3686 gc_num_liveobj, gc_num_forwardobj, false);
3689 #endif // GC_PROFLIE
3691 #ifdef RAWPATH // TODO GC_DEBUG
3692 printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
3693 udn_tile_coord_y());
3696 #ifdef GC_CACHE_ADAPT
3698 if(PREFINISHPHASE == gcphase) {
3702 #ifdef RAWPATH // TODO GC_DEBUG
3703 printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
3704 udn_tile_coord_y());
3706 // cache adapt phase
3707 cacheAdapt_mutator();
3708 cacheAdapt_gc(false);
3709 //send init finish msg to core coordinator
3710 send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
3711 #ifdef RAWPATH // TODO GC_DEBUG
3712 printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
3713 udn_tile_coord_y());
3715 #ifdef GC_CACHE_SAMPLING
3716 // reset the sampling arrays
3717 bamboo_dtlb_sampling_reset();
3718 #endif // GC_CACHE_SAMPLING
3719 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
3720 // zero out the gccachesamplingtbl
3721 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
3722 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
3723 size_cachesamplingtbl_local_r);
3725 #endif // GC_CACHE_ADAPT
3727 // invalidate all shared mem pointers
3728 bamboo_cur_msp = NULL;
3729 bamboo_smem_size = 0;
3730 bamboo_smem_zero_top = NULL;
3733 if(FINISHPHASE == gcphase) {
3737 #ifdef RAWPATH // TODO GC_DEBUG
3738 printf("(%x,%x) Finish gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
3740 } // void gc_collect(struct garbagelist * stackptr)
3742 inline void gc_master(struct garbagelist * stackptr) {
3743 tprintf("start GC !!!!!!!!!!!!! \n");
3745 gcphase = INITPHASE;
3747 waitconfirm = false;
3751 // Note: all cores need to init gc including non-gc cores
3752 for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
3753 // send GC init messages to all cores
3754 send_msg_1(i, GCSTARTINIT, false);
3756 bool isfirst = true;
3757 bool allStall = false;
3759 #ifdef GC_CACHE_ADAPT
3760 // prepare for cache adaption:
3761 cacheAdapt_gc(true);
3762 #endif // GC_CACHE_ADAPT
3764 #ifdef RAWPATH // TODO GC_DEBUG
3765 printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
3766 udn_tile_coord_y());
3769 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
3771 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3772 if(gc_checkAllCoreStatus_I()) {
3773 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3776 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3780 if(gc_profile_flag) {
3787 #ifdef GC_CACHE_ADAPT_POLICY_OUTPUT
3788 gc_output_cache_sampling();
3789 #endif // GC_CACHE_ADAPT
3790 #ifdef RAWPATH // TODO GC_DEBUG
3791 printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
3792 udn_tile_coord_y());
3794 // restore the gcstatus of all cores
3795 // Note: all cores have to do mark including non-gc cores
3796 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
3797 for(i = 1; i < NUMCORESACTIVE; ++i) {
3798 gccorestatus[i] = 1;
3799 // send GC start messages to all cores
3800 send_msg_1(i, GCSTART, false);
3803 gcphase = MARKPHASE;
3805 while(MARKPHASE == gcphase) {
3806 mark(isfirst, stackptr);
3813 } // while(MARKPHASE == gcphase)
3814 // send msgs to all cores requiring large objs info
3815 // Note: only need to ask gc cores, non-gc cores do not host any objs
3816 numconfirm = NUMCORES4GC - 1;
3817 for(i = 1; i < NUMCORES4GC; ++i) {
3818 send_msg_1(i, GCLOBJREQUEST, false);
3820 gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
3825 } // wait for responses
3826 // check the heaptop
3827 if(gcheaptop < gcmarkedptrbound) {
3828 gcheaptop = gcmarkedptrbound;
3832 if(gc_profile_flag) {
3839 #ifdef RAWPATH // TODO GC_DEBUG
3840 printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
3841 udn_tile_coord_y());
3843 // cache all large objs
3845 // no enough space to cache large objs
3846 BAMBOO_EXIT(0xb02b);
3848 // predict number of blocks to fill for each core
3849 unsigned int tmpheaptop = 0;
3850 int numpbc = loadbalance(&tmpheaptop);
3852 numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
3853 #ifdef RAWPATH // TODO GC_DEBUG
3854 printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
3855 udn_tile_coord_y());
3857 //int tmptopptr = 0;
3858 //BASEPTR(gctopcore, 0, &tmptopptr);
3860 //tmptopptr = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
3861 tmpheaptop = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
3862 GC_BAMBOO_DEBUGPRINT(0xabab);
3863 GC_BAMBOO_DEBUGPRINT_REG(tmpheaptop);
3864 for(i = 0; i < NUMCORES4GC; ++i) {
3865 unsigned int tmpcoreptr = 0;
3866 BASEPTR(i, numpbc, &tmpcoreptr);
3867 // init some data strutures for compact phase
3869 gcfilledblocks[i] = 0;
3870 gcrequiredmems[i] = 0;
3871 gccorestatus[i] = 1;
3872 //send start compact messages to all cores
3873 //TODO bug here, do not know if the direction is positive or negtive?
3874 if (tmpcoreptr < tmpheaptop) {
3875 gcstopblock[i] = numpbc + 1;
3876 if(i != STARTUPCORE) {
3877 send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
3879 gcblock2fill = numpbc+1;
3880 } // if(i != STARTUPCORE)
3882 gcstopblock[i] = numpbc;
3883 if(i != STARTUPCORE) {
3884 send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
3886 gcblock2fill = numpbc;
3887 } // if(i != STARTUPCORE)
3889 GC_BAMBOO_DEBUGPRINT(0xf000+i);
3890 GC_BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
3891 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
3898 if(gc_profile_flag) {
3907 bool finalcompact = false;
3908 // initialize pointers for comapcting
3909 struct moveHelper * orig =
3910 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3911 struct moveHelper * to =
3912 (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
3913 initOrig_Dst(orig, to);
3914 int filledblocks = 0;
3915 unsigned int heaptopptr = 0;
3916 bool finishcompact = false;
3917 bool iscontinue = true;
3918 bool localcompact = true;
3919 while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
3920 if((!finishcompact) && iscontinue) {
3921 GC_BAMBOO_DEBUGPRINT(0xeaa01);
3922 GC_BAMBOO_DEBUGPRINT_REG(numpbc);
3923 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3924 finishcompact = compacthelper(orig, to, &filledblocks,
3925 &heaptopptr, &localcompact);
3926 GC_BAMBOO_DEBUGPRINT(0xeaa02);
3927 GC_BAMBOO_DEBUGPRINT_REG(finishcompact);
3928 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3929 GC_BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
3930 GC_BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
3931 GC_BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
3934 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3935 if(gc_checkCoreStatus_I()) {
3936 // all cores have finished compacting
3937 // restore the gcstatus of all cores
3938 for(i = 0; i < NUMCORES4GC; ++i) {
3939 gccorestatus[i] = 1;
3941 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3944 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3945 // check if there are spare mem for pending move requires
3946 if(COMPACTPHASE == gcphase) {
3947 GC_BAMBOO_DEBUGPRINT(0xeaa03);
3948 resolvePendingMoveRequest();
3949 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3951 GC_BAMBOO_DEBUGPRINT(0xeaa04);
3954 } // if(gc_checkCoreStatus_I()) else ...
3957 GC_BAMBOO_DEBUGPRINT(0xeaa05);
3958 GC_BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
3959 GC_BAMBOO_DEBUGPRINT_REG(gcblock2fill);
3960 GC_BAMBOO_DEBUGPRINT_REG(gctomove);
3961 to->ptr = gcmovestartaddr;
3962 to->numblocks = gcblock2fill - 1;
3963 to->bound = (to->numblocks==0) ?
3964 BAMBOO_SMEM_SIZE_L :
3965 BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
3966 BASEPTR(gcdstcore, to->numblocks, &(to->base));
3967 to->offset = to->ptr - to->base;
3968 to->top = (to->numblocks==0) ?
3969 (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
3971 to->offset = BAMBOO_CACHE_LINE_SIZE;
3972 to->ptr += to->offset; // for header
3973 to->top += to->offset;
3974 if(gcdstcore == BAMBOO_NUM_OF_CORE) {
3975 localcompact = true;
3977 localcompact = false;
3981 } else if(!finishcompact) {
3985 } // while(COMPACTPHASE == gcphase)
3988 if(gc_profile_flag) {
3995 #ifdef RAWPATH // TODO GC_DEBUG
3996 printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
3997 udn_tile_coord_y());
4001 #ifdef RAWPATH // TODO GC_DEBUG
4002 printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
4003 udn_tile_coord_y());
4009 gcphase = FLUSHPHASE;
4010 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4011 // Note: all cores should flush their runtime data including non-gc
4013 for(i = 1; i < NUMCORESACTIVE; ++i) {
4014 // send start flush messages to all cores
4015 gccorestatus[i] = 1;
4016 send_msg_1(i, GCSTARTFLUSH, false);
4020 if(gc_profile_flag) {
4027 #ifdef RAWPATH // TODO GC_DEBUG
4028 printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
4029 udn_tile_coord_y());
4034 #ifdef GC_CACHE_ADAPT
4035 // now the master core need to decide the new cache strategy
4036 cacheAdapt_master();
4037 #endif // GC_CACHE_ADAPT
4039 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4040 while(FLUSHPHASE == gcphase) {
4041 // check the status of all cores
4042 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4043 if(gc_checkAllCoreStatus_I()) {
4044 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4047 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4048 } // while(FLUSHPHASE == gcphase)
4049 #ifdef RAWPATH // TODO GC_DEBUG
4050 printf("(%x,%x) Finish flush phase \n", udn_tile_coord_x(),
4051 udn_tile_coord_y());
4054 #ifdef GC_CACHE_ADAPT
4057 if(gc_profile_flag) {
4064 gcphase = PREFINISHPHASE;
4065 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4066 // Note: all cores should flush their runtime data including non-gc
4068 for(i = 1; i < NUMCORESACTIVE; ++i) {
4069 // send start flush messages to all cores
4070 gccorestatus[i] = 1;
4071 send_msg_1(i, GCSTARTPREF, false);
4073 #ifdef RAWPATH // TODO GC_DEBUG
4074 printf("(%x,%x) Start prefinish phase \n", udn_tile_coord_x(),
4075 udn_tile_coord_y());
4077 // cache adapt phase
4078 cacheAdapt_mutator();
4080 if(gc_profile_flag) {
4082 #ifdef GC_CACHE_ADAPT_OUTPUT
4083 bamboo_output_cache_policy();
4088 cacheAdapt_gc(false);
4090 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4091 while(PREFINISHPHASE == gcphase) {
4092 // check the status of all cores
4093 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4094 if(gc_checkAllCoreStatus_I()) {
4095 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4098 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4099 } // while(PREFINISHPHASE == gcphase)
4101 #ifdef GC_CACHE_SAMPLING
4102 // reset the sampling arrays
4103 bamboo_dtlb_sampling_reset();
4104 #endif // GC_CACHE_SAMPLING
4105 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4106 // zero out the gccachesamplingtbl
4107 BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
4108 BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,
4109 size_cachesamplingtbl_local_r);
4110 BAMBOO_MEMSET_WH(gccachepolicytbl,0,size_cachepolicytbl);
4112 #endif // GC_CACHE_ADAPT
4114 gcphase = FINISHPHASE;
4116 // invalidate all shared mem pointers
4117 // put it here as it takes time to inform all the other cores to
4118 // finish gc and it might cause problem when some core resumes
4119 // mutator earlier than the other cores
4120 bamboo_cur_msp = NULL;
4121 bamboo_smem_size = 0;
4122 bamboo_smem_zero_top = NULL;
4126 if(gc_profile_flag) {
4133 gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
4134 for(i = 1; i < NUMCORESACTIVE; ++i) {
4135 // send gc finish messages to all cores
4136 send_msg_1(i, GCFINISH, false);
4137 gccorestatus[i] = 1;
4141 gcprocessing = false;
4142 #ifdef RAWPATH // TODO GC_DEBUG
4143 printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
4144 udn_tile_coord_y());
4146 tprintf("finish GC ! \n");
4147 } // void gc_master(struct garbagelist * stackptr)
4149 inline bool gc(struct garbagelist * stackptr) {
4152 gcprocessing = false;
4156 #ifdef GC_CACHE_ADAPT
4157 #ifdef GC_CACHE_SAMPLING
4158 // disable the timer interrupt
4159 bamboo_mask_timer_intr();
4162 // core coordinator routine
4163 if(0 == BAMBOO_NUM_OF_CORE) {
4165 printf("(%x,%x) Check if can do gc or not\n", udn_tile_coord_x(),
4166 udn_tile_coord_y());
4168 bool isallstall = true;
4169 gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
4170 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
4172 for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
4173 if(gccorestatus[ti] != 0) {
4179 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4180 // some of the cores are still executing the mutator and did not reach
4181 // some gc safe point, therefore it is not ready to do gc
4187 if(gc_profile_flag) {
4195 gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
4196 gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
4198 GC_BAMBOO_DEBUGPRINT(0xec04);
4199 for(int i = 0; i < NUMCORESACTIVE; ++i) {
4200 sumsendobj += gcnumsendobjs[0][i];
4201 GC_BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
4202 } // for(i = 1; i < NUMCORESACTIVE; ++i)
4203 GC_BAMBOO_DEBUGPRINT(0xec05);
4204 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
4205 for(int i = 0; i < NUMCORESACTIVE; ++i) {
4206 sumsendobj -= gcnumreceiveobjs[0][i];
4207 GC_BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
4208 } // for(i = 1; i < NUMCORESACTIVE; ++i)
4209 GC_BAMBOO_DEBUGPRINT(0xec06);
4210 GC_BAMBOO_DEBUGPRINT_REG(sumsendobj);
4211 if(0 != sumsendobj) {
4212 // there were still some msgs on the fly, wait until there
4213 // are some update pregc information coming and check it again
4215 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4223 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
4226 #ifdef RAWPATH // TODO GC_DEBUG
4227 printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
4229 // Zero out the remaining bamboo_cur_msp
4230 // Only zero out the first 4 bytes of the remaining memory
4231 // Move the operation here because for the GC_CACHE_ADAPT version,
4232 // we need to make sure during the gcinit phase the shared heap is not
4233 // touched. Otherwise, there would be problem when adapt the cache
4235 if((bamboo_cur_msp != 0)
4236 && (bamboo_smem_zero_top == bamboo_cur_msp)
4237 && (bamboo_smem_size > 0)) {
4238 *((int *)bamboo_cur_msp) = 0;
4240 #ifdef GC_FLUSH_DTLB
4241 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4242 BAMBOO_CLEAN_DTLB();
4243 gc_num_flush_dtlb++;
4246 #ifdef GC_CACHE_ADAPT
4247 #ifdef GC_CACHE_SAMPLING
4248 // get the sampling data
4249 bamboo_output_dtlb_sampling();
4250 #endif // GC_CACHE_SAMPLING
4251 #endif // GC_CACHE_ADAPT
4252 gcprocessing = true;
4253 gc_master(stackptr);
4254 } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
4255 // Zero out the remaining bamboo_cur_msp
4256 // Only zero out the first 4 bytes of the remaining memory
4257 // Move the operation here because for the GC_CACHE_ADAPT version,
4258 // we need to make sure during the gcinit phase the shared heap is not
4259 // touched. Otherwise, there would be problem when adapt the cache
4261 if((bamboo_cur_msp != 0)
4262 && (bamboo_smem_zero_top == bamboo_cur_msp)
4263 && (bamboo_smem_size > 0)) {
4264 *((int *)bamboo_cur_msp) = 0;
4266 #ifdef GC_FLUSH_DTLB
4267 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4268 BAMBOO_CLEAN_DTLB();
4269 gc_num_flush_dtlb++;
4272 #ifdef GC_CACHE_ADAPT
4273 #ifdef GC_CACHE_SAMPLING
4274 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4275 // get the sampling data
4276 bamboo_output_dtlb_sampling();
4278 #endif // GC_CACHE_SAMPLING
4279 #endif // GC_CACHE_ADAPT
4280 gcprocessing = true;
4281 gc_collect(stackptr);
4283 // Zero out the remaining bamboo_cur_msp
4284 // Only zero out the first 4 bytes of the remaining memory
4285 // Move the operation here because for the GC_CACHE_ADAPT version,
4286 // we need to make sure during the gcinit phase the shared heap is not
4287 // touched. Otherwise, there would be problem when adapt the cache
4289 if((bamboo_cur_msp != 0)
4290 && (bamboo_smem_zero_top == bamboo_cur_msp)
4291 && (bamboo_smem_size > 0)) {
4292 *((int *)bamboo_cur_msp) = 0;
4294 #ifdef GC_FLUSH_DTLB
4295 if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
4296 BAMBOO_CLEAN_DTLB();
4297 gc_num_flush_dtlb++;
4300 #ifdef GC_CACHE_ADAPT
4301 #ifdef GC_CACHE_SAMPLING
4302 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
4303 // get the sampling data
4304 bamboo_output_dtlb_sampling();
4306 #endif // GC_CACHE_SAMPLING
4307 #endif // GC_CACHE_ADAPT
4308 // not a gc core, should wait for gcfinish msg
4309 gcprocessing = true;
4310 gc_nocollect(stackptr);
4312 #ifdef GC_CACHE_ADAPT
4313 #ifdef GC_CACHE_SAMPLING
4314 // enable the timer interrupt
4315 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING);
4316 bamboo_unmask_timer_intr();
4317 #endif // GC_CACHE_SAMPLING
4318 #endif // GC_CACHE_ADAPT
4321 } // void gc(struct garbagelist * stackptr)
4324 inline void gc_profileStart(void) {
4325 if(!gc_infoOverflow) {
4326 GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
4327 gc_infoArray[gc_infoIndex] = gcInfo;
4329 gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
4333 inline void gc_profileItem(void) {
4334 if(!gc_infoOverflow) {
4335 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
4336 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
4340 inline void gc_profileEnd(void) {
4341 if(!gc_infoOverflow) {
4342 GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
4343 gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
4344 gcInfo->time[gcInfo->index++] = gc_num_livespace;
4345 gcInfo->time[gcInfo->index++] = gc_num_freespace;
4346 gcInfo->time[gcInfo->index++] = gc_num_lobj;
4347 gcInfo->time[gcInfo->index++] = gc_num_lobjspace;
4348 gcInfo->time[gcInfo->index++] = gc_num_obj;
4349 gcInfo->time[gcInfo->index++] = gc_num_liveobj;
4350 gcInfo->time[gcInfo->index++] = gc_num_forwardobj;
4352 if(gc_infoIndex == GCINFOLENGTH) {
4353 gc_infoOverflow = true;
4354 //taskInfoIndex = 0;
4359 // output the profiling data
4360 void gc_outputProfileData() {
4363 unsigned long long totalgc = 0;
4365 #ifndef BAMBOO_MEMPROF
4366 BAMBOO_PRINT(0xdddd);
4368 // output task related info
4369 for(i= 0; i < gc_infoIndex; i++) {
4370 GCInfo * gcInfo = gc_infoArray[i];
4371 #ifdef BAMBOO_MEMPROF
4372 unsigned long long tmp=gcInfo->time[gcInfo->index-8]-gcInfo->time[0]; //0;
4374 unsigned long long tmp = 0;
4375 BAMBOO_PRINT(0xddda);
4376 for(j = 0; j < gcInfo->index - 7; j++) {
4377 BAMBOO_PRINT(gcInfo->time[j]);
4378 BAMBOO_PRINT(gcInfo->time[j]-tmp);
4379 BAMBOO_PRINT(0xdddb);
4380 tmp = gcInfo->time[j];
4382 tmp = (tmp-gcInfo->time[0]);
4383 BAMBOO_PRINT_REG(tmp);
4384 BAMBOO_PRINT(0xdddc);
4385 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 7]);
4386 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 6]);
4387 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 5]);
4388 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 4]);
4389 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 3]);
4390 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 2]);
4391 BAMBOO_PRINT(gcInfo->time[gcInfo->index - 1]);
4392 BAMBOO_PRINT(0xddde);
4396 #ifndef BAMBOO_MEMPROF
4397 BAMBOO_PRINT(0xdddf);
4399 BAMBOO_PRINT_REG(totalgc);
4401 if(gc_infoOverflow) {
4402 BAMBOO_PRINT(0xefee);
4405 #ifndef BAMBOO_MEMPROF
4406 BAMBOO_PRINT(0xeeee);
4409 #endif // #ifdef GC_PROFILE