code changes
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.c
1 // TODO: DO NOT support tag!!!
2 #ifdef MULTICORE_GC
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "multicoregarbage.h"
6 #include "multicoregcmark.h"
7 #include "gcqueue.h"
8 #include "multicoregccompact.h"
9 #include "multicoregcflush.h"
10 #include "multicoregcprofile.h"
11 #include "gcqueue.h"
12
13 #ifdef SMEMM
14 extern unsigned int gcmem_mixed_threshold;
15 extern unsigned int gcmem_mixed_usedmem;
16 #endif // SMEMM
17
18 volatile bool gcflag;
19 gc_status_t gc_status_info;
20
21 unsigned long long gc_output_cache_policy_time=0;
22
23 #ifdef GC_DEBUG
24 // dump whole mem in blocks
25 void dumpSMem() {
26   int block = 0;
27   int sblock = 0;
28   unsigned int j = 0;
29   void * i = 0;
30   int coren = 0;
31   int x = 0;
32   int y = 0;
33   printf("(%x,%x) Dump shared mem: \n",udn_tile_coord_x(),udn_tile_coord_y());
34   // reserved blocks for sblocktbl
35   printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
36          udn_tile_coord_y());
37   for(i=BAMBOO_BASE_VA; (unsinged int)i<(unsigned int)gcbaseva; i+= 4*16) {
38     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",
39         udn_tile_coord_x(), udn_tile_coord_y(),
40         *((int *)(i)), *((int *)(i + 4)),
41         *((int *)(i + 4*2)), *((int *)(i + 4*3)),
42         *((int *)(i + 4*4)), *((int *)(i + 4*5)),
43         *((int *)(i + 4*6)), *((int *)(i + 4*7)),
44         *((int *)(i + 4*8)), *((int *)(i + 4*9)),
45         *((int *)(i + 4*10)), *((int *)(i + 4*11)),
46         *((int *)(i + 4*12)), *((int *)(i + 4*13)),
47         *((int *)(i + 4*14)), *((int *)(i + 4*15)));
48   }
49   sblock = 0;
50   bool advanceblock = false;
51   // remaining memory
52   for(i=gcbaseva; (unsigned int)i<(unsigned int)(gcbaseva+BAMBOO_SHARED_MEM_SIZE); i+=4*16) {
53     advanceblock = false;
54     // computing sblock # and block #, core coordinate (x,y) also
55     if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
56       // finished a sblock
57       if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
58         if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
59           // finished a block
60           block++;
61           advanceblock = true;  
62         }
63       } else {
64         // finished a block
65         block++;
66         advanceblock = true;
67       }
68       // compute core #
69       if(advanceblock) {
70         coren = gc_block2core[block%(NUMCORES4GC*2)];
71       }
72       // compute core coordinate
73       x = BAMBOO_COORDS_X(coren);
74       y = BAMBOO_COORDS_Y(coren);
75       printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
76           udn_tile_coord_x(), udn_tile_coord_y(),block, sblock++, x, y,
77           (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
78     }
79     j++;
80     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",
81         udn_tile_coord_x(), udn_tile_coord_y(),
82         *((int *)(i)), *((int *)(i + 4)),
83         *((int *)(i + 4*2)), *((int *)(i + 4*3)),
84         *((int *)(i + 4*4)), *((int *)(i + 4*5)),
85         *((int *)(i + 4*6)), *((int *)(i + 4*7)),
86         *((int *)(i + 4*8)), *((int *)(i + 4*9)),
87         *((int *)(i + 4*10)), *((int *)(i + 4*11)),
88         *((int *)(i + 4*12)), *((int *)(i + 4*13)),
89         *((int *)(i + 4*14)), *((int *)(i + 4*15)));
90   }
91   printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
92 }
93 #endif
94
95 void initmulticoregcdata() {
96   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
97     // startup core to initialize corestatus[]
98     for(int i = 0; i < NUMCORESACTIVE; i++) {
99       gccorestatus[i] = 1;
100       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
101       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
102     } 
103     for(int i = 0; i < NUMCORES4GC; i++) {
104       gcloads[i] = 0;
105       gcrequiredmems[i] = 0;
106       gcstopblock[i] = 0;
107       gcfilledblocks[i] = 0;
108     }
109   }
110
111   bamboo_smem_zero_top = NULL;
112   gcflag = false;
113   gc_status_info.gcprocessing = false;
114   gc_status_info.gcphase = FINISHPHASE;
115
116   gcprecheck = true;
117   gccurr_heaptop = 0;
118   gcself_numsendobjs = 0;
119   gcself_numreceiveobjs = 0;
120   gcmarkedptrbound = 0;
121   gcforwardobjtbl = allocateMGCHash_I(128);
122   gcheaptop = 0;
123   gcmovestartaddr = 0;
124   gctomove = false;
125   gcmovepending = 0;
126   gcblock2fill = 0;
127 #ifdef SMEMM
128   gcmem_mixed_threshold=(unsigned int)((BAMBOO_SHARED_MEM_SIZE-bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
129   gcmem_mixed_usedmem = 0;
130 #endif
131 #ifdef MGC_SPEC
132   gc_profile_flag = false;
133 #endif
134   gc_localheap_s = false;
135 #ifdef GC_CACHE_ADAPT
136   gccachestage = false;
137 #endif 
138
139   INIT_MULTICORE_GCPROFILE_DATA();
140 }
141
142 void dismulticoregcdata() {
143   freeMGCHash(gcforwardobjtbl);
144 }
145
146 void initGC() {
147   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
148     for(int i = 0; i < NUMCORES4GC; i++) {
149       gccorestatus[i] = 1;
150       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
151       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
152       gcloads[i] = 0;
153       gcrequiredmems[i] = 0;
154       gcfilledblocks[i] = 0;
155       gcstopblock[i] = 0;
156     } 
157     for(int i = NUMCORES4GC; i < NUMCORESACTIVE; i++) {
158       gccorestatus[i] = 1;
159       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
160       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
161     }
162     gcheaptop = 0;
163     gcnumsrobjs_index = 0;
164   } 
165   gcself_numsendobjs = 0;
166   gcself_numreceiveobjs = 0;
167   gcmarkedptrbound = 0;
168   gcmovestartaddr = 0;
169   gctomove = false;
170   gcblock2fill = 0;
171   gcmovepending = 0;
172   gccurr_heaptop = 0;
173
174   gc_queueinit();
175
176   MGCHashreset(gcforwardobjtbl);
177
178   GCPROFILE_INIT();
179   gc_output_cache_policy_time=0;
180
181
182 bool gc_checkAllCoreStatus() {
183   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
184   for(int i = 0; i < NUMCORESACTIVE; i++) {
185     if(gccorestatus[i] != 0) {
186       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
187       return false;
188     }  
189   }  
190   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
191   return true;
192 }
193
194 // NOTE: should be invoked with interrupts turned off
195 bool gc_checkAllCoreStatus_I() {
196   for(int i = 0; i < NUMCORESACTIVE; i++) {
197     if(gccorestatus[i] != 0) {
198       return false;
199     }  
200   }  
201   return true;
202 }
203
204 void checkMarkStatus_p2() {
205   // check if the sum of send objs and receive obj are the same
206   // yes->check if the info is the latest; no->go on executing
207   unsigned int sumsendobj = 0;
208   for(int i = 0; i < NUMCORESACTIVE; i++) {
209     sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
210   } 
211   for(int i = 0; i < NUMCORESACTIVE; i++) {
212     sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
213   } 
214   if(0 == sumsendobj) {
215     // Check if there are changes of the numsendobjs or numreceiveobjs 
216     // on each core
217     int i = 0;
218     for(i = 0; i < NUMCORESACTIVE; i++) {
219       if((gcnumsendobjs[0][i]!=gcnumsendobjs[1][i])||(gcnumreceiveobjs[0][i]!=gcnumreceiveobjs[1][i]) ) {
220         break;
221       }
222     }  
223     if(i == NUMCORESACTIVE) {    
224       // all the core status info are the latest,stop mark phase
225       gc_status_info.gcphase = COMPACTPHASE;
226       // restore the gcstatus for all cores
227       for(int i = 0; i < NUMCORESACTIVE; i++) {
228         gccorestatus[i] = 1;
229       }  
230     } else {
231       // There were changes between phase 1 and phase 2, can not decide 
232       // whether the mark phase has been finished
233       waitconfirm = false;
234       // As it fails in phase 2, flip the entries
235       gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
236     } 
237   } else {
238     // There were changes between phase 1 and phase 2, can not decide 
239     // whether the mark phase has been finished
240     waitconfirm = false;
241     // As it fails in phase 2, flip the entries
242     gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
243   }
244 }
245
246 void checkMarkStatus() {
247   if((!waitconfirm)||(waitconfirm && (numconfirm == 0))) {
248     unsigned int entry_index = 0;
249     if(waitconfirm) {
250       // phase 2
251       entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
252     } else {
253       // phase 1
254       entry_index = gcnumsrobjs_index;
255     }
256     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
257     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;  
258     gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
259     gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
260     // check the status of all cores
261     if (gc_checkAllCoreStatus_I()) {
262       // ask for confirm
263       if(!waitconfirm) {
264         // the first time found all cores stall
265         // send out status confirm msg to all other cores
266         // reset the corestatus array too    
267         waitconfirm = true;
268         numconfirm = NUMCORESACTIVE - 1;
269         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
270         GC_SEND_MSG_1_TO_CLIENT(GCMARKCONFIRM);
271       } else {
272         // Phase 2
273         checkMarkStatus_p2(); 
274         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
275       }
276     } else {
277       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
278     } 
279   } 
280
281
282 // compute load balance for all cores
283 int loadbalance(void ** heaptop) {
284   // compute load balance
285   // get the total loads
286   unsigned int tloads = 0;
287   for(int i = 0; i < NUMCORES4GC; i++) {
288     tloads += gcloads[i];
289   }
290   *heaptop = gcbaseva + tloads;
291
292   unsigned int topblockindex;
293   
294   BLOCKINDEX(topblockindex, *heaptop);
295   // num of blocks per core
296   unsigned int numbpc = (topblockindex+NUMCORES4GC-1)/NUMCORES4GC;
297   
298   return numbpc;
299 }
300
301
302 // update the bmmboo_smemtbl to record current shared mem usage
303 void updateSmemTbl(unsigned int coren, void * localtop) {
304   unsigned int ltopcore = 0;
305   unsigned int bound = BAMBOO_SMEM_SIZE_L;
306   BLOCKINDEX(ltopcore, localtop);
307   if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
308     bound = BAMBOO_SMEM_SIZE;
309   }
310   unsigned int load = (unsigned INTPTR)(localtop-gcbaseva)%(unsigned int)bound;
311   unsigned int toset = 0;
312   for(int j=0; 1; j++) {
313     for(int i=0; i<2; i++) {
314       toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
315       if(toset < ltopcore) {
316         bamboo_smemtbl[toset]=BLOCKSIZE(toset<NUMCORES4GC);
317 #ifdef SMEMM
318         gcmem_mixed_usedmem += bamboo_smemtbl[toset];
319 #endif
320       } else if(toset == ltopcore) {
321         bamboo_smemtbl[toset] = load;
322 #ifdef SMEMM
323         gcmem_mixed_usedmem += bamboo_smemtbl[toset];
324 #endif
325         return;
326       } else {
327         return;
328       }
329     }
330   }
331 }
332
333 void gc_collect(struct garbagelist * stackptr) {
334   gc_status_info.gcprocessing = true;
335   // inform the master that this core is at a gc safe point and is ready to 
336   // do gc
337   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
338
339   // core collector routine
340   //wait for init phase
341   WAITFORGCPHASE(INITPHASE);
342
343   GC_PRINTF("Do initGC\n");
344   initGC();
345   CACHEADAPT_GC(true);
346   //send init finish msg to core coordinator
347   send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
348
349   //wait for mark phase
350   WAITFORGCPHASE(MARKPHASE);
351
352   GC_PRINTF("Start mark phase\n");
353   mark(true, stackptr);
354   GC_PRINTF("Finish mark phase, start compact phase\n");
355   compact();
356   GC_PRINTF("Finish compact phase\n");
357
358   WAITFORGCPHASE(UPDATEPHASE);
359
360   GC_PRINTF("Start flush phase\n");
361   GCPROFILE_INFO_2_MASTER();
362   update(stackptr);
363   GC_PRINTF("Finish flush phase\n");
364
365   CACHEADAPT_PHASE_CLIENT();
366
367   // invalidate all shared mem pointers
368   bamboo_cur_msp = NULL;
369   bamboo_smem_size = 0;
370   bamboo_smem_zero_top = NULL;
371   gcflag = false;
372
373   WAITFORGCPHASE(FINISHPHASE);
374
375   GC_PRINTF("Finish gc! \n");
376
377
378 void gc_nocollect(struct garbagelist * stackptr) {
379   gc_status_info.gcprocessing = true;
380   // inform the master that this core is at a gc safe point and is ready to 
381   // do gc
382   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
383   
384   WAITFORGCPHASE(INITPHASE);
385
386   GC_PRINTF("Do initGC\n");
387   initGC();
388   CACHEADAPT_GC(true);
389   //send init finish msg to core coordinator
390   send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
391
392   WAITFORGCPHASE(MARKPHASE);
393
394   GC_PRINTF("Start mark phase\n"); 
395   mark(true, stackptr);
396   GC_PRINTF("Finish mark phase, wait for flush\n");
397
398   // non-gc core collector routine
399   WAITFORGCPHASE(UPDATEPHASE);
400
401   GC_PRINTF("Start flush phase\n");
402   GCPROFILE_INFO_2_MASTER();
403   update(stackptr);
404   GC_PRINTF("Finish flush phase\n"); 
405
406   CACHEADAPT_PHASE_CLIENT();
407
408   // invalidate all shared mem pointers
409   bamboo_cur_msp = NULL;
410   bamboo_smem_size = 0;
411   bamboo_smem_zero_top = NULL;
412
413   gcflag = false;
414   WAITFORGCPHASE(FINISHPHASE);
415
416   GC_PRINTF("Finish gc! \n");
417 }
418
419 void master_mark(struct garbagelist *stackptr) {
420   bool isfirst = true;
421
422   GC_PRINTF("Start mark phase \n");
423   GC_SEND_MSG_1_TO_CLIENT(GCSTART);
424   gc_status_info.gcphase = MARKPHASE;
425   // mark phase
426
427   while(MARKPHASE == gc_status_info.gcphase) {
428     mark(isfirst, stackptr);
429     isfirst=false;
430     // check gcstatus
431     checkMarkStatus();
432   }
433 }
434
435 void master_getlargeobjs() {
436   // send msgs to all cores requiring large objs info
437   // Note: only need to ask gc cores, non-gc cores do not host any objs
438   numconfirm = NUMCORES4GC - 1;
439   for(int i = 1; i < NUMCORES4GC; i++) {
440     send_msg_1(i,GCLOBJREQUEST);
441   }
442   gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
443   //spin until we have all responses
444   while(numconfirm!=0) ;
445
446   // check the heaptop
447   if(gcheaptop < gcmarkedptrbound) {
448     gcheaptop = gcmarkedptrbound;
449   }
450   GCPROFILE_ITEM();
451   GC_PRINTF("prepare to cache large objs \n");
452
453 }
454
455
456 void master_updaterefs(struct garbagelist * stackptr) {
457   gc_status_info.gcphase = UPDATEPHASE;
458   GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
459   GCPROFILE_ITEM();
460   GC_PRINTF("Start flush phase \n");
461   // flush phase
462   update(stackptr);
463   GC_CHECK_ALL_CORE_STATUS(UPDATEPHASE==gc_status_info.gcphase);
464   GC_PRINTF("Finish flush phase \n");
465 }
466
467 void master_finish() {
468   gc_status_info.gcphase = FINISHPHASE;
469   
470   // invalidate all shared mem pointers
471   // put it here as it takes time to inform all the other cores to
472   // finish gc and it might cause problem when some core resumes
473   // mutator earlier than the other cores
474   bamboo_cur_msp = NULL;
475   bamboo_smem_size = 0;
476   bamboo_smem_zero_top = NULL;
477   
478   GCPROFILE_END();
479   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
480   CACHEADAPT_OUTPUT_CACHE_POLICY();
481   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
482   gcflag = false;
483   GC_SEND_MSG_1_TO_CLIENT(GCFINISH);
484   
485   gc_status_info.gcprocessing = false;
486   if(gcflag) {
487     // inform other cores to stop and wait for gc
488     gcprecheck = true;
489     for(int i = 0; i < NUMCORESACTIVE; i++) {
490       // reuse the gcnumsendobjs & gcnumreceiveobjs
491       gcnumsendobjs[0][i] = 0;
492       gcnumreceiveobjs[0][i] = 0;
493     }
494     GC_SEND_MSG_1_TO_CLIENT(GCSTARTPRE);
495   }
496 }
497
498 void gc_master(struct garbagelist * stackptr) {
499   tprintf("start GC !!!!!!!!!!!!! \n");
500   gc_status_info.gcprocessing = true;
501   gc_status_info.gcphase = INITPHASE;
502
503   waitconfirm = false;
504   numconfirm = 0;
505   initGC();
506   GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
507   CACHEADAPT_GC(true);
508   GC_PRINTF("Check core status \n");
509   GC_CHECK_ALL_CORE_STATUS(true);
510   GCPROFILE_ITEM();
511   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
512   CACHEADAPT_OUTPUT_CACHE_SAMPLING();
513   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
514
515   // do mark phase
516   master_mark(stackptr);
517
518   // get large objects from all cores
519   master_getlargeobjs();
520
521   // compact the heap
522   master_compact();
523   
524   // update the references
525   master_updaterefs(stackptr);
526
527   // do cache adaptation
528   CACHEADAPT_PHASE_MASTER();
529
530   // do finish up stuff
531   master_finish();
532
533   GC_PRINTF("gc finished   \n");
534   tprintf("finish GC ! %d \n",gcflag);
535
536
537 void pregccheck() {
538   while(true) {
539     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
540     gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
541     gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
542     int sumsendobj = 0;
543     for(int i = 0; i < NUMCORESACTIVE; i++) {
544       sumsendobj += gcnumsendobjs[0][i];
545     }  
546     for(int i = 0; i < NUMCORESACTIVE; i++) {
547       sumsendobj -= gcnumreceiveobjs[0][i];
548     } 
549     if(0 != sumsendobj) {
550       // there were still some msgs on the fly, wait until there 
551       // are some update pregc information coming and check it again
552       gcprecheck = false;
553       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
554
555       while(!gcprecheck) ;
556     } else {
557       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
558       return;
559     }
560   }
561 }
562
563 void pregcprocessing() {
564 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
565   // disable the timer interrupt
566   bamboo_mask_timer_intr();
567 #endif
568   // Zero out the remaining memory here because for the GC_CACHE_ADAPT version,
569   // we need to make sure during the gcinit phase the shared heap is not 
570   // touched. Otherwise, there would be problem when adapt the cache strategy.
571   BAMBOO_CLOSE_CUR_MSP();
572 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
573   // get the sampling data 
574   bamboo_output_dtlb_sampling();
575 #endif
576 }
577
578 void postgcprocessing() {
579 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
580   // enable the timer interrupt
581   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); 
582   bamboo_unmask_timer_intr();
583 #endif
584 }
585
586 bool gc(struct garbagelist * stackptr) {
587   // check if do gc
588   if(!gcflag) {
589     gc_status_info.gcprocessing = false;
590     return false;
591   }
592
593   // core coordinator routine
594   if(0 == BAMBOO_NUM_OF_CORE) {
595     GC_PRINTF("Check if we can do gc or not\n");
596     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
597     if(!gc_checkAllCoreStatus()) {
598       // some of the cores are still executing the mutator and did not reach
599       // some gc safe point, therefore it is not ready to do gc
600       gcflag = true;
601       return false;
602     } else {
603       GCPROFILE_START();
604       pregccheck();
605     }
606     GC_PRINTF("start gc! \n");
607     pregcprocessing();
608     gc_master(stackptr);
609   } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
610     pregcprocessing();
611     gc_collect(stackptr);
612   } else {
613     pregcprocessing();
614     gc_nocollect(stackptr);
615   }
616   postgcprocessing();
617
618   return true;
619
620
621 #endif