static void gc_queueinit() {
// initialize queue
if (gchead==NULL) {
- gcheadindex=gctailindex=gctailindex2 = 0;
+ gcheadindex=gctailindex=0;
gchead=gctail=RUNMALLOC(sizeof(struct pointerblock));
} else {
gctailindex=gcheadindex=0;
extern unsigned int bitmarkmappingarray[];
extern unsigned int revmarkmappingarray[];
+#define ALIGNMENTSIZE 32
+//Bytes to shift to get minimum alignment units
+#define ALIGNMENTSHIFT 5
+
#define NOTMARKED 0
-#define ALIGNOBJSIZE(x) (x)>>5
-#define ALIGNSIZETOBYTES(x) (x)<<5
-#define ALIGNTOTABLEINDEX(x) (x)>>(5+4)
-#define CONVERTTABLEINDEXTOPTR(x) (((unsigned INTPTR)((x)<<(5+4)))+gcbase)
+#define BITSPERALIGNMENT 2
+#define ALIGNOBJSIZE(x) (x)>>ALIGNMENTSHIFT
+#define ALIGNSIZETOBYTES(x) (x)<<ALIGNMENTSHIFT
+#define ALIGNTOTABLEINDEX(x) (x)>>(ALIGNMENTSHIFT+4)
+#define CONVERTTABLEINDEXTOPTR(x) (((unsigned INTPTR)((x)<<(ALIGNMENTSHIFT+4)))+gcbaseva)
+//Minimum alignment unit
+
+
+
+
#define OBJMASK 0x40000000 //set towhatever smallest object mark is
/* Return length in units of ALIGNSIZE */
static inline unsigned int getMarkedLength(void *ptr) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
unsigned INTPTR val;
/* Return non-zero value if the object is marked */
static inline unsigned int checkMark(void *ptr) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
/* Set length in units of ALIGNSIZE */
static inline void setLength(void *ptr, unsigned int length) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
unsigned int ormask=(length>=16)?0xc4000000+(length-16):revmarkmappingarray[length];
/* Set length for premarked object */
static inline void setLengthMarked(void *ptr, unsigned int length) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
unsigned int ormask=(length>=16)?0xc4000000+(length-16):revmarkmappingarray[length];
/* Set length in units of ALIGNSIZE */
static inline void setMark(void *ptr) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
gcmarktbl[hibits]|=OBJMASK>>lobits;
}
static inline void clearMark(void *ptr) {
- unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbase));
+ unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
unsigned INTPTR hibits=alignsize>>4;
unsigned INTPTR lobits=(alignsize&15)<<1;
gc_cache_revise_information.to_page_index=toindex;
gc_cache_revise_information.orig_page_start_va=orig->ptr;
gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(((unsigned INTPTR)(orig->ptr-gcbaseva))/BAMBOO_PAGE_SIZE+1);
- gc_cache_revise_information.orig_page_index=((unsigned INTPTR)(orig->blockbase-gcbaseva))/BAMBOO_PAGE_SIZE;
+ gc_cache_revise_information.orig_page_index=((unsigned INTPTR)(orig->base-gcbaseva))/BAMBOO_PAGE_SIZE;
}
INLINE static void samplingDataConvert(void * current_ptr) {
return numbpc;
}
-// compute total mem size required and sort the lobjs in ascending order
-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;
-}
-
-bool cacheLObjs() {
- // check the total mem size need for large objs
- unsigned long long sumsize = 0;
- unsigned int size = 0;
-
- 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
- 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, void * localtop) {
compact();
GC_PRINTF("Finish compact phase\n");
- WAITFORGCPHASE(FLUSHPHASE);
+ WAITFORGCPHASE(UPDATEPHASE);
GC_PRINTF("Start flush phase\n");
GCPROFILE_INFO_2_MASTER();
GC_PRINTF("Finish mark phase, wait for flush\n");
// non-gc core collector routine
- WAITFORGCPHASE(FLUSHPHASE);
+ WAITFORGCPHASE(UPDATEPHASE);
GC_PRINTF("Start flush phase\n");
GCPROFILE_INFO_2_MASTER();
GCPROFILE_ITEM();
GC_PRINTF("prepare to cache large objs \n");
- // cache all large objs
- BAMBOO_ASSERTMSG(cacheLObjs(), "Not enough space to cache large objects\n");
}
void master_updaterefs(struct garbagelist * stackptr) {
- gc_status_info.gcphase = FLUSHPHASE;
- GC_SEND_MSG_1_TO_CLIENT(GCSTARTFLUSH);
+ gc_status_info.gcphase = UPDATEPHASE;
+ GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
GCPROFILE_ITEM();
GC_PRINTF("Start flush phase \n");
// flush phase
flush(stackptr);
- GC_CHECK_ALL_CORE_STATUS(FLUSHPHASE==gc_status_info.gcphase);
+ GC_CHECK_ALL_CORE_STATUS(UPDATEPHASE==gc_status_info.gcphase);
GC_PRINTF("Finish flush phase \n");
}
((((unsigned int)p)>=gcbaseva)&&(((unsigned int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
-//Minimum alignment unit
-#define ALIGNMENTBYTES 32
-
-//Bytes to shift to get minimum alignment units
-#define ALIGNMENTSHIFT 5
#define MAXBLOCK 0x4fffffff //local block number that can never be reached...
void transferMarkResults_I();
-bool gcfindSpareMem_I(unsigned int * startaddr,unsigned int * tomove,unsigned int * dstcore,unsigned int requiredmem,unsigned int requiredcore);
+void * gcfindSpareMem_I(unsigned int requiredmem,unsigned int requiredcore);
#define INITMULTICOREGCDATA() initmulticoregcdata()
#define DISMULTICOREGCDATA() dismulticoregcdata()
#include "runtime_arch.h"
#include "multicoreruntime.h"
#include "multicoregarbage.h"
+#include "markbit.h"
bool gc_checkCoreStatus() {
for(int i = 0; i < NUMCORES4GC; ++i) {
void initOrig_Dst(struct moveHelper * orig,struct moveHelper * to) {
// init the dst ptr
- to->blocknum = 0;
- BASEPTR(to->base, BAMBOO_NUM_OF_CORE, to->blocknum);
+ to->localblocknum = 0;
+ BASEPTR(to->base, BAMBOO_NUM_OF_CORE, to->localblocknum);
to->ptr = to->base;
- to->bound=to->base+BLOCKSIZE(to->blocknum);
+ to->bound=to->base+BLOCKSIZE(to->localblocknum);
// init the orig ptr
- orig->blocknum = 0;
+ orig->localblocknum = 0;
orig->ptr=orig->base = to->base;
- orig->bound = orig->base + BLOCKSIZE(orig->blocknum);
+ orig->bound = orig->base + BLOCKSIZE(orig->localblocknum);
}
void getSpaceLocally(struct moveHelper *to) {
// next available block
gcfilledblocks[sourcecore]++;
void * newbase = NULL;
- BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
+ BASEPTR(newbase, sourcecore, gcfilledblocks[sourcecore]);
topptrs[sourcecore] = newbase;
return requiredmem-remain;
}
return NULL;
}
-bool gcfindSpareMem(unsigned int * startaddr,unsigned int * tomove,unsigned int * dstcore,unsigned int requiredmem,unsigned int requiredcore) {
+bool gcfindSpareMem(unsigned int requiredmem,unsigned int requiredcore) {
BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- bool retval=gcfindSpareMem_I(startaddr, tomove, dstcore, requiredmem, requiredcore);
+ bool retval=gcfindSpareMem_I(requiredmem, requiredcore);
BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
return retval;
}
void *tobound=to->bound;
void *origptr=orig->ptr;
void *origbound=orig->bound;
- unsigned INTPTR origendoffset=ALIGNTOTABLEINDEX((unsigned INTPTR)(origbound-gcbase));
+ unsigned INTPTR origendoffset=ALIGNTOTABLEINDEX((unsigned INTPTR)(origbound-gcbaseva));
unsigned int objlength;
while(origptr<origbound) {
//Try to skip over stuff fast first
- unsigned INTPTR offset=(unsigned INTPTR) (origptr-gcbase);
+ unsigned INTPTR offset=(unsigned INTPTR) (origptr-gcbaseva);
unsigned INTPTR arrayoffset=ALIGNTOTABLEINDEX(offset);
if (!gcmarktbl[arrayoffset]) {
do {
origptr+=length;
toptr=endtoptr;
} else
- origptr+=ALIGNSIZE;
+ origptr+=ALIGNMENTSIZE;
}
}
void initOrig_Dst(struct moveHelper * orig,struct moveHelper * to);
void compacthelper(struct moveHelper * orig,struct moveHelper * to);
-void compactblocks(struct moveHelper * orig,struct moveHelper * to);
+unsigned int compactblocks(struct moveHelper * orig,struct moveHelper * to);
void compact();
void compact_master(struct moveHelper * orig, struct moveHelper * to);
#endif // MULTICORE_GC
#include "ObjectHash.h"
#include "GenericHashtable.h"
#include "gcqueue.h"
+#include "markbit.h"
/* Task specific includes */
/* This function is performance critical... spend more time optimizing it */
-unsigned int updateblocks(struct moveHelper * orig, struct moveHelper * to) {
+void * updateblocks(struct moveHelper * orig, struct moveHelper * to) {
void *tobase=to->base;
void *tobound=to->bound;
void *origptr=orig->ptr;
void *origbound=orig->bound;
- unsigned INTPTR origendoffset=ALIGNTOTABLEINDEX((unsigned INTPTR)(origbound-gcbase));
+ unsigned INTPTR origendoffset=ALIGNTOTABLEINDEX((unsigned INTPTR)(origbound-gcbaseva));
unsigned int objlength;
while(origptr<origbound) {
//Try to skip over stuff fast first
- unsigned INTPTR offset=(unsigned INTPTR) (origptr-gcbase);
+ unsigned INTPTR offset=(unsigned INTPTR) (origptr-gcbaseva);
unsigned INTPTR arrayoffset=ALIGNTOTABLEINDEX(offset);
if (!gcmarktbl[arrayoffset]) {
do {
if (arrayoffset<origendoffset) {
//finished with block...
origptr=origbound;
- to->ptr=toptr;
orig->ptr=origptr;
return 0;
}
void *endtoptr=dstptr+length;
if (endtoptr>tobound||endtoptr<tobase) {
- toptr=tobound;
- to->ptr=toptr;
+ //get use the next block of memory
+ to->ptr=tobound;
orig->ptr=origptr;
- return length;
+ return dstptr;
}
/* Move the object */
- if(origptr <= dstptr+size) {
- memmove(dstptr, origptr, size);
+ if(origptr <= endtoptr) {
+ memmove(dstptr, origptr, length);
} else {
- memcpy(dstptr, origptr, size);
+ memcpy(dstptr, origptr, length);
}
/* Update the pointers in the object */
//good to move objects and update pointers
origptr+=length;
} else
- origptr+=ALIGNSIZE;
+ origptr+=ALIGNMENTSIZE;
}
}
#ifdef MULTICORE_GC
-#include "multicoregcmark.h"
#include "runtime.h"
#include "multicoreruntime.h"
#include "GenericHashtable.h"
#include "gcqueue.h"
+#include "multicoregcmark.h"
+#include "markbit.h"
#ifdef TASK
extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
}
}
-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++) {
}
// 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);
if(startaddr) {
// cache the msg first
if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4_I(cnum,GCMOVESTART,startaddr);
+ cache_msg_2_I(cnum,GCMOVESTART,startaddr);
} else {
- send_msg_4_I(cnum,GCMOVESTART,startaddr);
+ send_msg_2_I(cnum,GCMOVESTART,startaddr);
}
}
} else {
}
INLINE void processmsg_gcmarkedobj_I() {
- void * data1 = (void *) msgdata[msgdataindex];
+ void * objptr = (void *) msgdata[msgdataindex];
MSG_INDEXINC_I();
- BAMBOO_ASSERT(ISSHAREDOBJ(data1));
// received a markedObj msg
if(!checkMark(objptr)) {
// this is the first time that this object is discovered,
// set the flag as DISCOVERED
- setMark(data1);
- gc_enqueue_I(data1);
+ setMark(objptr);
+ gc_enqueue_I(objptr);
}
gcself_numreceiveobjs++;
gc_status_info.gcbusystatus = true;
int length = msgdata[msgdataindex];
MSG_INDEXINC_I();
gc_lobjenqueue_I(lobj, length, cnum);
- gcnumlobjs++;
}
}