Add gcprofile to PMC garbage collector and compute the size of allocated obj instead...
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.c
index 4aeaa245667a0624a2de538998096c22d751eee9..4518fed89c10057533a9a19906e331d67af6d4b0 100644 (file)
@@ -1,52 +1,38 @@
-// BAMBOO_EXIT(0xb000);
-// TODO: DO NOT support tag!!!
 #ifdef MULTICORE_GC
 #include "runtime.h"
+#include "multicoreruntime.h"
 #include "multicoregarbage.h"
 #include "multicoregcmark.h"
 #include "multicoregccompact.h"
 #include "multicoregcflush.h"
-#include "multicoreruntime.h"
 #include "multicoregcprofile.h"
+#include "gcqueue.h"
+#include "multicoremem_helper.h"
+#include "bambooalign.h"
+#ifdef PERFCOUNT
+#include "bme_perf_counter.h"
+#endif
 
-struct pointerblock *gchead=NULL;
-int gcheadindex=0;
-struct pointerblock *gctail=NULL;
-int gctailindex=0;
-struct pointerblock *gctail2=NULL;
-int gctailindex2=0;
-struct pointerblock *gcspare=NULL;
-
-struct lobjpointerblock *gclobjhead=NULL;
-int gclobjheadindex=0;
-struct lobjpointerblock *gclobjtail=NULL;
-int gclobjtailindex=0;
-struct lobjpointerblock *gclobjtail2=NULL;
-int gclobjtailindex2=0;
-struct lobjpointerblock *gclobjspare=NULL;
+volatile bool gcflag;
+gc_status_t gc_status_info;
 
-#ifdef MULTICORE_GC
-#ifdef SMEMM
-extern unsigned int gcmem_mixed_threshold;
-extern unsigned int gcmem_mixed_usedmem;
-#endif // SMEMM
-#endif // MULTICORE_GC
+unsigned long long gc_output_cache_policy_time=0;
 
 #ifdef GC_DEBUG
 // dump whole mem in blocks
-INLINE void dumpSMem() {
+void dumpSMem() {
   int block = 0;
   int sblock = 0;
   unsigned int j = 0;
-  void * i = 0;
+  unsigned int i = 0;
   int coren = 0;
   int x = 0;
   int y = 0;
   printf("(%x,%x) Dump shared mem: \n",udn_tile_coord_x(),udn_tile_coord_y());
   // reserved blocks for sblocktbl
   printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
-      udn_tile_coord_y());
-  for(i=BAMBOO_BASE_VA; (unsinged int)i<(unsigned int)gcbaseva; i+= 4*16) {
+        udn_tile_coord_y());
+  for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
     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",
         udn_tile_coord_x(), udn_tile_coord_y(),
         *((int *)(i)), *((int *)(i + 4)),
@@ -58,38 +44,35 @@ INLINE void dumpSMem() {
         *((int *)(i + 4*12)), *((int *)(i + 4*13)),
         *((int *)(i + 4*14)), *((int *)(i + 4*15)));
   }
-  sblock = gcreservedsb;
+  sblock = 0;
   bool advanceblock = false;
   // remaining memory
-  for(i=gcbaseva;
-      (unsigned int)i<(unsigned int)(gcbaseva+BAMBOO_SHARED_MEM_SIZE); 
-      i+=4*16) {
+  for(i=gcbaseva; (unsigned int)i<(unsigned int)(gcbaseva+BAMBOO_SHARED_MEM_SIZE); i+=4*16) {
     advanceblock = false;
     // computing sblock # and block #, core coordinate (x,y) also
     if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
       // finished a sblock
       if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
-    if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
-      // finished a block
-      block++;
-      advanceblock = true;
-    }
+        if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
+          // finished a block
+          block++;
+          advanceblock = true; 
+        }
       } else {
-    // finished a block
-    block++;
-    advanceblock = true;
+        // finished a block
+        block++;
+        advanceblock = true;
       }
       // compute core #
       if(advanceblock) {
-    coren = gc_block2core[block%(NUMCORES4GC*2)];
+        coren = gc_block2core[block%(NUMCORES4GC*2)];
       }
       // compute core coordinate
       x = BAMBOO_COORDS_X(coren);
       y = BAMBOO_COORDS_Y(coren);
       printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
-         udn_tile_coord_x(), udn_tile_coord_y(),
-             block, sblock++, x, y,
-             (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
+          udn_tile_coord_x(), udn_tile_coord_y(),block, sblock++, x, y,
+          (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
     }
     j++;
     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",
@@ -107,139 +90,140 @@ INLINE void dumpSMem() {
 }
 #endif
 
-INLINE void initmulticoregcdata() {
-  int i = 0;
-  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
-    // startup core to initialize corestatus[]
-    for(i = 0; i < NUMCORESACTIVE; ++i) {
-      gccorestatus[i] = 1;
-      gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
-      gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
-    } 
-    for(i = 0; i < NUMCORES4GC; ++i) {
-      gcloads[i] = 0;
-      gcrequiredmems[i] = 0;
-      gcstopblock[i] = 0;
-      gcfilledblocks[i] = 0;
+bool gc_checkCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    if(gccorestatus[i]) {
+      return false;
     }
   }
+  return true;
+}
+
+void gc_resetCoreStatus() {
+  for(int i = 0; i < NUMCORES4GC; i++) {
+    gccorestatus[i] = 1;
+  }
+}
 
+
+void initmulticoregcdata() {
   bamboo_smem_zero_top = NULL;
   gcflag = false;
-  gcprocessing = false;
-  gcphase = FINISHPHASE;
+  gc_status_info.gcprocessing = false;
+  gc_status_info.gcphase = FINISHPHASE;
+
   gcprecheck = true;
-  gccurr_heaptop = 0;
-  gcself_numsendobjs = 0;
-  gcself_numreceiveobjs = 0;
-  gcmarkedptrbound = 0;
-  gcforwardobjtbl = allocateMGCHash_I(20, 3);
-  gcnumlobjs = 0;
-  gcheaptop = 0;
-  gctopcore = 0;
-  gctopblock = 0;
-  gcmovestartaddr = 0;
-  gctomove = false;
-  gcmovepending = 0;
-  gcblock2fill = 0;
-#ifdef SMEMM
-  gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
-               -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
-  gcmem_mixed_usedmem = 0;
-#endif
+  gcforwardobjtbl = allocateMGCHash_I(128);
 #ifdef MGC_SPEC
   gc_profile_flag = false;
 #endif
-#ifdef GC_FLUSH_DTLB
-  gc_num_flush_dtlb = 0;
-#endif
-  gc_localheap_s = false;
-#ifdef GC_CACHE_ADAPT
-  gccachestage = false;
-#endif 
+
+  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+    allocationinfo.blocktable=RUNMALLOC(sizeof(struct blockrecord)*GCNUMBLOCK);
+    for(int i=0; i<GCNUMBLOCK;i++) {
+      if (1==NUMCORES4GC)
+       allocationinfo.blocktable[i].corenum=0;
+      else
+       allocationinfo.blocktable[i].corenum=gc_block2core[(i%(NUMCORES4GC*2))];
+      allocationinfo.blocktable[i].status=BS_FREE;
+      allocationinfo.blocktable[i].usedspace=0;
+      allocationinfo.blocktable[i].freespace=GLOBALBLOCKSIZE(i);
+    }
+    buildCore2Test();
+  }
+
+  //initialize update structures
+  origarraycount=0;
+  for(int i=0;i<NUMCORES4GC;i++) {
+    origblockarray[i]=NULL;
+  }
 
   INIT_MULTICORE_GCPROFILE_DATA();
 }
 
-INLINE void dismulticoregcdata() {
+void dismulticoregcdata() {
   freeMGCHash(gcforwardobjtbl);
 }
 
-INLINE void initGC() {
-  int i;
+void initGC() {
   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
-    for(i = 0; i < NUMCORES4GC; ++i) {
+    for(int i = 0; i < NUMCORES4GC; i++) {
       gccorestatus[i] = 1;
       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
       gcloads[i] = 0;
       gcrequiredmems[i] = 0;
-      gcfilledblocks[i] = 0;
-      gcstopblock[i] = 0;
     } 
-    for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
+    for(int i = NUMCORES4GC; i < NUMCORESACTIVE; i++) {
       gccorestatus[i] = 1;
       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
     }
-    gcheaptop = 0;
-    gctopcore = 0;
-    gctopblock = 0;
-  gcnumsrobjs_index = 0;
+    gcnumsrobjs_index = 0;
   } 
   gcself_numsendobjs = 0;
   gcself_numreceiveobjs = 0;
-  gcmarkedptrbound = 0;
-  gcnumlobjs = 0;
   gcmovestartaddr = 0;
   gctomove = false;
   gcblock2fill = 0;
   gcmovepending = 0;
   gccurr_heaptop = 0;
-  gcdstcore = 0;
+  update_origblockptr=NULL;
+  gc_queueinit();
 
-  // initialize queue
-  if (gchead==NULL) {
-    gcheadindex=gctailindex=gctailindex2 = 0;
-    gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
-  } else {
-    gctailindex = gctailindex2 = gcheadindex = 0;
-    gctail = gctail2 = gchead;
-  }
-
-  // initialize the large obj queues
-  if (gclobjhead==NULL) {
-    gclobjheadindex=0;
-    gclobjtailindex=0;
-    gclobjtailindex2 = 0;
-    gclobjhead=gclobjtail=gclobjtail2=
-    RUNMALLOC(sizeof(struct lobjpointerblock));
-  } else {
-    gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
-    gclobjtail = gclobjtail2 = gclobjhead;
-  }
-  gclobjhead->next = gclobjhead->prev = NULL;
-
-  freeMGCHash(gcforwardobjtbl);
-  gcforwardobjtbl = allocateMGCHash(20, 3);
+  MGCHashreset(gcforwardobjtbl);
 
   GCPROFILE_INIT();
+  gc_output_cache_policy_time=0;
 } 
 
-INLINE bool gc_checkAllCoreStatus_I() {
-  int i = 0;
-  for(i = 0; i < NUMCORESACTIVE; ++i) {
-    if(gccorestatus[i] != 0) {
-      break;
+void checkMarkStatus_p2() {
+  //  tprintf("Check mark status 2\n");
+  // check if the sum of send objs and receive obj are the same
+  // yes->check if the info is the latest; no->go on executing
+  unsigned int sumsendobj = 0;
+  for(int i = 0; i < NUMCORESACTIVE; i++) {
+    sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
+  } 
+  for(int i = 0; i < NUMCORESACTIVE; i++) {
+    sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
+  } 
+  if(0 == sumsendobj) {
+    // Check if there are changes of the numsendobjs or numreceiveobjs 
+    // on each core
+    int i = 0;
+    for(i = 0; i < NUMCORESACTIVE; i++) {
+      if((gcnumsendobjs[0][i]!=gcnumsendobjs[1][i])||(gcnumreceiveobjs[0][i]!=gcnumreceiveobjs[1][i]) ) {
+        break;
+      }
     }  
-  }  
-  return (i == NUMCORESACTIVE);
+    if(i == NUMCORESACTIVE) {    
+      //tprintf("Mark terminated\n");
+      // all the core status info are the latest,stop mark phase
+      gc_status_info.gcphase = COMPACTPHASE;
+      // restore the gcstatus for all cores
+      for(int i = 0; i < NUMCORESACTIVE; i++) {
+        gccorestatus[i] = 1;
+      }  
+    } else {
+      // There were changes between phase 1 and phase 2, can not decide 
+      // whether the mark phase has been finished
+      waitconfirm = false;
+      // As it fails in phase 2, flip the entries
+      gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+    } 
+  } else {
+    // There were changes between phase 1 and phase 2, can not decide 
+    // whether the mark phase has been finished
+    waitconfirm = false;
+    // As it fails in phase 2, flip the entries
+    gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+  }
 }
 
-INLINE void checkMarkStatue() {
-  int i;
-  if((!waitconfirm) ||
-      (waitconfirm && (numconfirm == 0))) {
+void checkMarkStatus() {
+  //  tprintf("Check mark status\n");
+  if((!waitconfirm)||(waitconfirm && (numconfirm == 0))) {
     unsigned int entry_index = 0;
     if(waitconfirm) {
       // phase 2
@@ -249,69 +233,20 @@ INLINE void checkMarkStatue() {
       entry_index = gcnumsrobjs_index;
     }
     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-    gccorestatus[BAMBOO_NUM_OF_CORE] = 0;  
-    gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
-    gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
     // check the status of all cores
-    bool allStall = gc_checkAllCoreStatus_I();
-    if(allStall) {
+    if (gc_checkCoreStatus()) {
       // ask for confirm
       if(!waitconfirm) {
         // the first time found all cores stall
         // send out status confirm msg to all other cores
         // reset the corestatus array too    
-        gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
         waitconfirm = true;
         numconfirm = NUMCORESACTIVE - 1;
         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-        for(i = 1; i < NUMCORESACTIVE; ++i) {
-          gccorestatus[i] = 1;
-          // send mark phase finish confirm request msg to core i
-          send_msg_1(i, GCMARKCONFIRM, false);
-        }
+        GC_SEND_MSG_1_TO_CLIENT(GCMARKCONFIRM);
       } else {
         // Phase 2
-        // check if the sum of send objs and receive obj are the same
-        // yes->check if the info is the latest; no->go on executing
-        unsigned int sumsendobj = 0;
-        for(i = 0; i < NUMCORESACTIVE; ++i) {
-          sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
-        } 
-        for(i = 0; i < NUMCORESACTIVE; ++i) {
-          sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
-        } 
-        if(0 == sumsendobj) {
-          // Check if there are changes of the numsendobjs or numreceiveobjs on
-          // each core
-          bool ischanged = false;
-          for(i = 0; i < NUMCORESACTIVE; ++i) {
-            if((gcnumsendobjs[0][i] != gcnumsendobjs[1][i]) || 
-                (gcnumreceiveobjs[0][i] != gcnumreceiveobjs[1][i]) ) {
-              ischanged = true;
-              break;
-            }
-          }  
-          if(!ischanged) {    
-            // all the core status info are the latest,stop mark phase
-            gcphase = COMPACTPHASE;
-            // restore the gcstatus for all cores
-            for(i = 0; i < NUMCORESACTIVE; ++i) {
-              gccorestatus[i] = 1;
-            }  
-          } else {
-            // There were changes between phase 1 and phase 2, can not decide 
-            // whether the mark phase has been finished
-            waitconfirm = false;
-            // As it fails in phase 2, flip the entries
-            gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
-          } 
-        } else {
-          // There were changes between phase 1 and phase 2, can not decide 
-          // whether the mark phase has been finished
-          waitconfirm = false;
-          // As it fails in phase 2, flip the entries
-          gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
-        } 
+        checkMarkStatus_p2(); 
         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
       }
     } else {
@@ -321,400 +256,57 @@ INLINE void checkMarkStatue() {
 } 
 
 // compute load balance for all cores
-INLINE int loadbalance(unsigned int * heaptop) {
+int loadbalance() {
   // compute load balance
-  int i;
-
   // get the total loads
-  unsigned int tloads = gcloads[STARTUPCORE];
-  for(i = 1; i < NUMCORES4GC; i++) {
+  void * heaptop;
+  unsigned int tloads = 0;
+  for(int i = 0; i < NUMCORES4GC; i++) {
     tloads += gcloads[i];
+    //tprintf("load: %d %d \n", gcloads[i], i);
   }
-  *heaptop = gcbaseva + tloads;
+  heaptop = gcbaseva + tloads;
 
-  unsigned int b = 0;
-  BLOCKINDEX(*heaptop, &b);
+  unsigned int topblockindex;
+  
+  BLOCKINDEX(topblockindex, heaptop);
   // num of blocks per core
-  unsigned int numbpc = (unsigned int)b/(unsigned int)(NUMCORES4GC);
-  gctopblock = b;
-  RESIDECORE(heaptop, &gctopcore);
-  return numbpc;
-}
-
-// compute total mem size required and sort the lobjs in ascending order
-INLINE unsigned int sortLObjs() {
-  unsigned int tmp_lobj = 0;
-  unsigned int tmp_len = 0;
-  unsigned int tmp_host = 0;
-  unsigned int sumsize = 0;
-
-  gclobjtail2 = gclobjtail;
-  gclobjtailindex2 = gclobjtailindex;
-  // TODO USE QUICK SORT INSTEAD?
-  while(gc_lobjmoreItems2_I()) {
-    gc_lobjdequeue2_I();
-    tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
-    tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
-    tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
-    sumsize += tmp_len;
-    GCPROFILE_RECORD_LOBJ();
-    unsigned int i = gclobjtailindex2-1;
-    struct lobjpointerblock * tmp_block = gclobjtail2;
-    // find the place to insert
-    while(true) {
-      if(i == 0) {
-    if(tmp_block->prev == NULL) {
-      break;
-    }
-    if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
-      tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
-      tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
-      tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
-      tmp_block = tmp_block->prev;
-      i = NUMLOBJPTRS-1;
-    } else {
-      break;
-    }  // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
-      } else {
-    if(tmp_block->lobjs[i-1] > tmp_lobj) {
-      tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
-      tmp_block->lengths[i] = tmp_block->lengths[i-1];
-      tmp_block->hosts[i] = tmp_block->hosts[i-1];
-      i--;
-    } else {
-      break;
-    }  
-      } 
-    }  
-    // insert it
-    if(i != gclobjtailindex2 - 1) {
-      tmp_block->lobjs[i] = tmp_lobj;
-      tmp_block->lengths[i] = tmp_len;
-      tmp_block->hosts[i] = tmp_host;
-    }
-  }
-  return sumsize;
-}
-
-INLINE bool cacheLObjs() {
-  // check the total mem size need for large objs
-  unsigned long long sumsize = 0;
-  unsigned int size = 0;
+  unsigned int numbpc = (topblockindex+NUMCORES4GC-1)/NUMCORES4GC;
   
-  sumsize = sortLObjs();
-
-  GCPROFILE_RECORD_LOBJSPACE();
-
-  // check if there are enough space to cache these large objs
-  unsigned int dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
-  if((unsigned long long)gcheaptop > (unsigned long long)dst) {
-    // do not have enough room to cache large objs
-    return false;
-  }
-
-  gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
-  // cache the largeObjs to the top of the shared heap
-  dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
-  while(gc_lobjmoreItems3_I()) {
-    gc_lobjdequeue3_I();
-    size = gclobjtail2->lengths[gclobjtailindex2];
-    // set the mark field to , indicating that this obj has been moved
-    // and need to be flushed
-    ((struct ___Object___ *)(gclobjtail2->lobjs[gclobjtailindex2]))->marked = 
-      COMPACTED;
-    dst -= size;
-    if((unsigned int)dst < 
-        (unsigned int)(gclobjtail2->lobjs[gclobjtailindex2]+size)) {
-      memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
-    } else {
-      memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
-    }
-  }
-  return true;
-} 
-
-// update the bmmboo_smemtbl to record current shared mem usage
-void updateSmemTbl(unsigned int coren,
-                   unsigned int localtop) {
-  unsigned int ltopcore = 0;
-  unsigned int bound = BAMBOO_SMEM_SIZE_L;
-  BLOCKINDEX(localtop, &ltopcore);
-  if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
-    bound = BAMBOO_SMEM_SIZE;
-  }
-  unsigned int load = (unsigned int)(localtop-gcbaseva)%(unsigned int)bound;
-  unsigned int i = 0;
-  unsigned int j = 0;
-  unsigned int toset = 0;
-  do {
-    toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
-    if(toset < ltopcore) {
-      bamboo_smemtbl[toset]=
-        (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-#ifdef SMEMM
-      gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
-    } else if(toset == ltopcore) {
-      bamboo_smemtbl[toset] = load;
-#ifdef SMEMM
-      gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
-      break;
-    } else {
-      break;
-    }
-    i++;
-    if(i == 2) {
-      i = 0;
-      j++;
-    }
-  } while(true);
-}
-
-INLINE unsigned int checkCurrHeapTop() {
-  // update the smemtbl
-  BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
-  // flush all gcloads to indicate the real heap top on one core
-  // previous it represents the next available ptr on a core
-  if(((unsigned int)gcloads[0] > (unsigned int)(gcbaseva+BAMBOO_SMEM_SIZE_L))
-     && (((unsigned int)gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
-    // edge of a block, check if this is exactly the heaptop
-    BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
-    gcloads[0]+=(gcfilledblocks[0]>1?(BAMBOO_SMEM_SIZE):(BAMBOO_SMEM_SIZE_L));
-  }
-  updateSmemTbl(0, gcloads[0]);
-  for(int i = 1; i < NUMCORES4GC; i++) {
-    unsigned int tmptop = 0;
-    if((gcfilledblocks[i] > 0)
-       && (((unsigned int)gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
-      // edge of a block, check if this is exactly the heaptop
-      BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
-      gcloads[i] +=
-        (gcfilledblocks[i]>1?(BAMBOO_SMEM_SIZE):(BAMBOO_SMEM_SIZE_L));
-      tmptop = gcloads[i];
-    }
-    updateSmemTbl(i, gcloads[i]);
-  } 
-
-  // find current heap top
-  // TODO
-  // a bug here: when using local allocation, directly move large objects
-  // to the highest free chunk might not be memory efficient
-  unsigned int tmpheaptop = 0;
-  int i = 0;
-  for(i = gcnumblock-1; i >= 0; i--) {
-    if(bamboo_smemtbl[i] > 0) {
-      break;
-    }
-  }
-  if(i == -1) {
-    tmpheaptop = gcbaseva;
-  } else {
-    tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
-        (BAMBOO_SMEM_SIZE_L*i) :
-        (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
-  }
-  return tmpheaptop;
+  return numbpc;
 }
 
-INLINE void moveLObjs() {
-#ifdef SMEMM
-  // update the gcmem_mixed_usedmem
-  gcmem_mixed_usedmem = 0;
-#endif
-  unsigned int size = 0;
-  unsigned int bound = 0;
-  unsigned int tmpheaptop = checkCurrHeapTop();
-
-  // move large objs from gcheaptop to tmpheaptop
-  // write the header first
-  unsigned int tomove = gcbaseva+(BAMBOO_SHARED_MEM_SIZE)-gcheaptop;
-#ifdef SMEMM
-  gcmem_mixed_usedmem += tomove;
-#endif
-  // flush the sbstartbl
-  BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
-    (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-(unsigned int)gcreservedsb)
-    *sizeof(unsigned int));
-  if(tomove == 0) {
-    gcheaptop = tmpheaptop;
-  } else {
-    // check how many blocks it acrosses
-    unsigned int remain = tmpheaptop-gcbaseva;
-    //number of the sblock
-    unsigned int sb = remain/BAMBOO_SMEM_SIZE+(unsigned int)gcreservedsb;
-    unsigned int b = 0;  // number of the block
-    BLOCKINDEX(tmpheaptop, &b);
-    // check the remaining space in this block
-    bound = (BAMBOO_SMEM_SIZE);
-    if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
-      bound = (BAMBOO_SMEM_SIZE_L);
-    }
-    remain = bound - remain%bound;
-
-    size = 0;
-    unsigned int isize = 0;
-    unsigned int host = 0;
-    unsigned int ptr = 0;
-    unsigned int base = tmpheaptop;
-    unsigned int cpysize = 0;
-    remain -= BAMBOO_CACHE_LINE_SIZE;
-    tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
-    gc_lobjqueueinit4_I();
-    while(gc_lobjmoreItems4_I()) {
-      ptr = (unsigned int)(gc_lobjdequeue4_I(&size, &host));
-      ALIGNSIZE(size, &isize);
-      if(remain >= isize) {
-    remain -= isize;
-    // move the large obj
-    if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
-      memmove(tmpheaptop, gcheaptop, size);
-    } else {
-      memcpy(tmpheaptop, gcheaptop, size);
-    }
-    // fill the remaining space with -2 padding
-    BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
-
-    gcheaptop += size;
-    cpysize += isize;
-    // cache the mapping info
-    gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=(unsigned int)tmpheaptop;
-    tmpheaptop += isize;
-
-    // update bamboo_smemtbl
-    bamboo_smemtbl[b] += isize;
-      } else {
-    // this object acrosses blocks
-    if(cpysize > 0) {
-      CLOSEBLOCK(base, cpysize+BAMBOO_CACHE_LINE_SIZE);
-      bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;
-      cpysize = 0;
-      base = tmpheaptop;
-      if(remain == 0) {
-        remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
-          BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-      }
-      remain -= BAMBOO_CACHE_LINE_SIZE;
-      tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
-      BLOCKINDEX(tmpheaptop, &b);
-      sb = (unsigned int)(tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE)+gcreservedsb;
-    } 
-
-    // move the large obj
-    if((unsigned int)gcheaptop < (unsigned int)(tmpheaptop+size)) {
-      memmove(tmpheaptop, gcheaptop, size);
-    } else {
-      memcpy(tmpheaptop, gcheaptop, size);
-    }
-    // fill the remaining space with -2 padding
-    BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
-    gcheaptop += size;
-    // cache the mapping info 
-    gcmappingtbl[OBJMAPPINGINDEX((unsigned int)ptr)]=(unsigned int)tmpheaptop;
-    tmpheaptop += isize;
-
-    // set the gcsbstarttbl and bamboo_smemtbl
-    unsigned int tmpsbs=1+(unsigned int)(isize-remain-1)/BAMBOO_SMEM_SIZE;
-    for(int k = 1; k < tmpsbs; k++) {
-      gcsbstarttbl[sb+k] = -1;
-    }
-    sb += tmpsbs;
-    bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-    BLOCKINDEX(tmpheaptop-1, &tmpsbs);
-    for(; b < tmpsbs; b++) {
-      bamboo_smemtbl[b] = bound;
-      if(b==NUMCORES4GC-1) {
-        bound = BAMBOO_SMEM_SIZE;
-      }
-    }
-    if(((unsigned int)(isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
-      gcsbstarttbl[sb] = -1;
-      remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
-           BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-      bamboo_smemtbl[b] = bound;
-    } else {
-      gcsbstarttbl[sb] = (int)tmpheaptop;
-      remain = tmpheaptop-gcbaseva;
-      bamboo_smemtbl[b] = remain%bound;
-      remain = bound - bamboo_smemtbl[b];
-    } 
-
-    CLOSEBLOCK(base, isize+BAMBOO_CACHE_LINE_SIZE);
-    cpysize = 0;
-    base = tmpheaptop;
-    if(remain == BAMBOO_CACHE_LINE_SIZE) {
-      // fill with 0 in case
-      BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
-    }
-    remain -= BAMBOO_CACHE_LINE_SIZE;
-    tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
-      } 
-    }
-
-    if(cpysize > 0) {
-      CLOSEBLOCK(base, cpysize+BAMBOO_CACHE_LINE_SIZE);
-      bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;
-    } else {
-      tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
-    }
-    gcheaptop = tmpheaptop;
-  } 
-
-  bamboo_free_block = 0;
-  unsigned int tbound = 0;
-  do {
-    tbound=(bamboo_free_block<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
-    if(bamboo_smemtbl[bamboo_free_block] == tbound) {
-      bamboo_free_block++;
-    } else {
-      // the first non-full partition
-      break;
-    }
-  } while(true);
-
-  GCPROFILE_RECORD_SPACE();
-} 
-
-INLINE void gc_collect(struct garbagelist * stackptr) {
-  gcprocessing = true;
-  tprintf("gc \n");
+void gc_collect(struct garbagelist * stackptr) {
+  gc_status_info.gcprocessing = true;
   // inform the master that this core is at a gc safe point and is ready to 
   // do gc
-  send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs, 
-    self_numreceiveobjs, false);
+  send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
 
   // core collector routine
-  while(true) {
-    if(INITPHASE == gcphase) {
-      break;
-    }
-  }
+  //wait for init phase
+  WAITFORGCPHASE(INITPHASE);
+
   GC_PRINTF("Do initGC\n");
   initGC();
   CACHEADAPT_GC(true);
   //send init finish msg to core coordinator
-  send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
+  send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
+
+  //wait for mark phase
+  WAITFORGCPHASE(MARKPHASE);
 
-  while(true) {
-    if(MARKPHASE == gcphase) {
-      break;
-    }
-  }
   GC_PRINTF("Start mark phase\n");
-  mark(true, stackptr);
+  mark(stackptr);
   GC_PRINTF("Finish mark phase, start compact phase\n");
   compact();
   GC_PRINTF("Finish compact phase\n");
 
-  while(true) {
-    if(FLUSHPHASE == gcphase) {
-      break;
-    }
-  }
-  GC_PRINTF("Start flush phase\n");
+  WAITFORGCPHASE(UPDATEPHASE);
+
+  GC_PRINTF("Start update phase\n");
   GCPROFILE_INFO_2_MASTER();
-  flush(stackptr);
-  GC_PRINTF("Finish flush phase\n");
+  update(stackptr);
+  GC_PRINTF("Finish update phase\n");
 
   CACHEADAPT_PHASE_CLIENT();
 
@@ -722,55 +314,42 @@ INLINE void gc_collect(struct garbagelist * stackptr) {
   bamboo_cur_msp = NULL;
   bamboo_smem_size = 0;
   bamboo_smem_zero_top = NULL;
-
   gcflag = false;
-  while(true) {
-    if(FINISHPHASE == gcphase) {
-      break;
-    }
-  }
+
+  WAITFORGCPHASE(FINISHPHASE);
 
   GC_PRINTF("Finish gc! \n");
 } 
 
-INLINE void gc_nocollect(struct garbagelist * stackptr) {
-  gcprocessing = true;
-  tprintf("gc \n");
+void gc_nocollect(struct garbagelist * stackptr) {
+  gc_status_info.gcprocessing = true;
   // inform the master that this core is at a gc safe point and is ready to 
   // do gc
-  send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs, 
-    self_numreceiveobjs, false);
+  send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
   
-  while(true) {
-    if(INITPHASE == gcphase) {
-      break;
-    }
-  }
+  WAITFORGCPHASE(INITPHASE);
+
   GC_PRINTF("Do initGC\n");
   initGC();
   CACHEADAPT_GC(true);
+
   //send init finish msg to core coordinator
-  send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
+  send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
+
+
+  WAITFORGCPHASE(MARKPHASE);
 
-  while(true) {
-    if(MARKPHASE == gcphase) {
-      break;
-    }
-  }
   GC_PRINTF("Start mark phase\n"); 
-  mark(true, stackptr);
-  GC_PRINTF("Finish mark phase, wait for flush\n");
+  mark(stackptr);
+  GC_PRINTF("Finish mark phase, wait for update\n");
 
   // non-gc core collector routine
-  while(true) {
-    if(FLUSHPHASE == gcphase) {
-      break;
-    }
-  }
-  GC_PRINTF("Start flush phase\n");
+  WAITFORGCPHASE(UPDATEPHASE);
+
+  GC_PRINTF("Start update phase\n");
   GCPROFILE_INFO_2_MASTER();
-  flush(stackptr);
-  GC_PRINTF("Finish flush phase\n"); 
+  update(stackptr);
+  GC_PRINTF("Finish update phase\n"); 
 
   CACHEADAPT_PHASE_CLIENT();
 
@@ -780,138 +359,51 @@ INLINE void gc_nocollect(struct garbagelist * stackptr) {
   bamboo_smem_zero_top = NULL;
 
   gcflag = false;
-  while(true) {
-    if(FINISHPHASE == gcphase) {
-      break;
-    }
-  }
+  WAITFORGCPHASE(FINISHPHASE);
+
   GC_PRINTF("Finish gc! \n");
 }
 
-INLINE void gc_master(struct garbagelist * stackptr) {
-  gcprocessing = true;
-  tprintf("start GC !!!!!!!!!!!!! \n");
-
-  gcphase = INITPHASE;
-  int i = 0;
-  waitconfirm = false;
-  numconfirm = 0;
-  initGC();
-  GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
-  CACHEADAPT_GC(true);
-  GC_PRINTF("Check core status \n");
-  GC_CHECK_ALL_CORE_STATUS(true);
-  GCPROFILE_ITEM();
-  CACHEADAPT_OUTPUT_CACHE_SAMPLING();
+void master_mark(struct garbagelist *stackptr) {
 
-  GC_PRINTF("(%x,%x) Start mark phase \n");
+  GC_PRINTF("Start mark phase \n");
+  gc_status_info.gcphase = MARKPHASE;
   GC_SEND_MSG_1_TO_CLIENT(GCSTART);
-  gcphase = MARKPHASE;
   // mark phase
-  bool isfirst = true;
-  while(MARKPHASE == gcphase) {
-    mark(isfirst, stackptr);
-    if(isfirst) {
-      isfirst = false;
-    }
 
-    // check gcstatus
-    checkMarkStatue();
-  }
+  mark(stackptr);
+}
 
+void master_getlargeobjs() {
   // send msgs to all cores requiring large objs info
   // Note: only need to ask gc cores, non-gc cores do not host any objs
   numconfirm = NUMCORES4GC - 1;
-  for(i = 1; i < NUMCORES4GC; ++i) {
-    send_msg_1(i, GCLOBJREQUEST, false);
+  for(int i = 1; i < NUMCORES4GC; i++) {
+    send_msg_1(i,GCLOBJREQUEST);
   }
   gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
-  while(true) {
-    if(numconfirm==0) {
-      break;
-    }
-  }   // wait for responses
-  // check the heaptop
-  if(gcheaptop < gcmarkedptrbound) {
-    gcheaptop = gcmarkedptrbound;
-  }
-  GCPROFILE_ITEM();
+  //spin until we have all responses
+  while(numconfirm!=0) ;
+
+  GCPROFILE_ITEM_MASTER();
   GC_PRINTF("prepare to cache large objs \n");
-  // cache all large objs
-  if(!cacheLObjs()) {
-    // no enough space to cache large objs
-    BAMBOO_EXIT(0xb02e);
-  }
-  // predict number of blocks to fill for each core
-  unsigned int tmpheaptop = 0;
-  int numpbc = loadbalance(&tmpheaptop);
-  // TODO
-  numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
-  GC_PRINTF("mark phase finished \n");
-
-  //int tmptopptr = 0;
-  //BASEPTR(gctopcore, 0, &tmptopptr);
-  // TODO
-  //tmptopptr = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
-  tmpheaptop = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
-  for(i = 0; i < NUMCORES4GC; ++i) {
-    unsigned int tmpcoreptr = 0;
-    BASEPTR(i, numpbc, &tmpcoreptr);
-    // init some data strutures for compact phase
-    gcloads[i] = 0;
-    gcfilledblocks[i] = 0;
-    gcrequiredmems[i] = 0;
-    gccorestatus[i] = 1;
-    //send start compact messages to all cores
-    //TODO bug here, do not know if the direction is positive or negtive?
-    if (tmpcoreptr < tmpheaptop) {
-      gcstopblock[i] = numpbc + 1;
-      if(i != STARTUPCORE) {
-        send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
-      } else {
-        gcblock2fill = numpbc+1;
-      }
-    } else {
-      gcstopblock[i] = numpbc;
-      if(i != STARTUPCORE) {
-        send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
-      } else {
-        gcblock2fill = numpbc;
-      }
-    }
-  }
-  BAMBOO_CACHE_MF();
-  GCPROFILE_ITEM();
-  // compact phase
-  struct moveHelper * orig =
-    (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
-  struct moveHelper * to =
-    (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
-  compact_master(orig, to); 
-  GCPROFILE_ITEM();
-  GC_PRINTF("prepare to move large objs \n");
-  // move largeObjs
-  moveLObjs();
-  GC_PRINTF("compact phase finished \n");
-  RUNFREE(orig);
-  RUNFREE(to);
-  orig = to = NULL;
-
-  gcphase = FLUSHPHASE;
-  GC_SEND_MSG_1_TO_CLIENT(GCSTARTFLUSH);
-  GCPROFILE_ITEM();
-  GC_PRINTF("Start flush phase \n");
-  // flush phase
-  flush(stackptr);
-  // now the master core need to decide the new cache strategy
-  CACHEADAPT_MASTER();
-  GC_CHECK_ALL_CORE_STATUS(FLUSHPHASE==gcphase);
-  GC_PRINTF("Finish flush phase \n");
 
-  CACHEADAPT_PHASE_MASTER();
+}
+
 
-  gcphase = FINISHPHASE;
+void master_updaterefs(struct garbagelist * stackptr) {
+  gc_status_info.gcphase = UPDATEPHASE;
+  GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
+  GC_PRINTF("Start update phase \n");
+  // update phase
+  update(stackptr);
+  GC_CHECK_ALL_CORE_STATUS();
+  GC_PRINTF("Finish update phase \n");
+}
 
+void master_finish() {
+  gc_status_info.gcphase = FINISHPHASE;
+  
   // invalidate all shared mem pointers
   // put it here as it takes time to inform all the other cores to
   // finish gc and it might cause problem when some core resumes
@@ -919,14 +411,19 @@ INLINE void gc_master(struct garbagelist * stackptr) {
   bamboo_cur_msp = NULL;
   bamboo_smem_size = 0;
   bamboo_smem_zero_top = NULL;
-
-  GCPROFILE_ITEM();
+  
+  GCPROFILE_END_MASTER();
+  unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
+  CACHEADAPT_OUTPUT_CACHE_POLICY();
+  gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
   gcflag = false;
+
   GC_SEND_MSG_1_TO_CLIENT(GCFINISH);
+  gc_status_info.gcprocessing = false;  
 
-  gcprocessing = false;
   if(gcflag) {
     // inform other cores to stop and wait for gc
+    GC_PRINTF("Back to Back gc case\n");
     gcprecheck = true;
     for(int i = 0; i < NUMCORESACTIVE; i++) {
       // reuse the gcnumsendobjs & gcnumreceiveobjs
@@ -935,20 +432,64 @@ INLINE void gc_master(struct garbagelist * stackptr) {
     }
     GC_SEND_MSG_1_TO_CLIENT(GCSTARTPRE);
   }
-  GC_PRINTF("gc finished   \n");
-  tprintf("finish GC ! %d \n", gcflag);
+}
+
+void gc_master(struct garbagelist * stackptr) {
+  tprintf("start GC!\n");
+  gc_status_info.gcprocessing = true;
+  gc_status_info.gcphase = INITPHASE;
+
+  waitconfirm = false;
+  numconfirm = 0;
+  initGC();
+  GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
+  CACHEADAPT_GC(true);
+  //tprintf("Check core status \n");
+  GC_CHECK_ALL_CORE_STATUS();
+  GCPROFILE_ITEM_MASTER();
+  unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
+  CACHEADAPT_OUTPUT_CACHE_SAMPLING();
+  gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
+  //tprintf("start mark phase\n");
+  // do mark phase
+  master_mark(stackptr);
+  GCPROFILE_ITEM_MASTER();
+  //tprintf("finish mark phase\n");
+  // get large objects from all cores
+  master_getlargeobjs();
+  //tprintf("start compact phase\n");
+  // compact the heap
+  master_compact();
+  //tprintf("start update phase\n");
+  // update the references
+  master_updaterefs(stackptr);
+  //tprintf("gc master finished update   \n");
+  // do cache adaptation
+  CACHEADAPT_PHASE_MASTER();
+  //tprintf("finish cachdapt phase\n");
+  // do finish up stuff
+#ifdef GC_DEBUG
+  for(int i=0;i<GCNUMBLOCK;i++) {
+    struct blockrecord *record=&allocationinfo.blocktable[i];
+    tprintf("%u. used=%u free=%u corenum=%u status=%u, base=%x, ptr=%x\n", i, record->usedspace, record->freespace, record->corenum, record->status, gcbaseva+OFFSET2BASEVA(i), (gcbaseva+OFFSET2BASEVA(i)+record->usedspace));
+  }
+#endif
+
+  master_finish();
+
+  //tprintf("finish GC ! %d \n",gcflag);
 } 
 
-INLINE void pregccheck_I() {
+void pregccheck() {
   while(true) {
+    BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
     gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
     gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
     int sumsendobj = 0;
-    int i = 0;
-    for(i = 0; i < NUMCORESACTIVE; ++i) {
+    for(int i = 0; i < NUMCORESACTIVE; i++) {
       sumsendobj += gcnumsendobjs[0][i];
     }  
-    for(i = 0; i < NUMCORESACTIVE; ++i) {
+    for(int i = 0; i < NUMCORESACTIVE; i++) {
       sumsendobj -= gcnumreceiveobjs[0][i];
     } 
     if(0 != sumsendobj) {
@@ -956,80 +497,60 @@ INLINE void pregccheck_I() {
       // are some update pregc information coming and check it again
       gcprecheck = false;
       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-      while(true) {
-        if(gcprecheck) {
-          break;
-        }
-      }
-      BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+
+      while(!gcprecheck) ;
     } else {
+      BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
       return;
     }
   }
 }
 
-INLINE void pregcprocessing() {
-#ifdef GC_CACHE_ADAPT
-#ifdef GC_CACHE_SAMPLING
+void pregcprocessing() {
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
   // disable the timer interrupt
   bamboo_mask_timer_intr();
-#endif 
-#endif
-  // Zero out the remaining memory here because for the GC_CACHE_ADAPT version,
-  // we need to make sure during the gcinit phase the shared heap is not 
-  // touched. Otherwise, there would be problem when adapt the cache strategy.
-  BAMBOO_CLOSE_CUR_MSP();
-#ifdef GC_FLUSH_DTLB
-  if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
-    BAMBOO_CLEAN_DTLB();
-    gc_num_flush_dtlb++;
-  }
-#endif
-#ifdef GC_CACHE_ADAPT
-#ifdef GC_CACHE_SAMPLING
   // get the sampling data 
   bamboo_output_dtlb_sampling();
 #endif
-#endif
 }
 
-INLINE void postgcprocessing() {
-#ifdef GC_CACHE_ADAPT
-#ifdef GC_CACHE_SAMPLING
+void postgcprocessing() {
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
   // enable the timer interrupt
   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); 
   bamboo_unmask_timer_intr();
-#endif
+  //turn on sampling again
+  bamboo_dtlb_sampling_init();
 #endif
 }
 
-INLINE bool gc(struct garbagelist * stackptr) {
+bool gc(struct garbagelist * stackptr) {
   // check if do gc
   if(!gcflag) {
-    gcprocessing = false;
+    gc_status_info.gcprocessing = false;
     return false;
   }
+#ifdef PERFCOUNT
+  profile_start(GC_REGION);
+#endif
 
   // core coordinator routine
   if(0 == BAMBOO_NUM_OF_CORE) {
     GC_PRINTF("Check if we can do gc or not\n");
     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-    BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-    if(!gc_checkAllCoreStatus_I()) {
-      BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-      // some of the cores are still executing the mutator and did not reach
-      // some gc safe point, therefore it is not ready to do gc
-      gcflag = true;
-      return false;
-    } else {
-      GCPROFILE_START();
-      pregccheck_I();
-      BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-    }
+
+    //wait for other cores to catch up
+    while(!gc_checkCoreStatus())
+      ;
+
+    pregccheck();
+    GCPROFILE_START_MASTER();
     GC_PRINTF("start gc! \n");
     pregcprocessing();
     gc_master(stackptr);
   } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
+    GC_PRINTF("Core reporting for gc.\n");
     pregcprocessing();
     gc_collect(stackptr);
   } else {
@@ -1037,7 +558,9 @@ INLINE bool gc(struct garbagelist * stackptr) {
     gc_nocollect(stackptr);
   }
   postgcprocessing();
-
+#ifdef PERFCOUNT
+  profile_start(APP_REGION);
+#endif
   return true;
 }