From e822d88dc662f8c57d1585ba8f1a5cb0703842bc Mon Sep 17 00:00:00 2001 From: jzhou Date: Sat, 2 Jul 2011 00:40:46 +0000 Subject: [PATCH] Add cache adaptive code to multicore gc and add support for System.gc() --- Robust/src/Runtime/bamboo/multicorecache.c | 208 +--------------- Robust/src/Runtime/bamboo/multicorecache.h | 233 +++++++++++++++--- Robust/src/Runtime/bamboo/multicoregarbage.c | 1 + .../src/Runtime/bamboo/multicoregccompact.c | 109 +++++++- .../src/Runtime/bamboo/multicoregccompact.h | 11 +- Robust/src/Runtime/bamboo/multicoremsg.c | 28 +++ Robust/src/Runtime/bamboo/multicoremsg.h | 35 +-- Robust/src/Runtime/bamboo/multicoreruntime.c | 24 ++ 8 files changed, 390 insertions(+), 259 deletions(-) diff --git a/Robust/src/Runtime/bamboo/multicorecache.c b/Robust/src/Runtime/bamboo/multicorecache.c index 061e96cd..b3bfba1e 100644 --- a/Robust/src/Runtime/bamboo/multicorecache.c +++ b/Robust/src/Runtime/bamboo/multicorecache.c @@ -167,204 +167,6 @@ void cacheAdapt_policy_dominate(int coren){ } } -#if 0 -#define GC_CACHE_ADAPT_OVERLOAD_THRESHOLD 10 -// record the worklocad of the hottestcore into core2heavypages -#define CACHEADAPT_RECORD_PAGE_WORKLOAD(hottestcore,totalfreq,hotfreq,remoteaccess,tmp_p) \ - { \ - workload[hottestcore] += (totalfreq); \ - total_workload += (totalfreq); \ - unsigned long long remoteaccess = (totalfreq) - (hotfreq); \ - unsigned int index = (unsigned int)core2heavypages[hottestcore][0]; \ - core2heavypages[hottestcore][3*index+3] = (remoteaccess); \ - core2heavypages[hottestcore][3*index+2] = (totalfreq); \ - core2heavypages[hottestcore][3*index+1] = (unsigned long long)((tmp_p)-1); \ - core2heavypages[hottestcore][0]++; \ - } - -void gc_quicksort(unsigned long long *array,unsigned int left,unsigned int right,unsigned int offset) { - unsigned int pivot = 0;; - unsigned int leftIdx = left; - unsigned int rightIdx = right; - if((right-left+1) >= 1) { - pivot = (left+right)/2; - while((leftIdx <= pivot) && (rightIdx >= pivot)) { - unsigned long long pivotValue = array[pivot*3-offset]; - while((array[leftIdx*3-offset] > pivotValue) && (leftIdx <= pivot)) { - leftIdx++; - } - while((array[rightIdx*3-offset] < pivotValue) && (rightIdx >= pivot)) { - rightIdx--; - } - // swap [leftIdx] & [rightIdx] - for(int k = 0; k < 3; k++) { - unsigned long long tmp = array[3*rightIdx-k]; - array[3*rightIdx-k] = array[3*leftIdx-k]; - array[3*leftIdx-k] = tmp; - } - leftIdx++; - rightIdx--; - if((leftIdx-1) == pivot) { - pivot = rightIdx = rightIdx + 1; - } else if((leftIdx+1) == pivot) { - pivot = leftIdx = leftIdx-1; - } - } - gc_quicksort(array, left, pivot-1, offset); - gc_quicksort(array, pivot+1, right, offset); - } - return; -} - -INLINE int cacheAdapt_h4h_remote_accesses(unsigned long long workload_threshold,unsigned long long ** core2heavypages, unsigned long long * workload,int i) { - int j = 1; - unsigned int index = (unsigned int)core2heavypages[i][0]; - if(workload[i] > workload_threshold) { - // sort according to the remoteaccess - gc_quicksort(&core2heavypages[i][0], 1, index, 0); - while((workload[i] > workload_threshold) && (j GC_CACHE_ADAPT_CROWD_THRESHOLD) { - // need to hfh these pages - // sort the pages according to remote access - gc_quicksort(&core2heavypages[i][0], j/3+1, j/3+num_crowded, 0); - // h4h those pages with more remote accesses - bamboo_cache_policy_t policy = {0}; - policy.cache_mode = BAMBOO_CACHE_MODE_HASH; - *((unsigned int*)core2heavypages[i][j]) = policy.word; - workload[i] -= core2heavypages[i][j+1]; - t_workload -= core2heavypages[i][j+1]; - j += 3; - threshold = GC_CACHE_ADAPT_ACCESS_THRESHOLD*workload[i]/100; - goto inner_crowd; - } - } - - return numchanged; -} -#endif - unsigned int cacheAdapt_decision(int coren) { BAMBOO_CACHE_MF(); // check the statistic data @@ -377,10 +179,6 @@ unsigned int cacheAdapt_decision(int coren) { cacheAdapt_policy_hottest(coren); #elif defined GC_CACHE_ADAPT_POLICY4 cacheAdapt_policy_dominate(coren); -//#elif defined GC_CACHE_ADAPT_POLICY5 -// cacheAdapt_policy_overload(coren); -//#elif defined GC_CACHE_ADAPT_POLICY6 -// cacheAdapt_policy_crowd(coren); #endif } @@ -401,6 +199,7 @@ void cacheAdapt_mutator() { } } +// Cache adapt phase process for clients void cacheAdapt_phase_client() { WAITFORGCPHASE(CACHEPOLICYPHASE); GC_PRINTF("Start cachepolicy phase\n"); @@ -427,6 +226,7 @@ void cacheAdapt_phase_client() { extern unsigned long long gc_output_cache_policy_time; +// Cache adpat phase process for the master void cacheAdapt_phase_master() { GCPROFILE_ITEM(); unsigned long long tmpt = BAMBOO_GET_EXE_TIME(); @@ -461,6 +261,7 @@ void cacheAdapt_phase_master() { } } +// output original cache sampling data for each page void gc_output_cache_sampling() { //extern volatile bool gc_profile_flag; //if(!gc_profile_flag) return; @@ -485,6 +286,7 @@ void gc_output_cache_sampling() { printf("=================\n"); } +// output revised cache sampling data for each page after compaction void gc_output_cache_sampling_r() { //extern volatile bool gc_profile_flag; //if(!gc_profile_flag) return; @@ -517,7 +319,7 @@ void gc_output_cache_sampling_r() { if(accesscore!=0) { for(int i = 0; i < NUMCORESACTIVE; i++) { int * local_tbl = (int *)((void *)gccachesamplingtbl_r+size_cachesamplingtbl_local_r*i); - int freq = local_tbl[page_index]/BAMBOO_PAGE_SIZE; + int freq = local_tbl[page_index]; ///BAMBOO_PAGE_SIZE; sumdata[accesscore-1][i]+=freq; } } diff --git a/Robust/src/Runtime/bamboo/multicorecache.h b/Robust/src/Runtime/bamboo/multicorecache.h index f5dc3d60..57fc8a0d 100644 --- a/Robust/src/Runtime/bamboo/multicorecache.h +++ b/Robust/src/Runtime/bamboo/multicorecache.h @@ -7,16 +7,20 @@ #include "multicoregarbage.h" #ifdef GC_CACHE_ADAPT -#define GC_CACHE_SAMPLING_UNIT 0x40000 //100000 //000 -#define GC_TILE_TIMER_EVENT_SETTING (GC_CACHE_SAMPLING_UNIT) //100000 //000 +// sampling unit to compute access frequency, this should be consistent all the +// time. +#define GC_CACHE_SAMPLING_UNIT 0x80000 +// freqeuency to trigger timer interrupt +#define GC_TILE_TIMER_EVENT_SETTING 10000000 +// data structure to record policy information for a page // should be consistent with multicoreruntime.h typedef union { unsigned int word; struct { - // policy type + // policy type, should be enough to accommodate all 4 possible polices unsigned int cache_mode : 3; // Reserved. unsigned int __reserved_0 : 5; @@ -31,70 +35,229 @@ typedef union }; } bamboo_cache_policy_t; -#define BAMBOO_CACHE_MODE_LOCAL 1 -#define BAMBOO_CACHE_MODE_HASH 2 -#define BAMBOO_CACHE_MODE_NONE 3 -#define BAMBOO_CACHE_MODE_COORDS 4 +#define BAMBOO_CACHE_MODE_LOCAL 1 // locally cached +#define BAMBOO_CACHE_MODE_HASH 2 // hash-for-home +#define BAMBOO_CACHE_MODE_NONE 3 // no caching +#define BAMBOO_CACHE_MODE_COORDS 4 // cached on a specific core +// data structure to hold page information while calculating revised sampling +// info during compaction typedef struct gc_cache_revise_info { - void * orig_page_start_va; + // the start address in current original page to be compacted to current + // destination page + void * orig_page_start_va; + // the end of current original page to be compacted void * orig_page_end_va; + // the index of current original page unsigned int orig_page_index; + // the start address in current destination page to where the current original + // page is compacted void * to_page_start_va; + // the end of current destination page void * to_page_end_va; + // the index of current destination page unsigned int to_page_index; - unsigned int revised_sampling[NUMCORESACTIVE]; } gc_cache_revise_info_t; +// global variable holding page information to compute revised sampling info extern gc_cache_revise_info_t gc_cache_revise_information; +/* This function initialize the gc_cache_revise_information. It should be + * invoked before we start compaction. + */ INLINE static void samplingDataReviseInit(struct moveHelper * orig,struct moveHelper * to) { + // initialize the destination page info gc_cache_revise_information.to_page_start_va=to->ptr; unsigned int toindex=(unsigned INTPTR)(to->base-gcbaseva)/BAMBOO_PAGE_SIZE; gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(toindex+1); gc_cache_revise_information.to_page_index=toindex; + // initilaize the original page info + unsigned int origindex=((unsigned INTPTR)(orig->base-gcbaseva))/BAMBOO_PAGE_SIZE; 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->base-gcbaseva))/BAMBOO_PAGE_SIZE; + gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(origindex+1); + gc_cache_revise_information.orig_page_index=origindex; } -INLINE static void samplingDataConvert(void * current_ptr) { - unsigned INTPTR tmp_factor=(unsigned INTPTR)(current_ptr-gc_cache_revise_information.to_page_start_va); +/* This function computes the revised profiling data of the first closed destination + * page of an object that acrosses multiple pages + */ +INLINE static void firstPageConvert(bool origclosefirst, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) { unsigned INTPTR topage=gc_cache_revise_information.to_page_index; unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index; int * newtable=&gccachesamplingtbl_r[topage]; int * oldtable=&gccachesamplingtbl[oldpage]; - + // compute the revised profiling info for the start destination page + if(origclosefirst) { + // the start original page closes first, now compute the revised profiling + // info for the start destination page. + // The start destination page = the rest of the start original page + + // delta_fator from the next original page + int * oldtable_next=&gccachesamplingtbl[oldpage+1]; + for(int tt = 0; tt < NUMCORESACTIVE; tt++) { + (*newtable)=((*newtable)+(*oldtable)*main_factor+(*oldtable_next)*delta_factor); + newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r); + oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local); + oldtable_next=(int*) (((char *)oldtable_next)+size_cachesamplingtbl_local); + } + // close the start original page + gc_cache_revise_information.orig_page_start_va+=main_factor+delta_factor; + gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE; + gc_cache_revise_information.orig_page_index++; + } else { + // the start destination page closes first, now compute the revised + // profiling info for it. + for(int tt = 0; tt < NUMCORESACTIVE; tt++) { + (*newtable)=((*newtable)+(*oldtable)*main_factor); + newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r); + oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local); + } + // record the new start of the original page + gc_cache_revise_information.orig_page_start_va+=main_factor; + } + // close the start original page and destination page + gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va; + gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE; + gc_cache_revise_information.to_page_index++; +} + +/* This function computes the revised profiling info for closed destination + * pages that are occupied by one object that acrosses multiple pages. + * the destination page = main_factor from the first unclosed original page + * + delta_factor from the next unclosed original page + */ +INLINE static void restClosedPageConvert(void * current_ptr, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) { + while(gc_cache_revise_information.to_page_end_va<=current_ptr) { + unsigned INTPTR topage=gc_cache_revise_information.to_page_index; + unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index; + int *newtable=&gccachesamplingtbl_r[topage]; + int *oldtable=&gccachesamplingtbl[oldpage]; + int *oldtable_next=&gccachesamplingtbl[oldpage+1]; + + for(int tt = 0; tt < NUMCORESACTIVE; tt++) { + (*newtable)=((*newtable)+(*oldtable)*main_factor+(*oldtable_next)*delta_factor); + newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r); + oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local); + oldtable_next=(int*) (((char *)oldtable_next)+size_cachesamplingtbl_local); + } + + // close the original page and the destination page + gc_cache_revise_information.orig_page_start_va+=BAMBOO_PAGE_SIZE; + gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE; + gc_cache_revise_information.orig_page_index++; + gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va; + gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE; + gc_cache_revise_information.to_page_index++; + } +} + +/* This function computes the revised profiling info for the last + * destination page of an object that acrosses multiple pages. + */ +INLINE static void lastPageConvert(void * current_ptr) { + unsigned INTPTR to_factor=current_ptr-gc_cache_revise_information.to_page_start_va; + unsigned INTPTR topage=gc_cache_revise_information.to_page_index; + unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index; + int *newtable=&gccachesamplingtbl_r[topage]; + int *oldtable=&gccachesamplingtbl[oldpage]; + for(int tt = 0; tt < NUMCORESACTIVE; tt++) { - (*newtable)=((*newtable)+(*oldtable)*tmp_factor); + (*newtable)=((*newtable)+(*oldtable)*to_factor); newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r); oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local); } -} + // do not need to set gc_cache_revise_information here for the last + // original/destination page as it will be set in completePageConvert() +} + +/* This function converts multiple original pages profiling data to multiple + * destination pages' profiling data + */ +INLINE static void samplingDataConvertMultiple(void * current_ptr) { + // first decide which page close first: original or destination? + unsigned INTPTR to_factor=(unsigned INTPTR)(gc_cache_revise_information.to_page_end_va-gc_cache_revise_information.to_page_start_va); + unsigned INTPTR orig_factor=(unsigned INTPTR)(gc_cache_revise_information.orig_page_end_va-gc_cache_revise_information.orig_page_start_va); + bool origclosefirst=to_factor>orig_factor; + unsigned INTPTR delta_factor=(origclosefirst)?(to_factor-orig_factor):(orig_factor-to_factor); + unsigned INTPTR main_factor=(origclosefirst)?orig_factor:to_factor; -INLINE static void completePageConvert(struct moveHelper * orig,struct moveHelper * to, void * current_ptr,bool closeToPage) { - void *ptr; - void *tocompare; - if(closeToPage) { - ptr=to->ptr; - tocompare=gc_cache_revise_information.to_page_end_va; + // compute the revised profiling info for the start destination page + firstPageConvert(origclosefirst, main_factor, delta_factor); + // update main_factor/delta_factor + if(origclosefirst) { + // for the following destination pages that are fully used: + // the destination page = (page_size-delta_factor) from the + // first unclosed original page + delta_factor + // from the next unclosed original page + // we always use main_factor to represent the factor from the first + // unclosed original page + main_factor=BAMBOO_PAGE_SIZE-delta_factor; } else { - ptr=orig->ptr; - tocompare=gc_cache_revise_information.orig_page_end_va; + // for the following destination pages that are fully used: + // the destination page = delta_factor from the first unclosed original + // page + (page_size-delta_factor) from the next + // unclosed original page + // we always use main_factor to represent the factor from the first + // unclosed original page + main_factor=delta_factor; + delta_factor=BAMBOO_PAGE_SIZE-delta_factor; } - if((unsigned int)ptr>=(unsigned int)tocompare) { - // end of an orig/to page - // compute the impact of this page for the new page + + // compute the revised profiling info for the following closed destination + // pages + restClosedPageConvert(current_ptr, main_factor, delta_factor); + + // compute the revised profiling info for the last destination page if needed + lastPageConvert(current_ptr); +} + +/* This function converts originial pages' profiling data to destination pages' + * profiling data. + * The parameter current_ptr indicates the current position in the destination + * pages. + * Note that there could be objects that across pages. In such cases, there are + * multiple orig/to pages are closed and all these to pages' profiling data + * should be properly updated. + */ +INLINE static void samplingDataConvert(void * current_ptr) { + if(gc_cache_revise_information.to_page_end_va=(unsigned int)(gc_cache_revise_information.to_page_end_va); + bool closeOrigPage=(unsigned int)(origptr)>=(unsigned int)(gc_cache_revise_information.orig_page_end_va); + if(closeToPage||closeOrigPage) { + // end of one or more orig/to page + // compute the impact of the original page(s) for the desitination page(s) samplingDataConvert(current_ptr); // prepare for an new orig page - unsigned INTPTR tmp_index=((unsigned INTPTR)(orig->ptr-gcbaseva))/BAMBOO_PAGE_SIZE; - gc_cache_revise_information.orig_page_start_va=orig->ptr; + unsigned INTPTR tmp_index=((unsigned INTPTR)(origptr-gcbaseva))/BAMBOO_PAGE_SIZE; + gc_cache_revise_information.orig_page_start_va=origptr; gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(tmp_index+1); gc_cache_revise_information.orig_page_index=tmp_index; - gc_cache_revise_information.to_page_start_va=to->ptr; + gc_cache_revise_information.to_page_start_va=toptr; if(closeToPage) { - gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(((unsigned INTPTR)(to->ptr-gcbaseva))/BAMBOO_PAGE_SIZE+1); - gc_cache_revise_information.to_page_index=((unsigned INTPTR)(to->ptr-gcbaseva))/BAMBOO_PAGE_SIZE; + unsigned INTPTR to_index=((unsigned INTPTR)(toptr-gcbaseva))/BAMBOO_PAGE_SIZE; + gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(to_index+1); + gc_cache_revise_information.to_page_index=to_index; } } } @@ -131,8 +294,8 @@ void gc_output_cache_sampling_r(); #define CACHEADAPT_SAMPLING_DATA_REVISE_INIT(o,t) \ samplingDataReviseInit((o),(t)) #define CACHEADAPT_SAMPLING_DATA_CONVERT(p) samplingDataConvert((p)) -#define CACHEADAPT_COMPLETE_PAGE_CONVERT(o, t, p, b) \ - completePageConvert((o), (t), (p), (b)); +#define CACHEADAPT_COMPLETE_PAGE_CONVERT(o, t, p) \ + completePageConvert((o), (t), (p)); #define CACHEADAPT_GC(b) cacheAdapt_gc(b) #define CACHEADAPT_MASTER() cacheAdapt_master() @@ -151,7 +314,7 @@ void gc_output_cache_sampling_r(); #ifdef MGC_SPEC #define CACHEADAPT_OUTPUT_CACHE_POLICY() \ { \ - if(gc_profile_flag) { \ + if(1) { \ bamboo_output_cache_policy(); \ } \ } diff --git a/Robust/src/Runtime/bamboo/multicoregarbage.c b/Robust/src/Runtime/bamboo/multicoregarbage.c index ef73a360..8416a527 100644 --- a/Robust/src/Runtime/bamboo/multicoregarbage.c +++ b/Robust/src/Runtime/bamboo/multicoregarbage.c @@ -247,6 +247,7 @@ int loadbalance() { unsigned int tloads = 0; for(int i = 0; i < NUMCORES4GC; i++) { tloads += gcloads[i]; + //tprintf("load: %d %d \n", gcloads[i], i); } heaptop = gcbaseva + tloads; diff --git a/Robust/src/Runtime/bamboo/multicoregccompact.c b/Robust/src/Runtime/bamboo/multicoregccompact.c index 18e3bf8f..394ea3aa 100644 --- a/Robust/src/Runtime/bamboo/multicoregccompact.c +++ b/Robust/src/Runtime/bamboo/multicoregccompact.c @@ -28,6 +28,10 @@ void initOrig_Dst(struct moveHelper * orig,struct moveHelper * to) { orig->localblocknum = 0; orig->ptr=orig->base = to->base; orig->bound = orig->base + BLOCKSIZE(orig->localblocknum); +#ifdef GC_CACHE_ADAPT + to->pagebound=to->base+BAMBOO_PAGE_SIZE; + orig->pagebound=orig->base+BAMBOO_PAGE_SIZE; +#endif } void getSpaceLocally(struct moveHelper *to) { @@ -36,6 +40,9 @@ void getSpaceLocally(struct moveHelper *to) { BASEPTR(to->base,BAMBOO_NUM_OF_CORE, to->localblocknum); to->ptr=to->base; to->bound = to->base + BLOCKSIZE(to->localblocknum); +#ifdef GC_CACHE_ADAPT + to->pagebound=to->base+BAMBOO_PAGE_SIZE; +#endif } //This function is called on the master core only...and typically by @@ -160,6 +167,9 @@ void getSpaceRemotely(struct moveHelper *to, unsigned int minimumbytes) { BLOCKINDEX(globalblocknum, to->ptr); to->base = gcbaseva + OFFSET2BASEVA(globalblocknum); to->bound = gcbaseva + BOUNDPTR(globalblocknum); +#ifdef GC_CACHE_ADAPT + to->pagebound=(void *)((int)((int)(to->ptr)&(~(BAMBOO_PAGE_SIZE-1)))+BAMBOO_PAGE_SIZE); +#endif } void getSpace(struct moveHelper *to, unsigned int minimumbytes) { @@ -184,8 +194,7 @@ void compacthelper(struct moveHelper * orig,struct moveHelper * to) { //Only send the message once senttopmessage=true; } - unsigned int minimumbytes=compactblocks(orig, to); - + unsigned int minimumbytes=COMPACTUNITS(orig, to); if (orig->ptr==orig->bound) { //need more data to compact //increment the core @@ -193,6 +202,9 @@ void compacthelper(struct moveHelper * orig,struct moveHelper * to) { BASEPTR(orig->base,BAMBOO_NUM_OF_CORE, orig->localblocknum); orig->ptr=orig->base; orig->bound = orig->base + BLOCKSIZE(orig->localblocknum); +#ifdef GC_CACHE_ADAPT + orig->pagebound=orig->base+BAMBOO_PAGE_SIZE; +#endif if (orig->base >= gcbaseva+BAMBOO_SHARED_MEM_SIZE) break; } @@ -349,6 +361,95 @@ void * gcfindSpareMem_I(unsigned INTPTR requiredmem, unsigned INTPTR desiredmem, return NULL; } +#ifdef GC_CACHE_ADAPT +/* To compute access rate per pages, we need to compact to page boundary + * instead of block boundary + */ +unsigned int compactpages(struct moveHelper * orig, struct moveHelper * to) { + void *toptrinit=to->ptr; + void *toptr=toptrinit; + void *tobound=to->bound; + void *topagebound=to->pagebound; + void *origptr=orig->ptr; + void *origpagebound=orig->pagebound; + unsigned INTPTR origendoffset=ALIGNTOTABLEINDEX((unsigned INTPTR)(origpagebound-gcbaseva)); + unsigned int objlength; + while((origptr=origendoffset) { + //finished with a page... + origptr=origpagebound; + to->ptr=toptr; + orig->ptr=origptr; + orig->pagebound+=BAMBOO_PAGE_SIZE; + gccurr_heaptop-=(unsigned INTPTR)(toptr-toptrinit); + // close the last destination page + CACHEADAPT_COMPLETE_PAGE_CONVERT(origptr, toptr, toptr); + return 0; + } + } while(!gcmarktbl[arrayoffset]); + origptr=CONVERTTABLEINDEXTOPTR(arrayoffset); + } + + //Scan more carefully next + objlength=getMarkedLength(origptr); + + if (objlength!=NOTMARKED) { + unsigned int length=ALIGNSIZETOBYTES(objlength); + + //code between this and next comment should be removed +#ifdef GC_DEBUG + unsigned int size; + unsigned int type; + gettype_size(origptr, &type, &size); + size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE; + + if (size!=length) { + tprintf("BAD SIZE IN BITMAP: type=%u object=%x size=%u length=%u\n", type, origptr, size, length); + unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(origptr-gcbaseva)); + unsigned INTPTR hibits=alignsize>>4; + unsigned INTPTR lobits=(alignsize&15)<<1; + tprintf("hibits=%x lobits=%x\n", hibits, lobits); + tprintf("hi=%x lo=%x\n", gcmarktbl[hibits], gcmarktbl[hibits+1]); + } +#endif + //end of code to remove + + void *endtoptr=toptr+length; + if (endtoptr>tobound) { + gccurr_heaptop-=(unsigned INTPTR)(toptr-toptrinit); + to->ptr=tobound; + orig->ptr=origptr; + // close a destination page, update the revise profiling info + CACHEADAPT_COMPLETE_PAGE_CONVERT(origptr, tobound, toptr); + return length; + } + //good to move objects and update pointers + //tprintf("Decided to compact obj %x to %x\n", origptr, toptr); + + gcmappingtbl[OBJMAPPINGINDEX(origptr)]=toptr; + + origptr+=length; + toptr=endtoptr; + } else + origptr+=ALIGNMENTSIZE; + } + to->ptr=toptr; + orig->ptr=origptr; + orig->pagebound=(void *)((int)(((int)origptr)&(~(BAMBOO_PAGE_SIZE-1)))+BAMBOO_PAGE_SIZE); + to->pagebound=(void *)((int)(((int)toptr)&(~(BAMBOO_PAGE_SIZE-1)))+BAMBOO_PAGE_SIZE); + gccurr_heaptop-=(unsigned INTPTR)(toptr-toptrinit); + // close the last destination page + CACHEADAPT_COMPLETE_PAGE_CONVERT(origptr, toptr, toptr); + return 0; +} + +#else /* This function is performance critical... spend more time optimizing it */ unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) { @@ -404,7 +505,7 @@ unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) { void *endtoptr=toptr+length; if (endtoptr>tobound) { - gccurr_heaptop-=(unsigned INTPTR)(toptr-toptrinit); + gccurr_heaptop-=(unsigned INTPTR)(toptr-toptrinit); to->ptr=tobound; orig->ptr=origptr; return length; @@ -425,6 +526,8 @@ unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) { return 0; } +#endif + void compact() { BAMBOO_ASSERT(COMPACTPHASE == gc_status_info.gcphase); diff --git a/Robust/src/Runtime/bamboo/multicoregccompact.h b/Robust/src/Runtime/bamboo/multicoregccompact.h index 0d56cfc8..8daf58f5 100644 --- a/Robust/src/Runtime/bamboo/multicoregccompact.h +++ b/Robust/src/Runtime/bamboo/multicoregccompact.h @@ -9,13 +9,22 @@ struct moveHelper { void * base; // base virtual address of current heap block void * ptr; // current pointer into block void * bound; // upper bound of current block +#ifdef GC_CACHE_ADAPT + void * pagebound; // upper bound of current available page +#endif }; void initOrig_Dst(struct moveHelper * orig,struct moveHelper * to); void compacthelper(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); +#ifdef GC_CACHE_ADAPT +unsigned int compactpages(struct moveHelper * orig,struct moveHelper * to); +#define COMPACTUNITS(o,t) compactpages((o), (t)) +#else +unsigned int compactblocks(struct moveHelper * orig,struct moveHelper * to); +#define COMPACTUNITS(o,t) compactblocks((o), (t)) +#endif #endif // MULTICORE_GC #endif // BAMBOO_MULTICORE_GC_COMPACT_H diff --git a/Robust/src/Runtime/bamboo/multicoremsg.c b/Robust/src/Runtime/bamboo/multicoremsg.c index 8deb797b..20b2bc9b 100644 --- a/Robust/src/Runtime/bamboo/multicoremsg.c +++ b/Robust/src/Runtime/bamboo/multicoremsg.c @@ -30,6 +30,7 @@ int msgsizearray[] = { 3, //MEMREQUEST, // 0xE0 3, //MEMRESPONSE, // 0xE1 #ifdef MULTICORE_GC + 1, //GCINVOKE 1, //GCSTARTPRE, // 0xE2 1, //GCSTARTINIT, // 0xE3 1, //GCSTART, // 0xE4 @@ -410,6 +411,28 @@ void processmsg_memresponse_I() { } #ifdef MULTICORE_GC +void processmsg_gcinvoke_I() { + BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE==STARTUPCORE); + if(!gc_status_info.gcprocessing && !gcflag) { + gcflag = true; + gcprecheck = true; + for(int i = 0; i < NUMCORESACTIVE; i++) { + // reuse the gcnumsendobjs & gcnumreceiveobjs + gcnumsendobjs[0][i] = 0; + gcnumreceiveobjs[0][i] = 0; + } + for(int i = 0; i < NUMCORES4GC; i++) { + if(i != STARTUPCORE) { + if(BAMBOO_CHECK_SEND_MODE()) { + cache_msg_1_I(i,GCSTARTPRE); + } else { + send_msg_1_I(i,GCSTARTPRE); + } + } + } + } +} + void processmsg_gcstartpre_I() { // the first time to be informed to start gc gcflag = true; @@ -887,6 +910,11 @@ processmsg: #ifdef MULTICORE_GC // GC msgs + case GCINVOKE: { + processmsg_gcinvoke_I(); + break; + } + case GCSTARTPRE: { processmsg_gcstartpre_I(); break; diff --git a/Robust/src/Runtime/bamboo/multicoremsg.h b/Robust/src/Runtime/bamboo/multicoremsg.h index 7f9fed18..0005e180 100644 --- a/Robust/src/Runtime/bamboo/multicoremsg.h +++ b/Robust/src/Runtime/bamboo/multicoremsg.h @@ -173,24 +173,25 @@ typedef enum { MEMREQUEST, // 0xE0 MEMRESPONSE, // 0xE1 #ifdef MULTICORE_GC - GCSTARTPRE, // 0xE2 - GCSTARTINIT, // 0xE3 - GCSTART, // 0xE4 - GCSTARTCOMPACT, // 0xE5 - GCSTARTUPDATE, // 0xE6 - GCFINISHPRE, // 0xE7 - GCFINISHINIT, // 0xE8 - GCFINISHMARK, // 0xE9 - GCFINISHCOMPACT, // 0xEa + GCINVOKE, // 0xE2 + GCSTARTPRE, // 0xE3 + GCSTARTINIT, // 0xE4 + GCSTART, // 0xE5 + GCSTARTCOMPACT, // 0xE6 + GCSTARTUPDATE, // 0xE7 + GCFINISHPRE, // 0xE8 + GCFINISHINIT, // 0xE9 + GCFINISHMARK, // 0xEa + GCFINISHCOMPACT, // 0xEb GCRETURNMEM, - GCFINISHUPDATE, // 0xEb - GCFINISH, // 0xEc - GCMARKCONFIRM, // 0xEd - GCMARKREPORT, // 0xEe - GCMARKEDOBJ, // 0xEf - GCMOVESTART, // 0xF0 - GCLOBJREQUEST, // 0xF1 - GCREQBLOCK, + GCFINISHUPDATE, // 0xEc + GCFINISH, // 0xEd + GCMARKCONFIRM, // 0xEe + GCMARKREPORT, // 0xEf + GCMARKEDOBJ, // 0xF0 + GCMOVESTART, // 0xF1 + GCLOBJREQUEST, // 0xF2 + GCREQBLOCK, GCGRANTBLOCK, GCLOBJINFO, // 0xF2 #ifdef GC_PROFILE diff --git a/Robust/src/Runtime/bamboo/multicoreruntime.c b/Robust/src/Runtime/bamboo/multicoreruntime.c index 8f4a025c..a7548dcb 100644 --- a/Robust/src/Runtime/bamboo/multicoreruntime.c +++ b/Robust/src/Runtime/bamboo/multicoreruntime.c @@ -346,6 +346,30 @@ void CALL00(___System______resetgcprofileflag____) { #endif } +void CALL00(___System______gc____) { +#ifdef MULTICORE_GC + if(BAMBOO_NUM_OF_CORE == STARTUPCORE) { + if(!gc_status_info.gcprocessing && !gcflag) { + gcflag = true; + gcprecheck = true; + for(int i = 0; i < NUMCORESACTIVE; i++) { + // reuse the gcnumsendobjs & gcnumreceiveobjs + gcnumsendobjs[0][i] = 0; + gcnumreceiveobjs[0][i] = 0; + } + for(int i = 0; i < NUMCORES4GC; i++) { + if(i != STARTUPCORE) { + send_msg_1_I(i,GCSTARTPRE); + } + } + } + } else { + // send msg to the startup core to start gc + send_msg_1(STARTUPCORE, GCINVOKE); + } +#endif +} + #ifdef D___System______printString____L___String___ void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) { -- 2.34.1