Merge pull request #949 from ermshiperete/bug-novell-463149
[mono.git] / tools / sgen / sgen-grep-binprot.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <glib.h>
5
6 #define SGEN_BINARY_PROTOCOL
7 #define MONO_INTERNAL
8
9 #include <mono/metadata/sgen-protocol.h>
10
11 #define SGEN_PROTOCOL_EOF       255
12
13 #define TYPE(t)         ((t) & 0x7f)
14 #define WORKER(t)       ((t) & 0x80)
15
16 static int
17 read_entry (FILE *in, void **data)
18 {
19         unsigned char type;
20         int size;
21
22         if (fread (&type, 1, 1, in) != 1)
23                 return SGEN_PROTOCOL_EOF;
24         switch (TYPE (type)) {
25         case SGEN_PROTOCOL_COLLECTION_FORCE: size = sizeof (SGenProtocolCollectionForce); break;
26         case SGEN_PROTOCOL_COLLECTION_BEGIN: size = sizeof (SGenProtocolCollection); break;
27         case SGEN_PROTOCOL_COLLECTION_END: size = sizeof (SGenProtocolCollection); break;
28         case SGEN_PROTOCOL_CONCURRENT_START: size = 0; break;
29         case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH: size = 0; break;
30         case SGEN_PROTOCOL_WORLD_STOPPING: size = sizeof (SGenProtocolWorldStopping); break;
31         case SGEN_PROTOCOL_WORLD_STOPPED: size = sizeof (SGenProtocolWorldStopped); break;
32         case SGEN_PROTOCOL_WORLD_RESTARTING: size = sizeof (SGenProtocolWorldRestarting); break;
33         case SGEN_PROTOCOL_WORLD_RESTARTED: size = sizeof (SGenProtocolWorldRestarted); break;
34         case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
35         case SGEN_PROTOCOL_ALLOC_PINNED: size = sizeof (SGenProtocolAlloc); break;
36         case SGEN_PROTOCOL_ALLOC_DEGRADED: size = sizeof (SGenProtocolAlloc); break;
37         case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
38         case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
39         case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
40         case SGEN_PROTOCOL_SCAN_BEGIN: size = sizeof (SGenProtocolScanBegin); break;
41         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: size = sizeof (SGenProtocolScanVTypeBegin); break;
42         case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
43         case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
44         case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
45         case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
46         case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
47         case SGEN_PROTOCOL_THREAD_SUSPEND: size = sizeof (SGenProtocolThreadSuspend); break;
48         case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
49         case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
50         case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
51         case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
52         case SGEN_PROTOCOL_CARD_SCAN: size = sizeof (SGenProtocolCardScan); break;
53         case SGEN_PROTOCOL_CEMENT: size = sizeof (SGenProtocolCement); break;
54         case SGEN_PROTOCOL_CEMENT_RESET: size = 0; break;
55         case SGEN_PROTOCOL_DISLINK_UPDATE: size = sizeof (SGenProtocolDislinkUpdate); break;
56         case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: size = sizeof (SGenProtocolDislinkUpdateStaged); break;
57         case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: size = sizeof (SGenProtocolDislinkProcessStaged); break;
58         case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN: size = sizeof (SGenProtocolDomainUnload); break;
59         case SGEN_PROTOCOL_DOMAIN_UNLOAD_END: size = sizeof (SGenProtocolDomainUnload); break;
60         default: assert (0);
61         }
62
63         if (size) {
64                 *data = malloc (size);
65                 if (fread (*data, size, 1, in) != 1)
66                         assert (0);
67         } else {
68                 *data = NULL;
69         }
70
71         return (int)type;
72 }
73
74 #define WORKER_PREFIX(t)        (WORKER ((t)) ? "w" : " ")
75
76 static void
77 print_entry (int type, void *data)
78 {
79         switch (TYPE (type)) {
80         case SGEN_PROTOCOL_COLLECTION_FORCE: {
81                 SGenProtocolCollectionForce *entry = data;
82                 printf ("%s collection force generation %d\n", WORKER_PREFIX (type), entry->generation);
83                 break;
84         }
85         case SGEN_PROTOCOL_COLLECTION_BEGIN: {
86                 SGenProtocolCollection *entry = data;
87                 printf ("%s collection begin %d generation %d\n", WORKER_PREFIX (type), entry->index, entry->generation);
88                 break;
89         }
90         case SGEN_PROTOCOL_COLLECTION_END: {
91                 SGenProtocolCollection *entry = data;
92                 printf ("%s collection end %d generation %d\n", WORKER_PREFIX (type), entry->index, entry->generation);
93                 break;
94         }
95         case SGEN_PROTOCOL_CONCURRENT_START: {
96                 printf ("%s concurrent start\n", WORKER_PREFIX (type));
97                 break;
98         }
99         case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH: {
100                 printf ("%s concurrent update or finish\n", WORKER_PREFIX (type));
101                 break;
102         }
103         case SGEN_PROTOCOL_WORLD_STOPPING: {
104                 SGenProtocolWorldStopping *entry = data;
105                 printf ("%s world stopping timestamp %lld\n", WORKER_PREFIX (type), entry->timestamp);
106                 break;
107         }
108         case SGEN_PROTOCOL_WORLD_STOPPED: {
109                 SGenProtocolWorldStopped *entry = data;
110                 long long total = entry->total_major_cards + entry->total_los_cards;
111                 long long marked = entry->marked_major_cards + entry->marked_los_cards;
112                 printf ("%s world stopped timestamp %lld total %lld marked %lld %0.2f%%\n", WORKER_PREFIX (type), entry->timestamp, total, marked, 100.0 * (double) marked / (double) total);
113                 break;
114         }
115         case SGEN_PROTOCOL_WORLD_RESTARTING: {
116                 SGenProtocolWorldRestarting *entry = data;
117                 long long total = entry->total_major_cards + entry->total_los_cards;
118                 long long marked = entry->marked_major_cards + entry->marked_los_cards;
119                 printf ("%s world restarting generation %d timestamp %lld total %lld marked %lld %0.2f%%\n", WORKER_PREFIX (type), entry->generation, entry->timestamp, total, marked, 100.0 * (double) marked / (double) total);
120                 break;
121         }
122         case SGEN_PROTOCOL_WORLD_RESTARTED: {
123                 SGenProtocolWorldRestarted *entry = data;
124                 printf ("%s world restarted generation %d timestamp %lld\n", WORKER_PREFIX (type), entry->generation, entry->timestamp);
125                 break;
126         }
127         case SGEN_PROTOCOL_ALLOC: {
128                 SGenProtocolAlloc *entry = data;
129                 printf ("%s alloc obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
130                 break;
131         }
132         case SGEN_PROTOCOL_ALLOC_PINNED: {
133                 SGenProtocolAlloc *entry = data;
134                 printf ("%s alloc pinned obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
135                 break;
136         }
137         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
138                 SGenProtocolAlloc *entry = data;
139                 printf ("%s alloc degraded obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
140                 break;
141         }
142         case SGEN_PROTOCOL_COPY: {
143                 SGenProtocolCopy *entry = data;
144                 printf ("%s copy from %p to %p vtable %p size %d\n", WORKER_PREFIX (type), entry->from, entry->to, entry->vtable, entry->size);
145                 break;
146         }
147         case SGEN_PROTOCOL_PIN: {
148                 SGenProtocolPin *entry = data;
149                 printf ("%s pin obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
150                 break;
151         }
152         case SGEN_PROTOCOL_MARK: {
153                 SGenProtocolMark *entry = data;
154                 printf ("%s mark obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
155                 break;
156         }
157         case SGEN_PROTOCOL_SCAN_BEGIN: {
158                 SGenProtocolScanBegin *entry = data;
159                 printf ("%s scan_begin obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
160                 break;
161         }
162         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
163                 SGenProtocolScanVTypeBegin *entry = data;
164                 printf ("%s scan_vtype_begin obj %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->size);
165                 break;
166         }
167         case SGEN_PROTOCOL_WBARRIER: {
168                 SGenProtocolWBarrier *entry = data;
169                 printf ("%s wbarrier ptr %p value %p value_vtable %p\n", WORKER_PREFIX (type), entry->ptr, entry->value, entry->value_vtable);
170                 break;
171         }
172         case SGEN_PROTOCOL_GLOBAL_REMSET: {
173                 SGenProtocolGlobalRemset *entry = data;
174                 printf ("%s global_remset ptr %p value %p value_vtable %p\n", WORKER_PREFIX (type), entry->ptr, entry->value, entry->value_vtable);
175                 break;
176         }
177         case SGEN_PROTOCOL_PTR_UPDATE: {
178                 SGenProtocolPtrUpdate *entry = data;
179                 printf ("%s ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n", WORKER_PREFIX (type),
180                                 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
181                 break;
182         }
183         case SGEN_PROTOCOL_CLEANUP: {
184                 SGenProtocolCleanup *entry = data;
185                 printf ("%s cleanup ptr %p vtable %p size %d\n", WORKER_PREFIX (type), entry->ptr, entry->vtable, entry->size);
186                 break;
187         }
188         case SGEN_PROTOCOL_EMPTY: {
189                 SGenProtocolEmpty *entry = data;
190                 printf ("%s empty start %p size %d\n", WORKER_PREFIX (type), entry->start, entry->size);
191                 break;
192         }
193         case SGEN_PROTOCOL_THREAD_SUSPEND: {
194                 SGenProtocolThreadSuspend *entry = data;
195                 printf ("%s thread_suspend thread %p ip %p\n", WORKER_PREFIX (type), entry->thread, entry->stopped_ip);
196                 break;
197         }
198         case SGEN_PROTOCOL_THREAD_RESTART: {
199                 SGenProtocolThreadRestart *entry = data;
200                 printf ("%s thread_restart thread %p\n", WORKER_PREFIX (type), entry->thread);
201                 break;
202         }
203         case SGEN_PROTOCOL_THREAD_REGISTER: {
204                 SGenProtocolThreadRegister *entry = data;
205                 printf ("%s thread_register thread %p\n", WORKER_PREFIX (type), entry->thread);
206                 break;
207         }
208         case SGEN_PROTOCOL_THREAD_UNREGISTER: {
209                 SGenProtocolThreadUnregister *entry = data;
210                 printf ("%s thread_unregister thread %p\n", WORKER_PREFIX (type), entry->thread);
211                 break;
212         }
213         case SGEN_PROTOCOL_MISSING_REMSET: {
214                 SGenProtocolMissingRemset *entry = data;
215                 printf ("%s missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n", WORKER_PREFIX (type),
216                                 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
217                 break;
218         }
219         case SGEN_PROTOCOL_CARD_SCAN: {
220                 SGenProtocolCardScan *entry = data;
221                 printf ("%s card_scan start %p size %d\n", WORKER_PREFIX (type), entry->start, entry->size);
222                 break;
223         }
224         case SGEN_PROTOCOL_CEMENT: {
225                 SGenProtocolCement *entry = data;
226                 printf ("%s cement obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
227                 break;
228         }
229         case SGEN_PROTOCOL_CEMENT_RESET: {
230                 printf ("%s cement_reset\n", WORKER_PREFIX (type));
231                 break;
232         }
233         case SGEN_PROTOCOL_DISLINK_UPDATE: {
234                 SGenProtocolDislinkUpdate *entry = data;
235                 printf ("%s dislink_update link %p obj %p staged %d", WORKER_PREFIX (type), entry->link, entry->obj, entry->staged);
236                 if (entry->obj)
237                         printf (" track %d\n", entry->track);
238                 else
239                         printf ("\n");
240                 break;
241         }
242         case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: {
243                 SGenProtocolDislinkUpdateStaged *entry = data;
244                 printf ("%s dislink_update_staged link %p obj %p index %d", WORKER_PREFIX (type), entry->link, entry->obj, entry->index);
245                 if (entry->obj)
246                         printf (" track %d\n", entry->track);
247                 else
248                         printf ("\n");
249                 break;
250         }
251         case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: {
252                 SGenProtocolDislinkProcessStaged *entry = data;
253                 printf ("%s dislink_process_staged link %p obj %p index %d\n", WORKER_PREFIX (type), entry->link, entry->obj, entry->index);
254                 break;
255         }
256         case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN: {
257                 SGenProtocolDomainUnload *entry = data;
258                 printf ("%s dislink_unload_begin domain %p\n", WORKER_PREFIX (type), entry->domain);
259                 break;
260         }
261         case SGEN_PROTOCOL_DOMAIN_UNLOAD_END: {
262                 SGenProtocolDomainUnload *entry = data;
263                 printf ("%s dislink_unload_end domain %p\n", WORKER_PREFIX (type), entry->domain);
264                 break;
265         }
266         default:
267                 assert (0);
268         }
269 }
270
271 static gboolean
272 matches_interval (gpointer ptr, gpointer start, int size)
273 {
274         return ptr >= start && (char*)ptr < (char*)start + size;
275 }
276
277 static gboolean
278 is_match (gpointer ptr, int type, void *data)
279 {
280         switch (TYPE (type)) {
281         case SGEN_PROTOCOL_COLLECTION_FORCE:
282         case SGEN_PROTOCOL_COLLECTION_BEGIN:
283         case SGEN_PROTOCOL_COLLECTION_END:
284         case SGEN_PROTOCOL_CONCURRENT_START:
285         case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH:
286         case SGEN_PROTOCOL_WORLD_STOPPING:
287         case SGEN_PROTOCOL_WORLD_STOPPED:
288         case SGEN_PROTOCOL_WORLD_RESTARTING:
289         case SGEN_PROTOCOL_WORLD_RESTARTED:
290         case SGEN_PROTOCOL_THREAD_SUSPEND:
291         case SGEN_PROTOCOL_THREAD_RESTART:
292         case SGEN_PROTOCOL_THREAD_REGISTER:
293         case SGEN_PROTOCOL_THREAD_UNREGISTER:
294         case SGEN_PROTOCOL_CEMENT_RESET:
295         case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN:
296         case SGEN_PROTOCOL_DOMAIN_UNLOAD_END:
297                 return TRUE;
298         case SGEN_PROTOCOL_ALLOC:
299         case SGEN_PROTOCOL_ALLOC_PINNED:
300         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
301                 SGenProtocolAlloc *entry = data;
302                 return matches_interval (ptr, entry->obj, entry->size);
303         }
304         case SGEN_PROTOCOL_COPY: {
305                 SGenProtocolCopy *entry = data;
306                 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
307         }
308         case SGEN_PROTOCOL_PIN: {
309                 SGenProtocolPin *entry = data;
310                 return matches_interval (ptr, entry->obj, entry->size);
311         }
312         case SGEN_PROTOCOL_MARK: {
313                 SGenProtocolMark *entry = data;
314                 return matches_interval (ptr, entry->obj, entry->size);
315         }
316         case SGEN_PROTOCOL_SCAN_BEGIN: {
317                 SGenProtocolScanBegin *entry = data;
318                 return matches_interval (ptr, entry->obj, entry->size);
319         }
320         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
321                 SGenProtocolScanVTypeBegin *entry = data;
322                 return matches_interval (ptr, entry->obj, entry->size);
323         }
324         case SGEN_PROTOCOL_WBARRIER: {
325                 SGenProtocolWBarrier *entry = data;
326                 return ptr == entry->ptr || ptr == entry->value;
327         }
328         case SGEN_PROTOCOL_GLOBAL_REMSET: {
329                 SGenProtocolGlobalRemset *entry = data;
330                 return ptr == entry->ptr || ptr == entry->value;
331         }
332         case SGEN_PROTOCOL_PTR_UPDATE: {
333                 SGenProtocolPtrUpdate *entry = data;
334                 return ptr == entry->ptr ||
335                         matches_interval (ptr, entry->old_value, entry->size) ||
336                         matches_interval (ptr, entry->new_value, entry->size);
337         }
338         case SGEN_PROTOCOL_CLEANUP: {
339                 SGenProtocolCleanup *entry = data;
340                 return matches_interval (ptr, entry->ptr, entry->size);
341         }
342         case SGEN_PROTOCOL_EMPTY: {
343                 SGenProtocolEmpty *entry = data;
344                 return matches_interval (ptr, entry->start, entry->size);
345         }
346         case SGEN_PROTOCOL_MISSING_REMSET: {
347                 SGenProtocolMissingRemset *entry = data;
348                 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
349         }
350         case SGEN_PROTOCOL_CARD_SCAN: {
351                 SGenProtocolCardScan *entry = data;
352                 return matches_interval (ptr, entry->start, entry->size);
353         }
354         case SGEN_PROTOCOL_CEMENT: {
355                 SGenProtocolCement *entry = data;
356                 return matches_interval (ptr, entry->obj, entry->size);
357         }
358         case SGEN_PROTOCOL_DISLINK_UPDATE: {
359                 SGenProtocolDislinkUpdate *entry = data;
360                 return ptr == entry->obj || ptr == entry->link;
361         }
362         case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: {
363                 SGenProtocolDislinkUpdateStaged *entry = data;
364                 return ptr == entry->obj || ptr == entry->link;
365         }
366         case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: {
367                 SGenProtocolDislinkProcessStaged *entry = data;
368                 return ptr == entry->obj || ptr == entry->link;
369         }
370         default:
371                 assert (0);
372         }
373 }
374
375 static gboolean
376 is_vtable_match (gpointer ptr, int type, void *data)
377 {
378         switch (TYPE (type)) {
379         case SGEN_PROTOCOL_ALLOC:
380         case SGEN_PROTOCOL_ALLOC_PINNED:
381         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
382                 SGenProtocolAlloc *entry = data;
383                 return ptr == entry->vtable;
384         }
385         case SGEN_PROTOCOL_COPY: {
386                 SGenProtocolCopy *entry = data;
387                 return ptr == entry->vtable;
388         }
389         case SGEN_PROTOCOL_PIN: {
390                 SGenProtocolPin *entry = data;
391                 return ptr == entry->vtable;
392         }
393         case SGEN_PROTOCOL_SCAN_BEGIN: {
394                 SGenProtocolScanBegin *entry = data;
395                 return ptr == entry->vtable;
396         }
397         case SGEN_PROTOCOL_WBARRIER: {
398                 SGenProtocolWBarrier *entry = data;
399                 return ptr == entry->value_vtable;
400         }
401         case SGEN_PROTOCOL_GLOBAL_REMSET: {
402                 SGenProtocolGlobalRemset *entry = data;
403                 return ptr == entry->value_vtable;
404         }
405         case SGEN_PROTOCOL_PTR_UPDATE: {
406                 SGenProtocolPtrUpdate *entry = data;
407                 return ptr == entry->vtable;
408         }
409         case SGEN_PROTOCOL_CLEANUP: {
410                 SGenProtocolCleanup *entry = data;
411                 return ptr == entry->vtable;
412         }
413         case SGEN_PROTOCOL_MISSING_REMSET: {
414                 SGenProtocolMissingRemset *entry = data;
415                 return ptr == entry->obj_vtable || ptr == entry->value_vtable;
416         }
417         case SGEN_PROTOCOL_CEMENT: {
418                 SGenProtocolCement *entry = data;
419                 return ptr == entry->vtable;
420         }
421         default:
422                 return FALSE;
423         }
424 }
425
426 int
427 main (int argc, char *argv[])
428 {
429         int type;
430         void *data;
431         int num_args = argc - 1;
432         int num_nums = 0;
433         int num_vtables = 0;
434         int i;
435         long nums [num_args];
436         long vtables [num_args];
437         gboolean dump_all = FALSE;
438         gboolean pause_times = FALSE;
439         gboolean pause_times_stopped = FALSE;
440         gboolean pause_times_concurrent = FALSE;
441         long long pause_times_ts = 0;
442
443         for (i = 0; i < num_args; ++i) {
444                 char *arg = argv [i + 1];
445                 char *next_arg = argv [i + 2];
446                 if (!strcmp (arg, "--all")) {
447                         dump_all = TRUE;
448                 } else if (!strcmp (arg, "--pause-times")) {
449                         pause_times = TRUE;
450                 } else if (!strcmp (arg, "-v") || !strcmp (arg, "--vtable")) {
451                         vtables [num_vtables++] = strtoul (next_arg, NULL, 16);
452                         ++i;
453                 } else {
454                         nums [num_nums++] = strtoul (arg, NULL, 16);
455                 }
456         }
457
458         if (dump_all)
459                 assert (!pause_times);
460         if (pause_times)
461                 assert (!dump_all);
462
463         while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
464                 if (pause_times) {
465                         switch (type) {
466                         case SGEN_PROTOCOL_WORLD_STOPPING: {
467                                 SGenProtocolWorldStopping *entry = data;
468                                 assert (!pause_times_stopped);
469                                 pause_times_concurrent = FALSE;
470                                 pause_times_ts = entry->timestamp;
471                                 pause_times_stopped = TRUE;
472                                 break;
473                         }
474                         case SGEN_PROTOCOL_CONCURRENT_START:
475                         case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH:
476                                 pause_times_concurrent = TRUE;
477                                 break;
478                         case SGEN_PROTOCOL_WORLD_RESTARTED: {
479                                 SGenProtocolWorldRestarted *entry = data;
480                                 assert (pause_times_stopped);
481                                 printf ("pause-time %d %d %lld %lld\n",
482                                                 entry->generation,
483                                                 pause_times_concurrent,
484                                                 entry->timestamp - pause_times_ts,
485                                                 pause_times_ts);
486                                 pause_times_stopped = FALSE;
487                                 break;
488                         }
489                         }
490                 } else {
491                         gboolean match = num_nums == 0 ? is_match (NULL, type, data) : FALSE;
492                         for (i = 0; i < num_nums; ++i) {
493                                 if (is_match ((gpointer) nums [i], type, data)) {
494                                         match = TRUE;
495                                         break;
496                                 }
497                         }
498                         if (!match) {
499                                 for (i = 0; i < num_vtables; ++i) {
500                                         if (is_vtable_match ((gpointer) vtables [i], type, data)) {
501                                                 match = TRUE;
502                                                 break;
503                                         }
504                                 }
505                         }
506                         if (dump_all)
507                                 printf (match ? "* " : "  ");
508                         if (match || dump_all)
509                                 print_entry (type, data);
510                 }
511                 free (data);
512         }
513
514         return 0;
515 }