1 #ifndef BAMBOO_MULTICORE_GARBAGE_H
2 #define BAMBOO_MULTICORE_GARBAGE_H
5 #include "multicoregc.h"
6 #include "multicorehelper.h" // for mappings between core # and block #
7 #include "structdefs.h"
8 #include "multicoregcprofile.h"
9 #include "multicorecache.h"
12 #define GC_PRINTF tprintf
14 #define GC_PRINTF if(0) tprintf
17 // data structures for GC
18 #define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
19 #define BAMBOO_LARGE_SMEM_BOUND (BAMBOO_SMEM_SIZE_L*NUMCORES4GC)
20 // let each gc core to have one big block, this is very important
21 // for the computation of NUMBLOCKS(s, n), DO NOT change this!
24 #define GC_NUM_FLUSH_DTLB 1
25 unsigned int gc_num_flush_dtlb;
37 INITPHASE = 0x0, // 0x0
40 SUBTLECOMPACTPHASE, // 0x3
44 PREFINISHPHASE, // 0x6
46 FINISHPHASE // 0x6/0x7
50 volatile bool gcprocessing;
51 volatile GCPHASETYPE gcphase; // indicating GC phase
53 #define WAITFORGCPHASE(phase) while(gcphase != phase) ;
55 volatile bool gcpreinform; // counter for stopped cores
56 volatile bool gcprecheck; // indicates if there are updated pregc information
58 unsigned int gccurr_heaptop;
59 struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
60 // for mark phase termination
61 volatile unsigned int gccorestatus[NUMCORESACTIVE];//records status of each core
64 volatile unsigned int gcnumsendobjs[2][NUMCORESACTIVE];//# of objects sent out
65 volatile unsigned int gcnumreceiveobjs[2][NUMCORESACTIVE];//# of objects received
66 volatile unsigned int gcnumsrobjs_index;//indicates which entry to record the
67 // info received before phase 1 of the mark finish
69 // the info received in phase 2 must be
70 // recorded in the other entry
71 volatile bool gcbusystatus;
72 unsigned int gcself_numsendobjs;
73 unsigned int gcself_numreceiveobjs;
76 unsigned int gcheaptop;
77 unsigned int gcloads[NUMCORES4GC];
78 unsigned int gctopcore; // the core host the top of the heap
79 unsigned int gctopblock; // the number of current top block
81 unsigned int gcnumlobjs;
83 // compact instruction
84 unsigned int gcmarkedptrbound;
85 unsigned int gcblock2fill;
86 unsigned int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
87 unsigned int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
89 unsigned int gcmovestartaddr;
90 unsigned int gcdstcore;
91 volatile bool gctomove;
92 unsigned int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
93 volatile unsigned int gcmovepending;
95 // shared memory pointer for pointer mapping tbls
96 // In GC version, this block of memory is located at the bottom of the
97 // shared memory, right on the top of the smem tbl.
98 // The bottom of the shared memory = sbstart tbl + smemtbl + bamboo_rmsp
99 // These three types of table are always reside at the bottom of the shared
100 // memory and will never be moved or garbage collected
101 unsigned int * gcmappingtbl;
102 unsigned int bamboo_rmsp_size;
103 unsigned int bamboo_baseobjsize;
105 // table recording the starting address of each small block
106 // (size is BAMBOO_SMEM_SIZE)
107 // Note: 1. this table always resides on the very bottom of the shared memory
108 // 2. it is not counted in the shared heap, would never be garbage
112 unsigned int gcsbstarttbl_len;
114 unsigned int gcreservedsb; // number of reserved sblock for sbstarttbl
115 unsigned int gcnumblock; // number of total blocks in the shared mem
116 unsigned int gcbaseva; // base va for shared memory without reserved sblocks
117 #ifdef GC_CACHE_ADAPT
118 unsigned int gctopva; // top va for shared memory without reserved sblocks
119 volatile bool gccachestage;
120 // table recording the sampling data collected for cache adaption
121 int * gccachesamplingtbl;
122 int * gccachesamplingtbl_local;
123 unsigned int size_cachesamplingtbl_local;
124 int * gccachesamplingtbl_r;
125 int * gccachesamplingtbl_local_r;
126 unsigned int size_cachesamplingtbl_local_r;
127 int * gccachepolicytbl;
128 unsigned int size_cachepolicytbl;
129 #endif // GC_CACHE_ADAPT
131 #define OBJMAPPINGINDEX(p) (((unsigned int)p-gcbaseva)/bamboo_baseobjsize)
133 #define ISSHAREDOBJ(p) \
134 ((((unsigned int)p)>=gcbaseva)&&(((unsigned int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
136 #define ALIGNSIZE(s, as) \
137 (*((unsigned int*)as))=((((unsigned int)(s-1))&(~(BAMBOO_CACHE_LINE_MASK)))+(BAMBOO_CACHE_LINE_SIZE))
139 // mapping of pointer to block # (start from 0), here the block # is
141 #define BLOCKINDEX(p, b) \
143 unsigned int t = (p) - gcbaseva; \
144 if(t < (BAMBOO_LARGE_SMEM_BOUND)) { \
145 (*((unsigned int*)b)) = t / (BAMBOO_SMEM_SIZE_L); \
147 (*((unsigned int*)b)) = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); \
151 // mapping of pointer to core #
152 #define RESIDECORE(p, c) \
154 if(1 == (NUMCORES4GC)) { \
155 (*((unsigned int*)c)) = 0; \
158 BLOCKINDEX((p), &b); \
159 (*((unsigned int*)c)) = gc_block2core[(b%(NUMCORES4GC*2))]; \
163 // NOTE: n starts from 0
164 // mapping of heaptop (how many bytes there are in the local heap) to
165 // the number of the block
166 // the number of the block indicates that the block is the xth block on
168 #define NUMBLOCKS(s, n) \
169 if(s < (BAMBOO_SMEM_SIZE_L)) { \
170 (*((unsigned int*)(n))) = 0; \
172 (*((unsigned int*)(n))) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
175 #define OFFSET(s, o) \
176 if(s < BAMBOO_SMEM_SIZE_L) { \
177 (*((unsigned int*)(o))) = (s); \
179 (*((unsigned int*)(o))) = ((s)-(BAMBOO_SMEM_SIZE_L))%(BAMBOO_SMEM_SIZE); \
182 #define OFFSET2BASEVA(i) \
183 (((i)<NUMCORES4GC)?(BAMBOO_SMEM_SIZE_L*(i)):(BAMBOO_SMEM_SIZE*((i)-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND))
185 #define BLOCKSIZE(c) \
186 ((c)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE)
188 // mapping of (core #, index of the block) to the global block index
189 #define BLOCKINDEX2(c, n) \
190 (gc_core2block[(2*(c))+((n)%2)]+((NUMCORES4GC*2)*((n)/2)))
192 #define BOUNDPTR(b) \
193 (((b)<NUMCORES4GC)?(((b)+1)*BAMBOO_SMEM_SIZE_L):(BAMBOO_LARGE_SMEM_BOUND+((b)-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE))
195 #define BLOCKBOUND(n) \
196 (((n)==0)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*(n))
198 // mapping of (core #, number of the block) to the base pointer of the block
199 #define BASEPTR(c, n, p) \
201 unsigned int b = BLOCKINDEX2((c), (n)); \
202 if(b < (NUMCORES4GC)) { \
203 (*((unsigned int*)p)) = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
205 (*((unsigned int*)p)) = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
206 (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
210 // the next core in the top of the heap
211 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
213 // close current block, fill the header
214 #define CLOSEBLOCK(base, size) \
216 BAMBOO_MEMSET_WH((base), '\0', BAMBOO_CACHE_LINE_SIZE); \
217 *((int*)(base)) = (size); \
220 // check if all cores are stall now
221 #define GC_CHECK_ALL_CORE_STATUS(f) \
223 gccorestatus[BAMBOO_NUM_OF_CORE] = 0; \
225 if(gc_checkAllCoreStatus()) { \
231 // send a 1-word msg to all clients
232 #define GC_SEND_MSG_1_TO_CLIENT(m) \
234 for(int i = 0; i < NUMCORESACTIVE; ++i) { \
235 gccorestatus[i] = 1; \
236 if(BAMBOO_NUM_OF_CORE != i) { \
237 send_msg_1(i, (m)); \
242 #define ISLOCAL(p) (hostcore(p)==BAMBOO_NUM_OF_CORE)
244 void initmulticoregcdata();
245 void dismulticoregcdata();
246 bool gc_checkAllCoreStatus();
247 bool gc(struct garbagelist * stackptr); // core coordinator routine
248 void gc_collect(struct garbagelist* stackptr); //core collector routine
249 void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
250 void master_mark(struct garbagelist *stackptr);
251 void master_getlargeobjs();
252 void master_compact();
253 void master_updaterefs();
254 void master_finish();
255 void gc_master(struct garbagelist * stackptr);
258 void transferMarkResults_I();
259 bool gcfindSpareMem_I(unsigned int * startaddr,unsigned int * tomove,unsigned int * dstcore,unsigned int requiredmem,unsigned int requiredcore);
261 #define INITMULTICOREGCDATA() initmulticoregcdata()
262 #define DISMULTICOREGCDATA() dismulticoregcdata()
263 #else // MULTICORE_GC
264 #define INITMULTICOREGCDATA()
265 #define DISMULTICOREGCDATA()
266 #endif // MULTICORE_GC
267 #endif // BAMBOO_MULTICORE_GARBAGE_H