Add gcprofile to PMC garbage collector and compute the size of allocated obj instead...
[IRC.git] / Robust / src / Runtime / bamboo / multicoregcprofile.h
1 #ifndef BAMBOO_MULTICORE_GC_PROFILE_H
2 #define BAMBOO_MULTICORE_GC_PROFILE_H
3 #if defined(MULTICORE_GC)||defined(PMC_GC)
4 #include "multicore.h"
5 #include "runtime_arch.h"
6 #include "structdefs.h"
7
8 #ifdef GC_PROFILE
9 #define GCINFOLENGTH 100
10
11 #ifdef GC_CACHE_ADAPT
12 #define GC_PROFILE_NUM_FIELD 15
13 #elif defined PMC_GC
14 #define GC_PROFILE_NUM_FIELD 15
15 #else
16 #define GC_PROFILE_NUM_FIELD 14
17 #endif // GC_CACHE_ADAPT
18
19 typedef struct gc_info {
20   unsigned long long time[GC_PROFILE_NUM_FIELD];
21   unsigned int index;
22 } GCInfo;
23
24 // the following data are supposed to be only valid on the master core
25 // the other cores should not maintain them
26 GCInfo * gc_infoArray[GCINFOLENGTH];
27 unsigned int gc_infoIndex;
28 bool gc_infoOverflow;
29 unsigned int gc_num_profiles;
30 unsigned int gc_size_allocatedobj;
31 unsigned long long gc_num_livespace;
32 unsigned long long gc_num_freespace;
33 unsigned long long gc_num_lobjspace;
34 unsigned int gc_num_lobj;
35
36 // these data should be maintained by all gc cores
37 unsigned int gc_num_liveobj;
38 unsigned int gc_num_forwardobj;
39
40
41 #ifdef MGC_SPEC
42 volatile bool gc_profile_flag;
43 #endif
44
45 void initmulticoregcprofiledata(void);
46 void gc_outputProfileData();
47 void gc_outputProfileDataReadable();
48
49 INLINE static void gc_profileInit() {
50   gc_num_livespace = 0;
51   gc_num_freespace = 0;
52   gc_num_lobj = 0;
53   gc_num_lobjspace = 0;
54   gc_num_liveobj = 0;
55   gc_num_forwardobj = 0;
56   gc_num_profiles = NUMCORESACTIVE - 1;
57 }
58
59 // these *_master function can only be invoked by the master core
60 INLINE static void gc_profileStart_master(void) {
61   if(!gc_infoOverflow) {
62     GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
63     gc_infoArray[gc_infoIndex] = gcInfo;
64     gcInfo->index = 1;
65     gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
66   }
67 }
68
69 INLINE static void gc_profileItem_master(void) {
70   if(!gc_infoOverflow) {
71     GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
72     gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
73   }
74 }
75
76 INLINE static void gc_profileEnd_master(void) {
77   if(!gc_infoOverflow) {
78     GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
79     gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
80     gcInfo->time[gcInfo->index++] = gc_num_livespace;
81     gcInfo->time[gcInfo->index++] = gc_num_freespace;
82     gcInfo->time[gcInfo->index++] = gc_num_lobj;
83     gcInfo->time[gcInfo->index++] = gc_num_lobjspace;
84     gcInfo->time[gcInfo->index++] = gc_size_allocatedobj;
85     gcInfo->time[gcInfo->index++] = gc_num_liveobj;
86     gcInfo->time[gcInfo->index++] = gc_num_forwardobj;
87     gc_infoIndex++;
88     gc_size_allocatedobj = 0; // reset the counter of allocated obj
89     if(gc_infoIndex == GCINFOLENGTH) {
90       gc_infoOverflow = true;
91     }
92   }
93 }
94
95 #define INIT_MULTICORE_GCPROFILE_DATA() initmulticoregcprofiledata()
96 #define GC_OUTPUT_PROFILE_DATA() gc_outputProfileData()
97 // send the num of obj/liveobj/forwardobj to the startupcore
98 #define GCPROFILE_INFO_2_MASTER() \
99   { \
100     if(STARTUPCORE != BAMBOO_NUM_OF_CORE) { \
101       send_msg_3(STARTUPCORE,GCPROFILES,gc_num_liveobj,gc_num_forwardobj); \
102     }\
103   }
104
105 #ifdef MGC_SPEC
106 // record allocated obj info
107 #define GCPROFILE_RECORD_ALLOCATED_OBJ(size) \
108   { \
109     if(gc_profile_flag) {\
110       gc_size_allocatedobj += size; \
111     } \
112   }
113 // record lobj info
114 #define GCPROFILE_RECORD_LOBJ() \
115   { \
116       gc_num_lobj++; \
117   }
118 // record lobj space info
119 #define GCPROFILE_RECORD_LOBJSPACE() \
120   { \
121     if(gc_profile_flag) { \
122       gc_num_lobjspace = sumsize; \
123     } \
124   }
125 #ifdef PMC_GC
126 // check the live/free space info
127 #define GCPROFILE_RECORD_SPACE_MASTER() \
128   { \
129     if(gc_profile_flag) { \
130       gc_num_freespace = 0; \
131       for(int i=0;i<NUMCORES4GC;i+=2) { \
132         void *startptr=pmc_heapptr->regions[i].lastptr; \
133         void *finishptr=(i+1)<NUMCORES4GC?pmc_heapptr->regions[i+1].lastptr:pmc_heapptr->regions[i].endptr; \
134         gc_num_freespace += finishptr-startptr; \ 
135       } \
136       gc_num_livespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_freespace; \
137     } \
138   }
139 #else
140 // check the live/free space info
141 #define GCPROFILE_RECORD_SPACE_MASTER() \
142   { \
143     if(gc_profile_flag) { \
144       gc_num_freespace = 0; \
145       block_t lowestblock=allocationinfo.lowestfreeblock; \
146       for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) { \
147         struct blockrecord * block=&allocationinfo.blocktable[searchblock]; \
148         if (block->status==BS_FREE) { \
149           gc_num_freespace+=block->freespace&~BAMBOO_CACHE_LINE_MASK; \
150         } \
151       } \
152       gc_num_livespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_freespace; \
153     } \
154   }
155 #endif
156 // record forward obj info
157 #define GCPROFILE_RECORD_FORWARD_OBJ() \
158   { \
159       gc_num_forwardobj++; \
160   }
161 // record live obj info
162 #define GCPROFILE_RECORD_LIVE_OBJ() \
163   { \
164       gc_num_liveobj++; \
165   }
166 #define GCPROFILE_START_MASTER() \
167   { \
168     if(gc_profile_flag) { \
169       gc_profileStart_master(); \
170     } \
171   }
172 #define GCPROFILE_ITEM_MASTER() \
173   { \
174     if(gc_profile_flag) { \
175       gc_profileItem_master(); \
176     } \
177   }
178 #define GCPROFILE_END_MASTER() \
179   { \
180     if(gc_profile_flag) { \
181       gc_profileEnd_master(); \
182     } \
183   }
184 #else // MGC_SPEC
185 // record allocated obj info
186 #define GCPROFILE_RECORD_ALLOCATED_OBJ(size) \
187   { \
188     gc_size_allocatedobj += size; \
189   }
190 #define GCPROFILE_RECORD_LOBJ() (gc_num_lobj++)
191 #define GCPROFILE_RECORD_LOBJSPACE() (gc_num_lobjspace = sumsize)
192 #ifdef PMC_GC
193 // check the live/free space info
194 #define GCPROFILE_RECORD_SPACE_MASTER() \
195   { \
196     gc_num_freespace = 0; \
197     for(int i=0;i<NUMCORES4GC;i+=2) { \
198       void *startptr=pmc_heapptr->regions[i].lastptr; \
199       void *finishptr=(i+1)<NUMCORES4GC?pmc_heapptr->regions[i+1].lastptr:pmc_heapptr->regions[i].endptr; \
200       gc_num_freespace += finishptr-startptr; \ 
201     } \
202     gc_num_livespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_freespace; \
203   }
204 #else
205 #define GCPROFILE_RECORD_SPACE_MASTER() \
206   { \
207     gc_num_freespace = 0; \
208     block_t lowestblock=allocationinfo.lowestfreeblock; \
209     for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) { \
210       struct blockrecord * block=&allocationinfo.blocktable[searchblock]; \
211       if (block->status==BS_FREE) { \
212         gc_num_freespace+=block->freespace&~BAMBOO_CACHE_LINE_MASK; \
213       } \
214     } \
215     gc_num_livespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_freespace; \
216   }
217 #endif
218 #define GCPROFILE_RECORD_FORWARD_OBJ() (gc_num_forwardobj++)
219 #define GCPROFILE_RECORD_LIVE_OBJ() (gc_num_liveobj++)
220 #define GCPROFILE_START_MASTER() gc_profileStart_master()
221 #define GCPROFILE_ITEM_MASTER() gc_profileItem_master()
222 #define GCPROFILE_END_MASTER() gc_profileEnd_master()
223 #endif // MGC_SPEC
224
225 #define GCPROFILE_INIT() gc_profileInit()
226
227 #else // GC_PROFILE
228 #define GCPROFILE_RECORD_ALLOCATED_OBJ(size) 
229 #define INIT_MULTICORE_GCPROFILE_DATA()
230 #define GC_OUTPUT_PROFILE_DATA() 
231 #define GCPROFILE_INFO_2_MASTER() 
232 #define GCPROFILE_RECORD_LOBJ()
233 #define GCPROFILE_RECORD_LOBJSPACE()
234 #define GCPROFILE_RECORD_SPACE()
235 #define GCPROFILE_RECORD_FORWARD_OBJ() 
236 #define GCPROFILE_RECORD_LIVE_OBJ() 
237 #define GCPROFILE_START_MASTER()
238 #define GCPROFILE_ITEM_MASTER()
239 #define GCPROFILE_END_MASTER()
240 #define GCPROFILE_INIT()
241 #endif // GC_PROFILE
242
243 #endif // MULTICORE_GC
244 #endif // BAMBOO_MULTICORE_GC_PROFILE_H