#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];
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];
}
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) {
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]);
}
}
}
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
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
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
}
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) {
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];
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 {
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