6 #define SGEN_BINARY_PROTOCOL
9 #include <mono/metadata/sgen-protocol.h>
11 #define SGEN_PROTOCOL_EOF 255
13 #define TYPE(t) ((t) & 0x7f)
14 #define WORKER(t) ((t) & 0x80)
17 read_entry (FILE *in, void **data)
22 if (fread (&type, 1, 1, in) != 1)
23 return SGEN_PROTOCOL_EOF;
24 switch (TYPE (type)) {
26 #define BEGIN_PROTOCOL_ENTRY0(method) \
27 case PROTOCOL_ID(method): size = 0; break;
28 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
29 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
30 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
31 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
32 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
33 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
34 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
35 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
36 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
37 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
38 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
39 case PROTOCOL_ID(method): size = sizeof (PROTOCOL_STRUCT(method)); break;
41 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
42 BEGIN_PROTOCOL_ENTRY0 (method)
43 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
44 BEGIN_PROTOCOL_ENTRY1 (method,t1,f1)
45 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
46 BEGIN_PROTOCOL_ENTRY2 (method,t1,f1,t2,f2)
47 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
48 BEGIN_PROTOCOL_ENTRY3 (method,t1,f1,t2,f2,t3,f3)
49 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
50 BEGIN_PROTOCOL_ENTRY4 (method,t1,f1,t2,f2,t3,f3,t4,f4)
51 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
52 BEGIN_PROTOCOL_ENTRY5 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5)
53 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
54 BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
58 #define DEFAULT_PRINT()
59 #define CUSTOM_PRINT(_)
61 #define IS_ALWAYS_MATCH(_)
62 #define MATCH_INDEX(_)
63 #define IS_VTABLE_MATCH(_)
65 #define END_PROTOCOL_ENTRY
66 #define END_PROTOCOL_ENTRY_HEAVY
68 #include <mono/metadata/sgen-protocol-def.h>
74 *data = malloc (size);
75 if (fread (*data, size, 1, in) != 1)
85 is_always_match (int type)
87 switch (TYPE (type)) {
88 #define BEGIN_PROTOCOL_ENTRY0(method) \
89 case PROTOCOL_ID(method):
90 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
91 case PROTOCOL_ID(method):
92 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
93 case PROTOCOL_ID(method):
94 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
95 case PROTOCOL_ID(method):
96 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
97 case PROTOCOL_ID(method):
98 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
99 case PROTOCOL_ID(method):
100 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
101 case PROTOCOL_ID(method):
103 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
104 BEGIN_PROTOCOL_ENTRY0 (method)
105 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
106 BEGIN_PROTOCOL_ENTRY1 (method,t1,f1)
107 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
108 BEGIN_PROTOCOL_ENTRY2 (method,t1,f1,t2,f2)
109 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
110 BEGIN_PROTOCOL_ENTRY3 (method,t1,f1,t2,f2,t3,f3)
111 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
112 BEGIN_PROTOCOL_ENTRY4 (method,t1,f1,t2,f2,t3,f3,t4,f4)
113 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
114 BEGIN_PROTOCOL_ENTRY5 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5)
115 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
116 BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
120 #define DEFAULT_PRINT()
121 #define CUSTOM_PRINT(_)
123 #define IS_ALWAYS_MATCH(is_always_match) \
124 return is_always_match;
125 #define MATCH_INDEX(_)
126 #define IS_VTABLE_MATCH(_)
128 #define END_PROTOCOL_ENTRY
129 #define END_PROTOCOL_ENTRY_HEAVY
131 #include <mono/metadata/sgen-protocol-def.h>
137 #define WORKER_PREFIX(t) (WORKER ((t)) ? "w" : " ")
139 enum { NO_COLOR = -1 };
145 /* The index of the ANSI color with which to highlight
146 * this entry, or NO_COLOR for no highlighting.
153 #define TYPE_LONGLONG 1
155 #define TYPE_POINTER 3
158 print_entry_content (int entries_size, PrintEntry *entries, gboolean color_output)
161 for (i = 0; i < entries_size; ++i) {
162 printf ("%s%s ", i == 0 ? "" : " ", entries [i].name);
163 if (color_output && entries [i].color != NO_COLOR)
164 /* Set foreground color, excluding black & white. */
165 printf ("\x1B[%dm", 31 + (entries [i].color % 6));
166 switch (entries [i].type) {
168 printf ("%d", *(int*) entries [i].data);
171 printf ("%lld", *(long long*) entries [i].data);
174 printf ("%lu", *(size_t*) entries [i].data);
177 printf ("%p", *(gpointer*) entries [i].data);
182 if (color_output && entries [i].color != NO_COLOR)
183 /* Reset foreground color to default. */
189 index_color (int index, int num_nums, int *match_indices)
192 for (result = 0; result < num_nums + 1; ++result)
193 if (index == match_indices [result])
199 print_entry (int type, void *data, int num_nums, int *match_indices, gboolean color_output)
201 const char *always_prefix = is_always_match (type) ? " " : "";
202 printf ("%s%s ", WORKER_PREFIX (type), always_prefix);
204 switch (TYPE (type)) {
206 #define BEGIN_PROTOCOL_ENTRY0(method) \
207 case PROTOCOL_ID(method): { \
208 const int pes_size G_GNUC_UNUSED = 0; \
209 PrintEntry pes [1] G_GNUC_UNUSED; \
210 printf ("%s", #method + strlen ("binary_protocol_"));
211 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
212 case PROTOCOL_ID(method): { \
213 PROTOCOL_STRUCT (method) *entry = data; \
214 const int pes_size G_GNUC_UNUSED = 1; \
215 PrintEntry pes [1] G_GNUC_UNUSED; \
217 pes [0].name = #f1; \
218 pes [0].data = &entry->f1; \
219 pes [0].color = index_color(0, num_nums, match_indices); \
220 printf ("%s ", #method + strlen ("binary_protocol_"));
221 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
222 case PROTOCOL_ID(method): { \
223 PROTOCOL_STRUCT (method) *entry = data; \
224 const int pes_size G_GNUC_UNUSED = 2; \
225 PrintEntry pes [2] G_GNUC_UNUSED; \
227 pes [0].name = #f1; \
228 pes [0].data = &entry->f1; \
229 pes [0].color = index_color(0, num_nums, match_indices); \
231 pes [1].name = #f2; \
232 pes [1].data = &entry->f2; \
233 pes [1].color = index_color(1, num_nums, match_indices); \
234 printf ("%s ", #method + strlen ("binary_protocol_"));
235 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
236 case PROTOCOL_ID(method): { \
237 PROTOCOL_STRUCT (method) *entry = data; \
238 const int pes_size G_GNUC_UNUSED = 3; \
239 PrintEntry pes [3] G_GNUC_UNUSED; \
241 pes [0].name = #f1; \
242 pes [0].data = &entry->f1; \
243 pes [0].color = index_color(0, num_nums, match_indices); \
245 pes [1].name = #f2; \
246 pes [1].data = &entry->f2; \
247 pes [1].color = index_color(1, num_nums, match_indices); \
249 pes [2].name = #f3; \
250 pes [2].data = &entry->f3; \
251 pes [2].color = index_color(2, num_nums, match_indices); \
252 printf ("%s ", #method + strlen ("binary_protocol_"));
253 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
254 case PROTOCOL_ID(method): { \
255 PROTOCOL_STRUCT (method) *entry = data; \
256 const int pes_size G_GNUC_UNUSED = 4; \
257 PrintEntry pes [4] G_GNUC_UNUSED; \
259 pes [0].name = #f1; \
260 pes [0].data = &entry->f1; \
261 pes [0].color = index_color(0, num_nums, match_indices); \
263 pes [1].name = #f2; \
264 pes [1].data = &entry->f2; \
265 pes [1].color = index_color(1, num_nums, match_indices); \
267 pes [2].name = #f3; \
268 pes [2].data = &entry->f3; \
269 pes [2].color = index_color(2, num_nums, match_indices); \
271 pes [3].name = #f4; \
272 pes [3].data = &entry->f4; \
273 pes [3].color = index_color(3, num_nums, match_indices); \
274 printf ("%s ", #method + strlen ("binary_protocol_"));
275 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
276 case PROTOCOL_ID(method): { \
277 PROTOCOL_STRUCT (method) *entry = data; \
278 const int pes_size G_GNUC_UNUSED = 5; \
279 PrintEntry pes [5] G_GNUC_UNUSED; \
281 pes [0].name = #f1; \
282 pes [0].data = &entry->f1; \
283 pes [0].color = index_color(0, num_nums, match_indices); \
285 pes [1].name = #f2; \
286 pes [1].data = &entry->f2; \
287 pes [1].color = index_color(1, num_nums, match_indices); \
289 pes [2].name = #f3; \
290 pes [2].data = &entry->f3; \
291 pes [2].color = index_color(2, num_nums, match_indices); \
293 pes [3].name = #f4; \
294 pes [3].data = &entry->f4; \
295 pes [3].color = index_color(3, num_nums, match_indices); \
297 pes [4].name = #f5; \
298 pes [4].data = &entry->f5; \
299 pes [4].color = index_color(4, num_nums, match_indices); \
300 printf ("%s ", #method + strlen ("binary_protocol_"));
301 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
302 case PROTOCOL_ID(method): { \
303 PROTOCOL_STRUCT (method) *entry = data; \
304 const int pes_size G_GNUC_UNUSED = 6; \
305 PrintEntry pes [6] G_GNUC_UNUSED; \
307 pes [0].name = #f1; \
308 pes [0].data = &entry->f1; \
309 pes [0].color = index_color(0, num_nums, match_indices); \
311 pes [1].name = #f2; \
312 pes [1].data = &entry->f2; \
313 pes [1].color = index_color(1, num_nums, match_indices); \
315 pes [2].name = #f3; \
316 pes [2].data = &entry->f3; \
317 pes [2].color = index_color(2, num_nums, match_indices); \
319 pes [3].name = #f4; \
320 pes [3].data = &entry->f4; \
321 pes [3].color = index_color(3, num_nums, match_indices); \
323 pes [4].name = #f5; \
324 pes [4].data = &entry->f5; \
325 pes [4].color = index_color(4, num_nums, match_indices); \
327 pes [5].name = #f6; \
328 pes [5].data = &entry->f6; \
329 pes [5].color = index_color(5, num_nums, match_indices); \
330 printf ("%s ", #method + strlen ("binary_protocol_"));
332 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
333 BEGIN_PROTOCOL_ENTRY0 (method)
334 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
335 BEGIN_PROTOCOL_ENTRY1 (method,t1,f1)
336 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
337 BEGIN_PROTOCOL_ENTRY2 (method,t1,f1,t2,f2)
338 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
339 BEGIN_PROTOCOL_ENTRY3 (method,t1,f1,t2,f2,t3,f3)
340 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
341 BEGIN_PROTOCOL_ENTRY4 (method,t1,f1,t2,f2,t3,f3,t4,f4)
342 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
343 BEGIN_PROTOCOL_ENTRY5 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5)
344 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
345 BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
349 #define DEFAULT_PRINT() \
350 print_entry_content (pes_size, pes, color_output);
351 #define CUSTOM_PRINT(print) \
354 #define IS_ALWAYS_MATCH(_)
355 #define MATCH_INDEX(_)
356 #define IS_VTABLE_MATCH(_)
358 #define END_PROTOCOL_ENTRY \
362 #define END_PROTOCOL_ENTRY_HEAVY \
365 #include <mono/metadata/sgen-protocol-def.h>
377 #define TYPE_LONGLONG long long
378 #define TYPE_SIZE size_t
379 #define TYPE_POINTER gpointer
382 matches_interval (gpointer ptr, gpointer start, int size)
384 return ptr >= start && (char*)ptr < (char*)start + size;
387 /* Returns the index of the field where a match was found,
388 * BINARY_PROTOCOL_NO_MATCH for no match, or
389 * BINARY_PROTOCOL_MATCH for a match with no index.
392 match_index (gpointer ptr, int type, void *data)
394 switch (TYPE (type)) {
396 #define BEGIN_PROTOCOL_ENTRY0(method) \
397 case PROTOCOL_ID (method): {
398 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
399 case PROTOCOL_ID (method): { \
400 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
401 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
402 case PROTOCOL_ID (method): { \
403 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
404 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
405 case PROTOCOL_ID (method): { \
406 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
407 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
408 case PROTOCOL_ID (method): { \
409 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
410 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
411 case PROTOCOL_ID (method): { \
412 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
413 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
414 case PROTOCOL_ID (method): { \
415 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
417 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
418 BEGIN_PROTOCOL_ENTRY0 (method)
419 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
420 BEGIN_PROTOCOL_ENTRY1 (method,t1,f1)
421 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
422 BEGIN_PROTOCOL_ENTRY2 (method,t1,f1,t2,f2)
423 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
424 BEGIN_PROTOCOL_ENTRY3 (method,t1,f1,t2,f2,t3,f3)
425 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
426 BEGIN_PROTOCOL_ENTRY4 (method,t1,f1,t2,f2,t3,f3,t4,f4)
427 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
428 BEGIN_PROTOCOL_ENTRY5 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5)
429 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
430 BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
434 #define DEFAULT_PRINT()
435 #define CUSTOM_PRINT(_)
437 #define IS_ALWAYS_MATCH(_)
438 #define MATCH_INDEX(block) \
440 #define IS_VTABLE_MATCH(_)
442 #define END_PROTOCOL_ENTRY \
445 #define END_PROTOCOL_ENTRY_HEAVY \
448 #include <mono/metadata/sgen-protocol-def.h>
455 is_vtable_match (gpointer ptr, int type, void *data)
457 switch (TYPE (type)) {
459 #define BEGIN_PROTOCOL_ENTRY0(method) \
460 case PROTOCOL_ID (method): {
461 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
462 case PROTOCOL_ID (method): { \
463 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
464 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
465 case PROTOCOL_ID (method): { \
466 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
467 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
468 case PROTOCOL_ID (method): { \
469 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
470 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
471 case PROTOCOL_ID (method): { \
472 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
473 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
474 case PROTOCOL_ID (method): { \
475 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
476 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
477 case PROTOCOL_ID (method): { \
478 PROTOCOL_STRUCT (method) *entry G_GNUC_UNUSED = data;
480 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
481 BEGIN_PROTOCOL_ENTRY0 (method)
482 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
483 BEGIN_PROTOCOL_ENTRY1 (method,t1,f1)
484 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
485 BEGIN_PROTOCOL_ENTRY2 (method,t1,f1,t2,f2)
486 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
487 BEGIN_PROTOCOL_ENTRY3 (method,t1,f1,t2,f2,t3,f3)
488 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
489 BEGIN_PROTOCOL_ENTRY4 (method,t1,f1,t2,f2,t3,f3,t4,f4)
490 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
491 BEGIN_PROTOCOL_ENTRY5 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5)
492 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
493 BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
497 #define DEFAULT_PRINT()
498 #define CUSTOM_PRINT(_)
500 #define IS_ALWAYS_MATCH(_)
501 #define MATCH_INDEX(block) \
503 #define IS_VTABLE_MATCH(_)
505 #define END_PROTOCOL_ENTRY \
508 #define END_PROTOCOL_ENTRY_HEAVY \
511 #include <mono/metadata/sgen-protocol-def.h>
523 main (int argc, char *argv[])
527 int num_args = argc - 1;
531 long nums [num_args];
532 long vtables [num_args];
533 gboolean dump_all = FALSE;
534 gboolean pause_times = FALSE;
535 gboolean pause_times_stopped = FALSE;
536 gboolean pause_times_concurrent = FALSE;
537 gboolean pause_times_finish = FALSE;
538 gboolean color_output = FALSE;
539 long long pause_times_ts = 0;
541 for (i = 0; i < num_args; ++i) {
542 char *arg = argv [i + 1];
543 char *next_arg = argv [i + 2];
544 if (!strcmp (arg, "--all")) {
546 } else if (!strcmp (arg, "--pause-times")) {
548 } else if (!strcmp (arg, "-v") || !strcmp (arg, "--vtable")) {
549 vtables [num_vtables++] = strtoul (next_arg, NULL, 16);
551 } else if (!strcmp (arg, "-c") || !strcmp (arg, "--color")) {
554 nums [num_nums++] = strtoul (arg, NULL, 16);
559 assert (!pause_times);
563 while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
566 case PROTOCOL_ID (binary_protocol_world_stopping): {
567 PROTOCOL_STRUCT (binary_protocol_world_stopping) *entry = data;
568 assert (!pause_times_stopped);
569 pause_times_concurrent = FALSE;
570 pause_times_finish = FALSE;
571 pause_times_ts = entry->timestamp;
572 pause_times_stopped = TRUE;
575 case PROTOCOL_ID (binary_protocol_concurrent_finish):
576 pause_times_finish = TRUE;
577 case PROTOCOL_ID (binary_protocol_concurrent_start):
578 case PROTOCOL_ID (binary_protocol_concurrent_update):
579 pause_times_concurrent = TRUE;
581 case PROTOCOL_ID (binary_protocol_world_restarted): {
582 PROTOCOL_STRUCT (binary_protocol_world_restarted) *entry = data;
583 assert (pause_times_stopped);
584 printf ("pause-time %d %d %d %lld %lld\n",
586 pause_times_concurrent,
588 entry->timestamp - pause_times_ts,
590 pause_times_stopped = FALSE;
595 int match_indices [num_nums + 1];
596 gboolean match = is_always_match (type);
597 match_indices [num_nums] = num_nums == 0 ? match_index (NULL, type, data) : BINARY_PROTOCOL_NO_MATCH;
598 match = match_indices [num_nums] != BINARY_PROTOCOL_NO_MATCH;
599 for (i = 0; i < num_nums; ++i) {
600 match_indices [i] = match_index ((gpointer) nums [i], type, data);
601 match = match || match_indices [i] != BINARY_PROTOCOL_NO_MATCH;
604 for (i = 0; i < num_vtables; ++i) {
605 if (is_vtable_match ((gpointer) vtables [i], type, data)) {
612 printf (match ? "* " : " ");
613 if (match || dump_all)
614 print_entry (type, data, num_nums, match_indices, color_output);