collector is described in "Parallel Garbage Collection for Shared Memory Multiprocessors"
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#include "pmc_garbage.h"
+
--- /dev/null
+#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
--- /dev/null
+#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
+}
--- /dev/null
+#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
--- /dev/null
+#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);
+ }
+ }
+ }
+}
--- /dev/null
+#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