1 #ifndef MULTICORE_GARBAGE_H
2 #define MULTICORE_GARBAGE_H
3 #include "multicoregc.h"
4 #include "multicorehelper.h" // for mappins between core # and block #
5 #include "structdefs.h"
7 #include "GCSharedHash.h"
9 #include "multicorecache.h"
10 #endif // GC_CACHE_ADAPT
16 // data structures for GC
18 #define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
20 #define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
22 #define BAMBOO_LARGE_SMEM_BOUND (BAMBOO_SMEM_SIZE_L*NUMCORES4GC)
23 // let each gc core to have one big block, this is very important
24 // for the computation of NUMBLOCKS(s, n), DO NOT change this!
27 #define GC_NUM_FLUSH_DTLB 1
28 int gc_num_flush_dtlb;
35 #define GCINFOLENGTH 100
38 #define GC_PROFILE_NUM_FIELD 16
40 #define GC_PROFILE_NUM_FIELD 15
41 #endif // GC_CACHE_ADAPT
43 typedef struct gc_info {
44 unsigned long long time[GC_PROFILE_NUM_FIELD];
48 GCInfo * gc_infoArray[GCINFOLENGTH];
51 unsigned long long gc_num_livespace;
52 unsigned long long gc_num_freespace;
53 unsigned long long gc_num_lobjspace;
54 unsigned int gc_num_lobj;
56 unsigned int gc_num_liveobj;
57 unsigned int gc_num_obj;
58 unsigned int gc_num_forwardobj;
74 INITPHASE = 0x0, // 0x0
77 SUBTLECOMPACTPHASE, // 0x3
81 PREFINISHPHASE, // 0x6
82 #endif // GC_CACHE_ADAPT
83 FINISHPHASE // 0x6/0x7
87 volatile bool gcprocessing;
88 volatile GCPHASETYPE gcphase; // indicating GC phase
90 volatile bool gcpreinform; // counter for stopped cores
91 volatile bool gcprecheck; // indicates if there are updated pregc information
94 struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
95 // for mark phase termination
96 volatile int gccorestatus[NUMCORESACTIVE]; // records status of each core
99 volatile int gcnumsendobjs[2][NUMCORESACTIVE]; // the # of objects sent out
100 volatile int gcnumreceiveobjs[2][NUMCORESACTIVE]; // the # of objects received
101 volatile int gcnumsrobjs_index; // indicates which entry to record the info
102 // received before phase 1 of the mark finish
104 // the info received in phase 2 must be
105 // recorded in the other entry
106 volatile bool gcbusystatus;
107 int gcself_numsendobjs;
108 int gcself_numreceiveobjs;
110 // for load balancing
112 int gcloads[NUMCORES4GC];
113 int gctopcore; // the core host the top of the heap
114 int gctopblock; // the number of current top block
118 // compact instruction
119 INTPTR gcmarkedptrbound;
121 int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
122 int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
124 INTPTR gcmovestartaddr;
126 volatile bool gctomove;
127 int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
128 volatile int gcmovepending;
130 // shared memory pointer for shared pointer mapping tbls
131 // In GC version, this block of memory is located at the bottom of the
132 // shared memory, right on the top of the smem tbl.
133 // The bottom of the shared memory = sbstart tbl + smemtbl
134 // + NUMCORES4GC bamboo_rmsp
135 // These three types of table are always reside at the bottom of the shared
136 // memory and will never be moved or garbage collected
137 #ifdef GC_SMALLPAGESIZE
138 #define BAMBOO_RMSP_SIZE (1024 * 1024)
140 #define BAMBOO_RMSP_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024)
143 // shared pointer mapping tbl
144 mgcsharedhashtbl_t * gcsharedptbl;
145 // remote shared pointer tbls
146 mgcsharedhashtbl_t * gcrpointertbls[NUMCORES4GC];
148 #ifdef LOCALHASHTBL_TEST
149 struct RuntimeHash * gcpointertbl;
151 mgchashtable_t * gcpointertbl;
155 volatile bool gcismapped;
157 // table recording the starting address of each small block
158 // (size is BAMBOO_SMEM_SIZE)
159 // Note: 1. this table always resides on the very bottom of the shared memory
160 // 2. it is not counted in the shared heap, would never be garbage
162 INTPTR * gcsbstarttbl;
163 int gcreservedsb; // number of reserved sblock for sbstarttbl
164 int gcnumblock; // number of total blocks in the shared mem
165 int gcbaseva; // base va for shared memory without reserved sblocks
166 #ifdef GC_CACHE_ADAPT
167 int gctopva; // top va for shared memory without reserved sblocks
168 volatile bool gccachestage;
169 // table recording the sampling data collected for cache adaption
170 unsigned int * gccachesamplingtbl;
171 unsigned int * gccachesamplingtbl_local;
172 unsigned int size_cachesamplingtbl_local;
173 unsigned int * gccachesamplingtbl_r;
174 unsigned int * gccachesamplingtbl_local_r;
175 unsigned int size_cachesamplingtbl_local_r;
176 int * gccachepolicytbl;
177 unsigned int size_cachepolicytbl;
178 #endif // GC_CACHE_ADAPT
180 #define ISSHAREDOBJ(p) \
181 ((((int)p)>gcbaseva)&&(((int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
183 #define ALIGNSIZE(s, as) \
184 (*((int*)as)) = (((s) & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE))
186 // mapping of pointer to block # (start from 0), here the block # is
188 #define BLOCKINDEX(p, b) \
190 int t = (p) - gcbaseva; \
191 if(t < (BAMBOO_LARGE_SMEM_BOUND)) { \
192 (*((int*)b)) = t / (BAMBOO_SMEM_SIZE_L); \
194 (*((int*)b)) = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); \
198 // mapping of pointer to core #
199 #define RESIDECORE(p, c) \
201 if(1 == (NUMCORES4GC)) { \
205 BLOCKINDEX((p), &b); \
206 (*((int*)c)) = gc_block2core[(b%(NUMCORES4GC*2))]; \
210 // NOTE: n starts from 0
211 // mapping of heaptop (how many bytes there are in the local heap) to
212 // the number of the block
213 // the number of the block indicates that the block is the xth block on
215 #define NUMBLOCKS(s, n) \
216 if(s < (BAMBOO_SMEM_SIZE_L)) { \
217 (*((int*)(n))) = 0; \
219 (*((int*)(n))) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
222 #define OFFSET(s, o) \
223 if(s < BAMBOO_SMEM_SIZE_L) { \
224 (*((int*)(o))) = (s); \
226 (*((int*)(o))) = ((s) - (BAMBOO_SMEM_SIZE_L)) % (BAMBOO_SMEM_SIZE); \
229 // mapping of (core #, index of the block) to the global block index
230 #define BLOCKINDEX2(c, n) (gc_core2block[(2*(c))+((n)%2)]+((NUMCORES4GC*2)*((n)/2)))
232 // mapping of (core #, number of the block) to the base pointer of the block
233 #define BASEPTR(c, n, p) \
235 int b = BLOCKINDEX2((c), (n)); \
236 if(b < (NUMCORES4GC)) { \
237 (*((int*)p)) = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
239 (*((int*)p)) = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
240 (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
244 // the next core in the top of the heap
245 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
247 inline bool gc(struct garbagelist * stackptr); // core coordinator routine
248 inline void gc_collect(struct garbagelist* stackptr); //core collector routine
249 inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
250 inline void transferMarkResults_I();
251 inline void gc_enqueue_I(void *ptr);
252 inline void gc_lobjenqueue_I(void *ptr, int length, int host);
253 inline bool gcfindSpareMem_I(int * startaddr,
259 inline void * gc_lobjdequeue4(int * length, int * host);
260 inline int gc_lobjmoreItems4();
261 inline void gc_lobjqueueinit4();
264 INLINE void gc_profileStart(void);
265 INLINE void gc_profileItem(void);
266 INLINE void gc_profileEnd(void);
267 void gc_outputProfileData();