6 #define SGEN_BINARY_PROTOCOL
9 #include <mono/metadata/sgen-protocol.h>
11 #define SGEN_PROTOCOL_EOF 255
14 read_entry (FILE *in, void **data)
19 if (fread (&type, 1, 1, in) != 1)
20 return SGEN_PROTOCOL_EOF;
22 case SGEN_PROTOCOL_COLLECTION_FORCE: size = sizeof (SGenProtocolCollectionForce); break;
23 case SGEN_PROTOCOL_COLLECTION_BEGIN: size = sizeof (SGenProtocolCollection); break;
24 case SGEN_PROTOCOL_COLLECTION_END: size = sizeof (SGenProtocolCollection); break;
25 case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
26 case SGEN_PROTOCOL_ALLOC_PINNED: size = sizeof (SGenProtocolAlloc); break;
27 case SGEN_PROTOCOL_ALLOC_DEGRADED: size = sizeof (SGenProtocolAlloc); break;
28 case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
29 case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
30 case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
31 case SGEN_PROTOCOL_SCAN_BEGIN: size = sizeof (SGenProtocolScanBegin); break;
32 case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: size = sizeof (SGenProtocolScanVTypeBegin); break;
33 case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
34 case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
35 case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
36 case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
37 case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
38 case SGEN_PROTOCOL_THREAD_SUSPEND: size = sizeof (SGenProtocolThreadSuspend); break;
39 case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
40 case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
41 case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
42 case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
43 case SGEN_PROTOCOL_CARD_SCAN: size = sizeof (SGenProtocolCardScan); break;
44 case SGEN_PROTOCOL_CEMENT: size = sizeof (SGenProtocolCement); break;
45 case SGEN_PROTOCOL_CEMENT_RESET: size = 0; break;
46 case SGEN_PROTOCOL_DISLINK_UPDATE: size = sizeof (SGenProtocolDislinkUpdate); break;
47 case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: size = sizeof (SGenProtocolDislinkUpdateStaged); break;
48 case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: size = sizeof (SGenProtocolDislinkProcessStaged); break;
49 case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN: size = sizeof (SGenProtocolDomainUnload); break;
50 case SGEN_PROTOCOL_DOMAIN_UNLOAD_END: size = sizeof (SGenProtocolDomainUnload); break;
55 *data = malloc (size);
56 if (fread (*data, size, 1, in) != 1)
66 print_entry (int type, void *data)
69 case SGEN_PROTOCOL_COLLECTION_FORCE: {
70 SGenProtocolCollectionForce *entry = data;
71 printf ("collection force generation %d\n", entry->generation);
74 case SGEN_PROTOCOL_COLLECTION_BEGIN: {
75 SGenProtocolCollection *entry = data;
76 printf ("collection begin %d generation %d\n", entry->index, entry->generation);
79 case SGEN_PROTOCOL_COLLECTION_END: {
80 SGenProtocolCollection *entry = data;
81 printf ("collection end %d generation %d\n", entry->index, entry->generation);
84 case SGEN_PROTOCOL_ALLOC: {
85 SGenProtocolAlloc *entry = data;
86 printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
89 case SGEN_PROTOCOL_ALLOC_PINNED: {
90 SGenProtocolAlloc *entry = data;
91 printf ("alloc pinned obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
94 case SGEN_PROTOCOL_ALLOC_DEGRADED: {
95 SGenProtocolAlloc *entry = data;
96 printf ("alloc degraded obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
99 case SGEN_PROTOCOL_COPY: {
100 SGenProtocolCopy *entry = data;
101 printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
104 case SGEN_PROTOCOL_PIN: {
105 SGenProtocolPin *entry = data;
106 printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
109 case SGEN_PROTOCOL_MARK: {
110 SGenProtocolMark *entry = data;
111 printf ("mark obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
114 case SGEN_PROTOCOL_SCAN_BEGIN: {
115 SGenProtocolScanBegin *entry = data;
116 printf ("scan_begin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
119 case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
120 SGenProtocolScanVTypeBegin *entry = data;
121 printf ("scan_vtype_begin obj %p size %d\n", entry->obj, entry->size);
124 case SGEN_PROTOCOL_WBARRIER: {
125 SGenProtocolWBarrier *entry = data;
126 printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
129 case SGEN_PROTOCOL_GLOBAL_REMSET: {
130 SGenProtocolGlobalRemset *entry = data;
131 printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
134 case SGEN_PROTOCOL_PTR_UPDATE: {
135 SGenProtocolPtrUpdate *entry = data;
136 printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
137 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
140 case SGEN_PROTOCOL_CLEANUP: {
141 SGenProtocolCleanup *entry = data;
142 printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
145 case SGEN_PROTOCOL_EMPTY: {
146 SGenProtocolEmpty *entry = data;
147 printf ("empty start %p size %d\n", entry->start, entry->size);
150 case SGEN_PROTOCOL_THREAD_SUSPEND: {
151 SGenProtocolThreadSuspend *entry = data;
152 printf ("thread_suspend thread %p ip %p\n", entry->thread, entry->stopped_ip);
155 case SGEN_PROTOCOL_THREAD_RESTART: {
156 SGenProtocolThreadRestart *entry = data;
157 printf ("thread_restart thread %p\n", entry->thread);
160 case SGEN_PROTOCOL_THREAD_REGISTER: {
161 SGenProtocolThreadRegister *entry = data;
162 printf ("thread_register thread %p\n", entry->thread);
165 case SGEN_PROTOCOL_THREAD_UNREGISTER: {
166 SGenProtocolThreadUnregister *entry = data;
167 printf ("thread_unregister thread %p\n", entry->thread);
170 case SGEN_PROTOCOL_MISSING_REMSET: {
171 SGenProtocolMissingRemset *entry = data;
172 printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
173 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
176 case SGEN_PROTOCOL_CARD_SCAN: {
177 SGenProtocolCardScan *entry = data;
178 printf ("card_scan start %p size %d\n", entry->start, entry->size);
181 case SGEN_PROTOCOL_CEMENT: {
182 SGenProtocolCement *entry = data;
183 printf ("cement obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
186 case SGEN_PROTOCOL_CEMENT_RESET: {
187 printf ("cement_reset\n");
190 case SGEN_PROTOCOL_DISLINK_UPDATE: {
191 SGenProtocolDislinkUpdate *entry = data;
192 printf ("dislink_update link %p obj %p staged %d", entry->link, entry->obj, entry->staged);
194 printf (" track %d\n", entry->track);
199 case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: {
200 SGenProtocolDislinkUpdateStaged *entry = data;
201 printf ("dislink_update_staged link %p obj %p index %d", entry->link, entry->obj, entry->index);
203 printf (" track %d\n", entry->track);
208 case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: {
209 SGenProtocolDislinkProcessStaged *entry = data;
210 printf ("dislink_process_staged link %p obj %p index %d\n", entry->link, entry->obj, entry->index);
213 case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN: {
214 SGenProtocolDomainUnload *entry = data;
215 printf ("dislink_unload_begin domain %p\n", entry->domain);
218 case SGEN_PROTOCOL_DOMAIN_UNLOAD_END: {
219 SGenProtocolDomainUnload *entry = data;
220 printf ("dislink_unload_end domain %p\n", entry->domain);
229 matches_interval (gpointer ptr, gpointer start, int size)
231 return ptr >= start && (char*)ptr < (char*)start + size;
235 is_match (gpointer ptr, int type, void *data)
238 case SGEN_PROTOCOL_COLLECTION_FORCE:
239 case SGEN_PROTOCOL_COLLECTION_BEGIN:
240 case SGEN_PROTOCOL_COLLECTION_END:
241 case SGEN_PROTOCOL_THREAD_SUSPEND:
242 case SGEN_PROTOCOL_THREAD_RESTART:
243 case SGEN_PROTOCOL_THREAD_REGISTER:
244 case SGEN_PROTOCOL_THREAD_UNREGISTER:
245 case SGEN_PROTOCOL_CEMENT_RESET:
246 case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN:
247 case SGEN_PROTOCOL_DOMAIN_UNLOAD_END:
249 case SGEN_PROTOCOL_ALLOC:
250 case SGEN_PROTOCOL_ALLOC_PINNED:
251 case SGEN_PROTOCOL_ALLOC_DEGRADED: {
252 SGenProtocolAlloc *entry = data;
253 return matches_interval (ptr, entry->obj, entry->size);
255 case SGEN_PROTOCOL_COPY: {
256 SGenProtocolCopy *entry = data;
257 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
259 case SGEN_PROTOCOL_PIN: {
260 SGenProtocolPin *entry = data;
261 return matches_interval (ptr, entry->obj, entry->size);
263 case SGEN_PROTOCOL_MARK: {
264 SGenProtocolMark *entry = data;
265 return matches_interval (ptr, entry->obj, entry->size);
267 case SGEN_PROTOCOL_SCAN_BEGIN: {
268 SGenProtocolScanBegin *entry = data;
269 return matches_interval (ptr, entry->obj, entry->size);
271 case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
272 SGenProtocolScanVTypeBegin *entry = data;
273 return matches_interval (ptr, entry->obj, entry->size);
275 case SGEN_PROTOCOL_WBARRIER: {
276 SGenProtocolWBarrier *entry = data;
277 return ptr == entry->ptr || ptr == entry->value;
279 case SGEN_PROTOCOL_GLOBAL_REMSET: {
280 SGenProtocolGlobalRemset *entry = data;
281 return ptr == entry->ptr || ptr == entry->value;
283 case SGEN_PROTOCOL_PTR_UPDATE: {
284 SGenProtocolPtrUpdate *entry = data;
285 return ptr == entry->ptr ||
286 matches_interval (ptr, entry->old_value, entry->size) ||
287 matches_interval (ptr, entry->new_value, entry->size);
289 case SGEN_PROTOCOL_CLEANUP: {
290 SGenProtocolCleanup *entry = data;
291 return matches_interval (ptr, entry->ptr, entry->size);
293 case SGEN_PROTOCOL_EMPTY: {
294 SGenProtocolEmpty *entry = data;
295 return matches_interval (ptr, entry->start, entry->size);
297 case SGEN_PROTOCOL_MISSING_REMSET: {
298 SGenProtocolMissingRemset *entry = data;
299 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
301 case SGEN_PROTOCOL_CARD_SCAN: {
302 SGenProtocolCardScan *entry = data;
303 return matches_interval (ptr, entry->start, entry->size);
305 case SGEN_PROTOCOL_CEMENT: {
306 SGenProtocolCement *entry = data;
307 return matches_interval (ptr, entry->obj, entry->size);
309 case SGEN_PROTOCOL_DISLINK_UPDATE: {
310 SGenProtocolDislinkUpdate *entry = data;
311 return ptr == entry->obj || ptr == entry->link;
313 case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: {
314 SGenProtocolDislinkUpdateStaged *entry = data;
315 return ptr == entry->obj || ptr == entry->link;
317 case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: {
318 SGenProtocolDislinkProcessStaged *entry = data;
319 return ptr == entry->obj || ptr == entry->link;
327 is_vtable_match (gpointer ptr, int type, void *data)
330 case SGEN_PROTOCOL_ALLOC:
331 case SGEN_PROTOCOL_ALLOC_PINNED:
332 case SGEN_PROTOCOL_ALLOC_DEGRADED: {
333 SGenProtocolAlloc *entry = data;
334 return ptr == entry->vtable;
336 case SGEN_PROTOCOL_COPY: {
337 SGenProtocolCopy *entry = data;
338 return ptr == entry->vtable;
340 case SGEN_PROTOCOL_PIN: {
341 SGenProtocolPin *entry = data;
342 return ptr == entry->vtable;
344 case SGEN_PROTOCOL_SCAN_BEGIN: {
345 SGenProtocolScanBegin *entry = data;
346 return ptr == entry->vtable;
348 case SGEN_PROTOCOL_WBARRIER: {
349 SGenProtocolWBarrier *entry = data;
350 return ptr == entry->value_vtable;
352 case SGEN_PROTOCOL_GLOBAL_REMSET: {
353 SGenProtocolGlobalRemset *entry = data;
354 return ptr == entry->value_vtable;
356 case SGEN_PROTOCOL_PTR_UPDATE: {
357 SGenProtocolPtrUpdate *entry = data;
358 return ptr == entry->vtable;
360 case SGEN_PROTOCOL_CLEANUP: {
361 SGenProtocolCleanup *entry = data;
362 return ptr == entry->vtable;
364 case SGEN_PROTOCOL_MISSING_REMSET: {
365 SGenProtocolMissingRemset *entry = data;
366 return ptr == entry->obj_vtable || ptr == entry->value_vtable;
368 case SGEN_PROTOCOL_CEMENT: {
369 SGenProtocolCement *entry = data;
370 return ptr == entry->vtable;
377 static gboolean dump_all = FALSE;
380 main (int argc, char *argv[])
384 int num_args = argc - 1;
388 long nums [num_args];
389 long vtables [num_args];
391 for (i = 0; i < num_args; ++i) {
392 char *arg = argv [i + 1];
393 char *next_arg = argv [i + 2];
394 if (!strcmp (arg, "--all")) {
396 } else if (!strcmp (arg, "-v") || !strcmp (arg, "--vtable")) {
397 vtables [num_vtables++] = strtoul (next_arg, NULL, 16);
400 nums [num_nums++] = strtoul (arg, NULL, 16);
404 while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
405 gboolean match = FALSE;
406 for (i = 0; i < num_nums; ++i) {
407 if (is_match ((gpointer) nums [i], type, data)) {
413 for (i = 0; i < num_vtables; ++i) {
414 if (is_vtable_match ((gpointer) vtables [i], type, data)) {
421 printf (match ? "* " : " ");
422 if (match || dump_all)
423 print_entry (type, data);