1 #ifndef BAMBOO_MULTICORE_CACHE_H
2 #define BAMBOO_MULTICORE_CACHE_H
5 #include "multicoremem.h"
6 #include "multicoregccompact.h"
7 #include "multicoregarbage.h"
10 // sampling unit to compute access frequency, this should be consistent all the
12 #define GC_CACHE_SAMPLING_UNIT 0x80000
13 // freqeuency to trigger timer interrupt
14 #define GC_TILE_TIMER_EVENT_SETTING 10000000
16 // data structure to record policy information for a page
17 // should be consistent with multicoreruntime.h
23 // policy type, should be enough to accommodate all 4 possible polices
24 unsigned int cache_mode : 3;
26 unsigned int __reserved_0 : 5;
27 // Location Override Target Y
28 unsigned int lotar_y : 4;
30 unsigned int __reserved_1 : 4;
31 // Location Override Target X
32 unsigned int lotar_x : 4;
34 unsigned int __reserved_2 : 12;
36 } bamboo_cache_policy_t;
38 #define BAMBOO_CACHE_MODE_LOCAL 1 // locally cached
39 #define BAMBOO_CACHE_MODE_HASH 2 // hash-for-home
40 #define BAMBOO_CACHE_MODE_NONE 3 // no caching
41 #define BAMBOO_CACHE_MODE_COORDS 4 // cached on a specific core
43 // data structure to hold page information while calculating revised sampling
44 // info during compaction
45 typedef struct gc_cache_revise_info {
46 // the start address in current original page to be compacted to current
48 void * orig_page_start_va;
49 // the end of current original page to be compacted
50 void * orig_page_end_va;
51 // the index of current original page
52 unsigned int orig_page_index;
53 // the start address in current destination page to where the current original
55 void * to_page_start_va;
56 // the end of current destination page
57 void * to_page_end_va;
58 // the index of current destination page
59 unsigned int to_page_index;
60 } gc_cache_revise_info_t;
62 // global variable holding page information to compute revised sampling info
63 extern gc_cache_revise_info_t gc_cache_revise_information;
65 /* This function initialize the gc_cache_revise_information. It should be
66 * invoked before we start compaction.
68 INLINE static void samplingDataReviseInit(struct moveHelper * orig,struct moveHelper * to) {
69 // initialize the destination page info
70 gc_cache_revise_information.to_page_start_va=to->ptr;
71 unsigned int toindex=(unsigned INTPTR)(to->base-gcbaseva)/BAMBOO_PAGE_SIZE;
72 gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(toindex+1);
73 gc_cache_revise_information.to_page_index=toindex;
74 // initilaize the original page info
75 unsigned int origindex=((unsigned INTPTR)(orig->base-gcbaseva))/BAMBOO_PAGE_SIZE;
76 gc_cache_revise_information.orig_page_start_va=orig->ptr;
77 gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(origindex+1);
78 gc_cache_revise_information.orig_page_index=origindex;
81 /* This function computes the revised profiling data of the first closed destination
82 * page of an object that acrosses multiple pages
84 INLINE static void firstPageConvert(bool origclosefirst, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
85 unsigned INTPTR topage=gc_cache_revise_information.to_page_index;
86 unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index;
87 int * newtable=&gccachesamplingtbl_r[topage];
88 int * oldtable=&gccachesamplingtbl[oldpage];
89 // compute the revised profiling info for the start destination page
91 // the start original page closes first, now compute the revised profiling
92 // info for the start destination page.
93 // The start destination page = the rest of the start original page +
94 // delta_fator from the next original page
95 int * oldtable_next=&gccachesamplingtbl[oldpage+1];
96 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
97 (*newtable)=((*newtable)+(*oldtable)*main_factor+(*oldtable_next)*delta_factor);
98 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
99 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
100 oldtable_next=(int*) (((char *)oldtable_next)+size_cachesamplingtbl_local);
102 // close the start original page
103 gc_cache_revise_information.orig_page_start_va+=main_factor+delta_factor;
104 gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
105 gc_cache_revise_information.orig_page_index++;
107 // the start destination page closes first, now compute the revised
108 // profiling info for it.
109 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
110 (*newtable)=((*newtable)+(*oldtable)*main_factor);
111 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
112 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
114 // record the new start of the original page
115 gc_cache_revise_information.orig_page_start_va+=main_factor;
117 // close the start original page and destination page
118 gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
119 gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
120 gc_cache_revise_information.to_page_index++;
123 /* This function computes the revised profiling info for closed destination
124 * pages that are occupied by one object that acrosses multiple pages.
125 * the destination page = main_factor from the first unclosed original page
126 * + delta_factor from the next unclosed original page
128 INLINE static void restClosedPageConvert(void * current_ptr, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
129 while(gc_cache_revise_information.to_page_end_va<=current_ptr) {
130 unsigned INTPTR topage=gc_cache_revise_information.to_page_index;
131 unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index;
132 int *newtable=&gccachesamplingtbl_r[topage];
133 int *oldtable=&gccachesamplingtbl[oldpage];
134 int *oldtable_next=&gccachesamplingtbl[oldpage+1];
136 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
137 (*newtable)=((*newtable)+(*oldtable)*main_factor+(*oldtable_next)*delta_factor);
138 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
139 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
140 oldtable_next=(int*) (((char *)oldtable_next)+size_cachesamplingtbl_local);
143 // close the original page and the destination page
144 gc_cache_revise_information.orig_page_start_va+=BAMBOO_PAGE_SIZE;
145 gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
146 gc_cache_revise_information.orig_page_index++;
147 gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
148 gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
149 gc_cache_revise_information.to_page_index++;
153 /* This function computes the revised profiling info for the last
154 * destination page of an object that acrosses multiple pages.
156 INLINE static void lastPageConvert(void * current_ptr) {
157 unsigned INTPTR to_factor=current_ptr-gc_cache_revise_information.to_page_start_va;
158 unsigned INTPTR topage=gc_cache_revise_information.to_page_index;
159 unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index;
160 int *newtable=&gccachesamplingtbl_r[topage];
161 int *oldtable=&gccachesamplingtbl[oldpage];
163 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
164 (*newtable)=((*newtable)+(*oldtable)*to_factor);
165 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
166 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
168 // do not need to set gc_cache_revise_information here for the last
169 // original/destination page as it will be set in completePageConvert()
172 /* This function converts multiple original pages profiling data to multiple
173 * destination pages' profiling data
175 INLINE static void samplingDataConvertMultiple(void * current_ptr) {
176 // first decide which page close first: original or destination?
177 unsigned INTPTR to_factor=(unsigned INTPTR)(gc_cache_revise_information.to_page_end_va-gc_cache_revise_information.to_page_start_va);
178 unsigned INTPTR orig_factor=(unsigned INTPTR)(gc_cache_revise_information.orig_page_end_va-gc_cache_revise_information.orig_page_start_va);
179 bool origclosefirst=to_factor>orig_factor;
180 unsigned INTPTR delta_factor=(origclosefirst)?(to_factor-orig_factor):(orig_factor-to_factor);
181 unsigned INTPTR main_factor=(origclosefirst)?orig_factor:to_factor;
183 // compute the revised profiling info for the start destination page
184 firstPageConvert(origclosefirst, main_factor, delta_factor);
185 // update main_factor/delta_factor
187 // for the following destination pages that are fully used:
188 // the destination page = (page_size-delta_factor) from the
189 // first unclosed original page + delta_factor
190 // from the next unclosed original page
191 // we always use main_factor to represent the factor from the first
192 // unclosed original page
193 main_factor=BAMBOO_PAGE_SIZE-delta_factor;
195 // for the following destination pages that are fully used:
196 // the destination page = delta_factor from the first unclosed original
197 // page + (page_size-delta_factor) from the next
198 // unclosed original page
199 // we always use main_factor to represent the factor from the first
200 // unclosed original page
201 main_factor=delta_factor;
202 delta_factor=BAMBOO_PAGE_SIZE-delta_factor;
205 // compute the revised profiling info for the following closed destination
207 restClosedPageConvert(current_ptr, main_factor, delta_factor);
209 // compute the revised profiling info for the last destination page if needed
210 lastPageConvert(current_ptr);
213 /* This function converts originial pages' profiling data to destination pages'
215 * The parameter current_ptr indicates the current position in the destination
217 * Note that there could be objects that across pages. In such cases, there are
218 * multiple orig/to pages are closed and all these to pages' profiling data
219 * should be properly updated.
221 INLINE static void samplingDataConvert(void * current_ptr) {
222 if(gc_cache_revise_information.to_page_end_va<current_ptr) {
223 // multiple pages are closed
224 samplingDataConvertMultiple(current_ptr);
226 unsigned INTPTR tmp_factor=(unsigned INTPTR)(current_ptr-gc_cache_revise_information.to_page_start_va);
228 unsigned INTPTR topage=gc_cache_revise_information.to_page_index;
229 unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index;
230 int * newtable=&gccachesamplingtbl_r[topage];
231 int * oldtable=&gccachesamplingtbl[oldpage];
233 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
234 (*newtable)=((*newtable)+(*oldtable)*tmp_factor);
235 newtable=(int*)(((char *)newtable)+size_cachesamplingtbl_local_r);
236 oldtable=(int*) (((char *)oldtable)+size_cachesamplingtbl_local);
244 INLINE static void completePageConvert(void * origptr, void * toptr, void * current_ptr) {
245 bool closeToPage=(unsigned int)(toptr)>=(unsigned int)(gc_cache_revise_information.to_page_end_va);
246 bool closeOrigPage=(unsigned int)(origptr)>=(unsigned int)(gc_cache_revise_information.orig_page_end_va);
247 if(closeToPage||closeOrigPage) {
248 // end of one or more orig/to page
249 // compute the impact of the original page(s) for the desitination page(s)
250 samplingDataConvert(current_ptr);
251 // prepare for an new orig page
252 unsigned INTPTR tmp_index=((unsigned INTPTR)(origptr-gcbaseva))/BAMBOO_PAGE_SIZE;
253 gc_cache_revise_information.orig_page_start_va=origptr;
254 gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(tmp_index+1);
255 gc_cache_revise_information.orig_page_index=tmp_index;
256 gc_cache_revise_information.to_page_start_va=toptr;
258 unsigned INTPTR to_index=((unsigned INTPTR)(toptr-gcbaseva))/BAMBOO_PAGE_SIZE;
259 gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(to_index+1);
260 gc_cache_revise_information.to_page_index=to_index;
265 void cacheAdapt_gc(bool isgccachestage);
266 void cacheAdapt_master();
267 void cacheAdapt_mutator();
268 void cacheAdapt_phase_client();
269 void cacheAdapt_phase_master();
270 void gc_output_cache_sampling();
271 void gc_output_cache_sampling_r();
273 #ifdef GC_CACHE_SAMPLING
274 // enable the timer interrupt
275 #define CACHEADAPT_ENABLE_TIMER() \
277 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); \
278 bamboo_unmask_timer_intr(); \
279 bamboo_dtlb_sampling_process(); \
282 #define CACHEADAPT_ENABLE_TIMER()
284 // disable the TILE_TIMER interrupt
285 #define CACHEADAPT_DISABLE_TIMER() bamboo_mask_timer_intr()
287 #ifdef GC_CACHE_SAMPLING
288 // reset the sampling arrays
289 #define CACHEADAPT_SAMPING_RESET() bamboo_dtlb_sampling_reset()
290 #else // GC_CACHE_SAMPING
291 #define CACHEADAPT_SAMPING_RESET()
294 #define CACHEADAPT_SAMPLING_DATA_REVISE_INIT(o,t) \
295 samplingDataReviseInit((o),(t))
296 #define CACHEADAPT_SAMPLING_DATA_CONVERT(p) samplingDataConvert((p))
297 #define CACHEADAPT_COMPLETE_PAGE_CONVERT(o, t, p) \
298 completePageConvert((o), (t), (p));
300 #define CACHEADAPT_GC(b) cacheAdapt_gc(b)
301 #define CACHEADAPT_MASTER() cacheAdapt_master()
302 #define CACHEADAPT_PHASE_CLIENT() cacheAdapt_phase_client()
303 #define CACHEADAPT_PHASE_MASTER() cacheAdapt_phase_master()
305 #ifdef GC_CACHE_ADAPT_OUTPUT
306 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING() gc_output_cache_sampling()
307 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING_R() gc_output_cache_sampling_r()
309 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING()
310 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING_R()
313 #ifdef GC_CACHE_ADAPT_OUTPUT_POLICY
315 #define CACHEADAPT_OUTPUT_CACHE_POLICY() \
318 bamboo_output_cache_policy(); \
322 #define CACHEADAPT_OUTPUT_CACHE_POLICY() bamboo_output_cache_policy()
324 #else // GC_CACHE_ADAPT_OUTPUT_POLICY
325 #define CACHEADAPT_OUTPUT_CACHE_POLICY()
326 #endif // GC_CACHE_ADAPT_OUTPUT
328 #else // GC_CACHE_ADAPT
329 #define CACHEADAPT_ENABLE_TIMER()
330 #define CACHEADAPT_DISABLE_TIMER()
331 #define CACHEADAPT_SAMPING_RESET()
332 #define CACHEADAPT_SAMPLING_DATA_REVISE_INIT(o,t)
333 #define CACHEADAPT_SAMPLING_DATA_CONVERT(p)
334 #define CACHEADAPT_COMPLETE_PAGE_CONVERT(o, t, p, b)
335 #define CACHEADAPT_GC(b)
336 #define CACHEADAPT_MASTER()
337 #define CACHEADAPT_PHASE_CLIENT()
338 #define CACHEADAPT_PHASE_MASTER()
339 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING()
340 #define CACHEADAPT_OUTPUT_CACHE_SAMPLING_R()
341 #define CACHEADAPT_OUTPUT_CACHE_POLICY()
342 #endif // GC_CACHE_ADAPT
343 #else // MULTICORE_GC
344 #define CACHEADAPT_ENABLE_TIMER()
345 #define CACHEADAPT_DISABLE_TIMER()
346 #endif // MULTICORE_GC
348 #endif // BAMBOO_MULTICORE_CACHE_H