bug fix + temporary debug code to be removed
[IRC.git] / Robust / src / Runtime / bamboo / multicoregcmark.c
index 889e4506cb9ce0c00af4325d3fe667ead9c67940..71a23c48e9776cfdac386cdee15549be4169e60a 100644 (file)
@@ -1,9 +1,11 @@
 #ifdef MULTICORE_GC
-#include "multicoregcmark.h"
 #include "runtime.h"
 #include "multicoreruntime.h"
 #include "GenericHashtable.h"
 #include "gcqueue.h"
+#include "multicoregcmark.h"
+#include "multicoregarbage.h"
+#include "markbit.h"
 
 #ifdef TASK
 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
@@ -17,18 +19,12 @@ extern int runtime_locklen;
 
 extern struct global_defs_t * global_defs_p;
 
-#ifdef SMEMM
-extern unsigned int gcmem_mixed_threshold;
-extern unsigned int gcmem_mixed_usedmem;
-#endif
-
 #ifdef MGC
 extern struct lockvector bamboo_threadlocks;
 #endif
 
 INLINE void gettype_size(void * ptr, int * ttype, unsigned int * tsize) {
   int type = ((int *)ptr)[0];
-  unsigned int size;
   if(type < NUMCLASSES) {
     // a normal object
     *tsize = classsize[type];
@@ -44,91 +40,65 @@ INLINE void gettype_size(void * ptr, int * ttype, unsigned int * tsize) {
 }
 
 INLINE bool isLarge(void * ptr, int * ttype, unsigned int * tsize) {
-  // check if a pointer is referring to a large object
+  // check if a pointer refers to a large object
   gettype_size(ptr, ttype, tsize);
-  unsigned int bound = (BAMBOO_SMEM_SIZE);
-  if(((unsigned int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
-    bound = (BAMBOO_SMEM_SIZE_L);
-  }
-  // ptr is a start of a block  OR it acrosses the boundary of current block
-  return (((((unsigned int)ptr-gcbaseva)%(bound))==0)||
-         ((bound-(((unsigned int)ptr-gcbaseva)%bound)) < (*tsize)));
-}
+  unsigned INTPTR blocksize = (((unsigned INTPTR)(ptr-gcbaseva)) < BAMBOO_LARGE_SMEM_BOUND)? BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
 
-INLINE unsigned int hostcore(void * ptr) {
-  // check the host core of ptr
-  unsigned int host = 0;
-  if(1 == (NUMCORES4GC)) { 
-    host = 0; 
-  } else { 
-    unsigned int b;
-    unsigned int t = (unsigned int)ptr - (unsigned int)gcbaseva; 
-    if(t < (BAMBOO_LARGE_SMEM_BOUND)) { 
-      b = t / (BAMBOO_SMEM_SIZE_L); 
-    } else { 
-      b = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); 
-    } 
-    host = gc_block2core[(b%(NUMCORES4GC*2))];
-  }
-  return host;
+  // ptr is a start of a block  OR it crosses the boundary of current block
+  return (*tsize) > blocksize;
 }
+
 //push the null check into the mark macro
-//#define MARKOBJ(objptr, ii) {void * marktmpptr=objptr; if (marktmpptr!=NULL) markObj(marktmpptr, __LINE__, ii);}
 
-//#define MARKOBJNONNULL(objptr, ii) {markObj(objptr, __LINE__, ii);}
+//#define MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {markObj(marktmpptr);if ((marktmpptr<gcbaseva)||(marktmpptr>(gcbaseva+BAMBOO_SHARED_MEM_SIZE))) tprintf("Bad pointer %x in line %u\n",marktmpptr, __LINE__);  }}
 
-#define MARKOBJ(objptr, ii) {void * marktmpptr=objptr; if (marktmpptr!=NULL) markObj(marktmpptr);}
+#define MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {markObj(marktmpptr);}}
 
-#define MARKOBJNONNULL(objptr, ii) {markObj(objptr);}
+#define MARKOBJNONNULL(objptr) {markObj(objptr);}
 
 // NOTE: the objptr should not be NULL and should be a shared obj
-INLINE void markObj(void * objptr) {
+void markObj(void * objptr) {
   unsigned int host = hostcore(objptr);
   if(BAMBOO_NUM_OF_CORE == host) {
     // on this core
-    if(((struct ___Object___ *)objptr)->marked == INIT) {
+    if(!checkAndCondSetMark(objptr)) {
       // this is the first time that this object is discovered,
       // set the flag as DISCOVERED
-      ((struct ___Object___ *)objptr)->marked = DISCOVERED;
-      BAMBOO_CACHE_FLUSH_LINE(objptr);
       gc_enqueue(objptr);
     }
   } else {
-    // check if this obj has been forwarded
-    if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
-      // send a msg to host informing that objptr is active
+    // check if this obj has been forwarded already
+    if(MGCHashadd(gcforwardobjtbl, (unsigned int)objptr)) {
+      // if not, send msg to host informing that objptr is active
       send_msg_2(host,GCMARKEDOBJ,objptr);
       GCPROFILE_RECORD_FORWARD_OBJ();
       gcself_numsendobjs++;
-      MGCHashadd(gcforwardobjtbl, (int)objptr);
     }
   }
-} 
+}
 
-INLINE void markgarbagelist(struct garbagelist * listptr) {
+void markgarbagelist(struct garbagelist * listptr) {
   for(;listptr!=NULL;listptr=listptr->next) {
     int size=listptr->size;
     for(int i=0; i<size; i++) {
-      MARKOBJ(listptr->array[i], i);
+      MARKOBJ(listptr->array[i]);
     }
   }
 }
 
 // enqueue root objs
-INLINE void tomark(struct garbagelist * stackptr) {
+void tomark(struct garbagelist * stackptr) {
   BAMBOO_ASSERT(MARKPHASE == gc_status_info.gcphase);
-
+  
   gc_status_info.gcbusystatus = true;
-  gcnumlobjs = 0;
-
+  
   // enqueue current stack
   markgarbagelist(stackptr);
-
+  
   // enqueue static pointers global_defs_p
   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
     markgarbagelist((struct garbagelist *)global_defs_p);
   }
-
 #ifdef TASK
   // enqueue objectsets
   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
@@ -140,28 +110,28 @@ INLINE void tomark(struct garbagelist * stackptr) {
         struct ObjectHash * set=parameter->objectset;
         struct ObjectNode * ptr=set->listhead;
         for(;ptr!=NULL;ptr=ptr->lnext) {
-          MARKOBJNONNULL((void *)ptr->key, 0);
+          MARKOBJNONNULL((void *)ptr->key);
         }
       }
     }
   }
-
-  // euqueue current task descriptor
+  
+  // enqueue current task descriptor
   if(currtpd != NULL) {
     for(int i=0; i<currtpd->numParameters; i++) {
       // currtpd->parameterArray[i] can not be NULL
-      MARKOBJNONNULL(currtpd->parameterArray[i], i);
+      MARKOBJNONNULL(currtpd->parameterArray[i]);
     }
   }
 
-  // euqueue active tasks
+  // enqueue active tasks
   if(activetasks != NULL) {
     struct genpointerlist * ptr=activetasks->list;
     for(;ptr!=NULL;ptr=ptr->inext) {
       struct taskparamdescriptor *tpd=ptr->src;
       for(int i=0; i<tpd->numParameters; i++) {
         // the tpd->parameterArray[i] can not be NULL
-        MARKOBJNONNULL(tpd->parameterArray[i], i);
+        MARKOBJNONNULL(tpd->parameterArray[i]);
       }
     }
   }
@@ -171,7 +141,7 @@ INLINE void tomark(struct garbagelist * stackptr) {
   for(;tmpobjptr != NULL;tmpobjptr=getNextQueueItem(tmpobjptr)) {
     struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
     // the objptr can not be NULL
-    MARKOBJNONNULL(objInfo->objptr, 0);
+    MARKOBJNONNULL(objInfo->objptr);
   }
 
   // enqueue cached objs to be transferred
@@ -179,13 +149,13 @@ INLINE void tomark(struct garbagelist * stackptr) {
   for(;item != NULL;item=getNextQueueItem(item)) {
     struct transObjInfo * totransobj=(struct transObjInfo *)(item->objectptr);
     // the objptr can not be NULL
-    MARKOBJNONNULL(totransobj->objptr, 0);
+    MARKOBJNONNULL(totransobj->objptr);
   }
 
   // enqueue lock related info
   for(int i = 0; i < runtime_locklen; i++) {
-    MARKOBJ((void *)(runtime_locks[i].redirectlock), 0);
-    MARKOBJ((void *)(runtime_locks[i].value), i);
+    MARKOBJ((void *)(runtime_locks[i].redirectlock));
+    MARKOBJ((void *)(runtime_locks[i].value));
   }
 #endif 
 
@@ -198,20 +168,18 @@ INLINE void tomark(struct garbagelist * stackptr) {
       unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
       for(int i = thread_counter; i > 0; i--) {
         // the thread obj can not be NULL
-        MARKOBJNONNULL((void *)bamboo_thread_queue[4+start], 0);
+        MARKOBJNONNULL((void *)bamboo_thread_queue[4+start]);
         start = (start+1)&bamboo_max_thread_num_mask;
       }
     }
   }
-
   // enqueue the bamboo_threadlocks
   for(int i = 0; i < bamboo_threadlocks.index; i++) {
     // the locks can not be NULL
-    MARKOBJNONNULL((void *)(bamboo_threadlocks.locks[i].object), i);
+    MARKOBJNONNULL((void *)(bamboo_threadlocks.locks[i].object));
   }
-
   // enqueue the bamboo_current_thread
-  MARKOBJ((void *)bamboo_current_thread, 0);
+  MARKOBJ(bamboo_current_thread);
 #endif
 }
 
@@ -227,7 +195,7 @@ INLINE void scanPtrsInObj(void * ptr, int type) {
     for(int i=1; i<=size; i++) {
       unsigned int offset=pointer[i];
       void * objptr=*((void **)(((char *)ptr)+offset));
-      MARKOBJ(objptr, i);
+      MARKOBJ(objptr);
     }
 #endif
   } else if (((unsigned int)pointer)==1) {
@@ -236,7 +204,7 @@ INLINE void scanPtrsInObj(void * ptr, int type) {
     int length=ao->___length___;
     for(int i=0; i<length; i++) {
       void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
-      MARKOBJ(objptr, i);
+      MARKOBJ(objptr);
     }
 #ifdef OBJECTHASPOINTERS
     pointer=pointerarray[OBJECTTYPE];
@@ -245,7 +213,7 @@ INLINE void scanPtrsInObj(void * ptr, int type) {
     for(int i=1; i<=size; i++) {
       unsigned int offset=pointer[i];
       void * objptr=*((void **)(((char *)ptr)+offset));
-      MARKOBJ(objptr, i);
+      MARKOBJ(objptr);
     }
 #endif
   } else {
@@ -254,75 +222,80 @@ INLINE void scanPtrsInObj(void * ptr, int type) {
     for(int i=1; i<=size; i++) {
       unsigned int offset=pointer[i];
       void * objptr=*((void **)(((char *)ptr)+offset));
-      MARKOBJ(objptr, i);
+      MARKOBJ(objptr);
     }
   }
 }
 
-INLINE void mark(bool isfirst, struct garbagelist * stackptr) {
-  if(isfirst) {
-    // enqueue root objs
-    tomark(stackptr);
-    gccurr_heaptop = 0; // record the size of all active objs in this core
-                        // aligned but does not consider block boundaries
-    gcmarkedptrbound = 0;
-  }
+void mark(struct garbagelist * stackptr) {
+  // enqueue root objs
+  tomark(stackptr);
+
   unsigned int isize = 0;
   bool sendStall = false;
   // mark phase
   while(MARKPHASE == gc_status_info.gcphase) {
     int counter = 0;
-    while(gc_moreItems2()) {
+    while(gc_moreItems()) {
       sendStall = false;
       gc_status_info.gcbusystatus = true;
-      unsigned int ptr = gc_dequeue2();
-
+      void * ptr = gc_dequeue();
       unsigned int size = 0;
-      unsigned int isize = 0;
       unsigned int type = 0;
-      // check if it is a local obj on this core
-      if(((struct ___Object___ *)ptr)->marked!=DISCOVERED) {
-        // ptr has been marked
-        continue;
-      } else if(isLarge(ptr, &type, &size)) {
+      bool islarge=isLarge(ptr, &type, &size);
+      unsigned int iunits = ALIGNUNITS(size);
+
+      //debugging for the next five lines
+      unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
+      unsigned INTPTR hibits=alignsize>>4;
+      unsigned INTPTR lobits=(alignsize&15)<<1;
+      unsigned INTPTR ohigh=gcmarktbl[hibits];
+      unsigned INTPTR olow=gcmarktbl[hibits+1];
+      setLengthMarked(ptr,iunits);
+      unsigned int unit=getMarkedLength(ptr);
+      if (unit!=iunits) {
+       tprintf("Bad mark on %x %u!=%u\n", ptr, unit, iunits);
+       tprintf("hibits=%x lobits=%x\n", hibits, lobits);
+       tprintf("ohigh=%x olow=%x", ohigh, olow);
+       unsigned INTPTR nhigh=gcmarktbl[hibits];
+       unsigned INTPTR nlow=gcmarktbl[hibits+1];
+       tprintf("nhigh=%x nlow=%x", nhigh, nlow);
+      }
+
+      if(islarge) {
         // ptr is a large object and not marked or enqueued
-        gc_lobjenqueue(ptr, size, BAMBOO_NUM_OF_CORE);
-        gcnumlobjs++;
+       printf("NEED TO SUPPORT LARGE OBJECTS!\n");
       } else {
         // ptr is an unmarked active object on this core
-        ALIGNSIZE(size, &isize);
+       unsigned int isize=iunits<<ALIGNMENTSHIFT;
         gccurr_heaptop += isize;
-       
-        if((unsigned int)(ptr + size) > (unsigned int)gcmarkedptrbound) {
-          gcmarkedptrbound = (unsigned int)(ptr + size);
-        }
       }
-      // mark this obj
-      ((struct ___Object___ *)ptr)->marked = MARKED;
-      BAMBOO_CACHE_FLUSH_LINE(ptr);
       // scan the pointers in object
-      scanPtrsInObj(ptr, type);      
-    }   
-    gc_status_info.gcbusystatus = false;
-    // send mark finish msg to core coordinator
-    if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
-      int entry_index = waitconfirm ? (gcnumsrobjs_index==0) : gcnumsrobjs_index;
-      gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
-      gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
-      gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numreceiveobjs;
-      gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
-    } else {
-      if(!sendStall) {
-        send_msg_4(STARTUPCORE,GCFINISHMARK,BAMBOO_NUM_OF_CORE,gcself_numsendobjs,gcself_numreceiveobjs);
-        sendStall = true;
+      scanPtrsInObj(ptr, type);
+    }
+
+    BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+    //make sure the queue is still empty...now we have interrupts off, things can't change on us...
+
+    if (!gc_moreItems_I()) {
+      gc_status_info.gcbusystatus = false;
+      // send mark finish msg to core coordinator
+      if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+       int entry_index = waitconfirm ? (gcnumsrobjs_index==0) : gcnumsrobjs_index;
+       gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+       gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
+       gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE]=gcself_numreceiveobjs;
+       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+       checkMarkStatus();
+      } else {
+       if(!sendStall) {
+         send_msg_4(STARTUPCORE,GCFINISHMARK,BAMBOO_NUM_OF_CORE,gcself_numsendobjs,gcself_numreceiveobjs);
+         sendStall = true;
+       }
+       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
       }
     }
-    
-    if(BAMBOO_NUM_OF_CORE == STARTUPCORE)
-      return;
   }
-
-  BAMBOO_CACHE_MF();
 } 
 
 #endif // MULTICORE_GC