start to implement second garbage collector to benchmark against...
authorbdemsky <bdemsky>
Tue, 5 Jul 2011 03:11:42 +0000 (03:11 +0000)
committerbdemsky <bdemsky>
Tue, 5 Jul 2011 03:11:42 +0000 (03:11 +0000)
collector is described in "Parallel Garbage Collection for Shared Memory Multiprocessors"

Robust/src/Runtime/bamboo/pmc_forward.c [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_forward.h [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_garbage.c [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_garbage.h [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_mark.c [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_mark.h [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_refupdate.c [new file with mode: 0644]
Robust/src/Runtime/bamboo/pmc_refupdate.h [new file with mode: 0644]

diff --git a/Robust/src/Runtime/bamboo/pmc_forward.c b/Robust/src/Runtime/bamboo/pmc_forward.c
new file mode 100644 (file)
index 0000000..007466f
--- /dev/null
@@ -0,0 +1,51 @@
+#include "pmc_forward.h"
+
+
+//Comment: should build dummy byte arrays to allow skipping data...
+void pmc_countbytes(struct pmc_region * region, void *bottomptr, void *topptr) {
+  void *tmpptr=bottomptr;
+  unsigned int totalbytes=0;
+  while(tmpptr<topptr) {
+    unsigned int type;
+    unsigned int size;
+    gettype_size(tmpptr, &type, &size);
+    if (!type) {
+      tmpptr+=ALIGNMENTSIZE;
+      continue;
+    }
+    size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
+    if (((struct ___Object___ *)tmpptr)->mark)
+      totalbytes+=size;
+    tmpptr+=size;
+  }
+  region->numbytes=totalbytes;
+}
+
+
+void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool fwddirection) {
+  void *tmpptr=bottomptr;
+  void *forwardptr=fwddirection?bottomptr:(topptr-totalbytes);
+  struct ___Object___ *lastobj=NULL;
+
+  while(tmpptr>topptr) {
+    unsigned int type;
+    unsigned int size;
+    gettype_size(tmpptr, &type, &size);
+    if (!type) {
+      tmpptr+=ALIGNMENTSIZE;
+      continue;
+    }
+    size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
+
+    if (((struct ___Object___ *)tmpptr)->mark) {
+      ((struct ___Object___ *)tmpptr)->mark=forwardptr;
+      forwardptr+=size;
+      if (lastobj&&!fwddirection) {
+       tmpptr->backward=lastobj;
+       lastobj=(struct ___Object___ *)tmpptr;
+      }
+    }
+    tmpptr+=size;
+  }
+  region->lastobj=lastobj;
+}
diff --git a/Robust/src/Runtime/bamboo/pmc_forward.h b/Robust/src/Runtime/bamboo/pmc_forward.h
new file mode 100644 (file)
index 0000000..418ce98
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef PMC_FORWARD_H
+#define PMC_FORWARD_H
+#include "pmc_garbage.h"
+
+void pmc_countbytes(struct pmc_unit * region, void *bottomptr, void *topptr);
+
+void pmc_forward(unsigned int totalbytes, void *bottomptr, void *topptr, bool fwddirection);
+
+
+#endif
diff --git a/Robust/src/Runtime/bamboo/pmc_garbage.c b/Robust/src/Runtime/bamboo/pmc_garbage.c
new file mode 100644 (file)
index 0000000..a9bfd48
--- /dev/null
@@ -0,0 +1,2 @@
+#include "pmc_garbage.h"
+
diff --git a/Robust/src/Runtime/bamboo/pmc_garbage.h b/Robust/src/Runtime/bamboo/pmc_garbage.h
new file mode 100644 (file)
index 0000000..dc3e202
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef PMC_GARBAGE_H
+#define PMC_GARBAGE_H
+struct pmc_unit {
+  unsigned int lock;
+  unsigned int numbytes;
+};
+
+struct pmc_region {
+  void * lastptr;
+  struct ___Object___ * lastobj;
+};
+
+struct pmc_heap {
+  struct pmc_region units[NUMCORES4GC*4];
+  struct pmc_region regions[NUMCORES4GC];
+  unsigned int lock;
+  unsigned int numthreads;
+};
+
+extern struct pmc_heap * pmc_heapptr;
+
+#endif
diff --git a/Robust/src/Runtime/bamboo/pmc_mark.c b/Robust/src/Runtime/bamboo/pmc_mark.c
new file mode 100644 (file)
index 0000000..f7dd408
--- /dev/null
@@ -0,0 +1,150 @@
+#include "pmc_mark.h"
+
+#define PMC_MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {pmc_markObj(marktmpptr);}}
+
+#define PMC_MARKOBJNONNULL(objptr) {pmc_markObj(objptr);}
+
+void pmc_markObj(struct ___Object___ *ptr) {
+  if (!ptr->mark) {
+    ptr->mark=1;
+    pmc_enqueue(ptr);
+  }
+}
+
+void pmc_scanPtrsInObj(void * ptr, int type) {
+  // scan all pointers in ptr
+  unsigned int * pointer = pointerarray[type];
+  if (pointer==0) {
+    /* Array of primitives */
+  } else if (((unsigned int)pointer)==1) {
+    /* Array of pointers */
+    struct ArrayObject *ao=(struct ArrayObject *) ptr;
+    int length=ao->___length___;
+    for(int i=0; i<length; i++) {
+      void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
+      PMC_MARKOBJ(objptr);
+    }
+  } else {
+    /* Normal Object */
+    int size=pointer[0];
+    for(int i=1; i<=size; i++) {
+      unsigned int offset=pointer[i];
+      void * objptr=*((void **)(((char *)ptr)+offset));
+      PMC_MARKOBJ(objptr);
+    }
+  }
+}
+
+void pmc_markgarbagelist(struct garbagelist * listptr) {
+  for(;listptr!=NULL;listptr=listptr->next) {
+    int size=listptr->size;
+    for(int i=0; i<size; i++) {
+      PMC_MARKOBJ(listptr->array[i]);
+    }
+  }
+}
+
+void pmc_mark(struct garbagelist *stackptr) {
+  pmc_tomark(stackptr);
+  while(true) {
+    pmc_marklocal();
+    
+    
+  }
+}
+
+void pmc_marklocal() {
+  
+}
+
+void pmc_tomark(struct garbagelist * stackptr) {
+  // enqueue current stack
+  pmc_markgarbagelist(stackptr);
+  
+  // enqueue static pointers global_defs_p
+  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+    pmc_markgarbagelist((struct garbagelist *)global_defs_p);
+  }
+#ifdef TASK
+  // enqueue objectsets
+  if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
+    for(int i=0; i<NUMCLASSES; i++) {
+      struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
+      int length = numqueues[BAMBOO_NUM_OF_CORE][i];
+      for(int j = 0; j < length; ++j) {
+        struct parameterwrapper * parameter = queues[j];
+        struct ObjectHash * set=parameter->objectset;
+        struct ObjectNode * ptr=set->listhead;
+        for(;ptr!=NULL;ptr=ptr->lnext) {
+          PMC_MARKOBJNONNULL((void *)ptr->key);
+        }
+      }
+    }
+  }
+  
+  // enqueue current task descriptor
+  if(currtpd != NULL) {
+    for(int i=0; i<currtpd->numParameters; i++) {
+      // currtpd->parameterArray[i] can not be NULL
+      PMC_MARKOBJNONNULL(currtpd->parameterArray[i]);
+    }
+  }
+
+  // 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
+        PMC_MARKOBJNONNULL(tpd->parameterArray[i]);
+      }
+    }
+  }
+
+  // enqueue cached transferred obj
+  struct QueueItem * tmpobjptr =  getHead(&objqueue);
+  for(;tmpobjptr != NULL;tmpobjptr=getNextQueueItem(tmpobjptr)) {
+    struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
+    // the objptr can not be NULL
+    PMC_MARKOBJNONNULL(objInfo->objptr);
+  }
+
+  // enqueue cached objs to be transferred
+  struct QueueItem * item = getHead(totransobjqueue);
+  for(;item != NULL;item=getNextQueueItem(item)) {
+    struct transObjInfo * totransobj=(struct transObjInfo *)(item->objectptr);
+    // the objptr can not be NULL
+    PMC_MARKOBJNONNULL(totransobj->objptr);
+  }
+
+  // enqueue lock related info
+  for(int i = 0; i < runtime_locklen; i++) {
+    PMC_MARKOBJ((void *)(runtime_locks[i].redirectlock));
+    PMC_MARKOBJ((void *)(runtime_locks[i].value));
+  }
+#endif 
+
+#ifdef MGC
+  // enqueue global thread queue
+  if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+    lockthreadqueue();
+    unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
+    if(thread_counter > 0) {
+      unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
+      for(int i = thread_counter; i > 0; i--) {
+        // the thread obj can not be NULL
+        PMC_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
+    PMC_MARKOBJNONNULL((void *)(bamboo_threadlocks.locks[i].object));
+  }
+  // enqueue the bamboo_current_thread
+  PMC_MARKOBJ(bamboo_current_thread);
+#endif
+}
diff --git a/Robust/src/Runtime/bamboo/pmc_mark.h b/Robust/src/Runtime/bamboo/pmc_mark.h
new file mode 100644 (file)
index 0000000..cb348ac
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef PMC_MARK_H
+#define PMC_MARK_H
+
+void pmc_markObj(struct ___Object___ *ptr);
+void pmc_scanPtrsInObj(void * ptr, int type);
+void pmc_mark(struct garbagelist *stackptr);
+void pmc_tomark(struct garbagelist * stackptr);
+void pmc_markgarbagelist(struct garbagelist * listptr);
+
+#endif
diff --git a/Robust/src/Runtime/bamboo/pmc_refupdate.c b/Robust/src/Runtime/bamboo/pmc_refupdate.c
new file mode 100644 (file)
index 0000000..780d615
--- /dev/null
@@ -0,0 +1,88 @@
+#include "pmc_forward.h"
+#include "pmc_refupdate.h"
+
+#define pmcupdateObj(objptr) ((void *)((struct ___Object___ *)objptr)->mark)
+
+#define PMCUPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) {obj=pmcupdateObj(updatetmpptr);}}
+
+#define PMCUPDATEOBJNONNULL(obj) {void *updatetmpptr=obj; obj=pmcupdateObj(updatetmpptr);}
+
+void pmc_updatePtrs(void *ptr, int type) {
+  unsigned int * pointer=pointerarray[type];
+  if (pointer==0) {
+    /* Array of primitives */
+  } else if (((unsigned int)pointer)==1) {
+    /* Array of pointers */
+    struct ArrayObject *ao=(struct ArrayObject *) ptr;
+    int length=ao->___length___;
+    for(int j=0; j<length; j++) {
+      PMCUPDATEOBJ(((void **)(((char *)&ao->___length___)+sizeof(int)))[j]);
+    }
+  } else {
+    unsigned int size=pointer[0];
+    
+    for(int i=1; i<=size; i++) {
+      unsigned int offset=pointer[i];
+      PMCUPDATEOBJ(*((void **)(((char *)ptr)+offset)));
+    }
+  }  
+}
+
+void pmc_referenceupdate(void *bottomptr, void *topptr) {
+  void *tmpptr=bottomptr;
+  while(tmpptr<topptr) {
+    unsigned int type;
+    unsigned int size;
+    gettype_size(tmpptr, &type, &size);
+    if (!type) {
+      tmpptr+=ALIGNMENTSIZE;
+      continue;
+    }
+    //if marked we update the pointers
+    if (((struct ___Object___ *) tmpptr)->mark) {
+      pmc_updatePtrs(tmpptr, type);
+    }
+    tmpptr+=size;
+  }
+}
+
+
+void pmc_compact(struct pmc_region * region, int forward, void *bottomptr, void *topptr) {
+  if (forward) {
+    void *tmpptr=bottomptr;
+    void *lastptr;
+    while(tmpptr<topptr) {
+      unsigned int type;
+      unsigned int size;
+      gettype_size(tmpptr, &type, &size);
+      if (!type) {
+       tmpptr+=ALIGNMENTSIZE;
+       continue;
+      }
+      //if marked we update the pointers
+      void *forwardptr=(void *)((struct ___Object___ *) tmpptr)->mark;
+      ((struct ___Object___ *) tmpptr)->mark=NULL;
+      if (forwardptr) {
+       memmove(forwardptr, tmpptr, size);
+      }
+      lastptr=forwardptr+size;
+      tmpptr+=size;
+    }
+    region->lastptr=lastptr;
+  } else {
+    struct ___Object___ *backward=region->lastobj;
+    struct ___Object___ *lastobj=NULL;
+    while(backward) {
+      lastobj=backward;
+      backward=backward->lastobj;
+      unsigned int type;
+      unsigned int size;
+      gettype_size(tmpptr, &type, &size);
+      void *forwardptr=(void *)((struct ___Object___ *) lastobj)->mark;
+      ((struct ___Object___ *) lastobj)->mark=NULL;
+      if (forwardptr) {
+       memmove(forwardptr, lastobj, size);
+      }
+    }
+  }
+}
diff --git a/Robust/src/Runtime/bamboo/pmc_refupdate.h b/Robust/src/Runtime/bamboo/pmc_refupdate.h
new file mode 100644 (file)
index 0000000..ccec188
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef PMC_REFUPDATE_H
+#define PMC_REFUPDATE_H
+
+void pmc_updatePtrs(void *ptr, int type);
+void pmc_referenceupdate(void *bottomptr, void *topptr);
+void pmc_compact(struct pmc_region * region, int forward, void *bottomptr, void *topptr);
+#endif