2010-05-28 Mark Probst <mark.probst@gmail.com>
[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 #include <mono/metadata/sgen-protocol.h>
7
8 #define SGEN_PROTOCOL_EOF       255
9
10 static int
11 read_entry (FILE *in, void **data)
12 {
13         unsigned char type;
14         int size;
15
16         if (fread (&type, 1, 1, in) != 1)
17                 return SGEN_PROTOCOL_EOF;
18         switch (type) {
19         case SGEN_PROTOCOL_COLLECTION: size = sizeof (SGenProtocolCollection); break;
20         case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
21         case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
22         case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
23         case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
24         case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
25         case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
26         case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
27         case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
28         case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
29         case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
30         case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
31         case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
32         case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
33         default: assert (0);
34         }
35
36         *data = malloc (size);
37         if (fread (*data, size, 1, in) != 1)
38                 assert (0);
39
40         return (int)type;
41 }
42
43 static void
44 print_entry (int type, void *data)
45 {
46         switch (type) {
47         case SGEN_PROTOCOL_COLLECTION: {
48                 SGenProtocolCollection *entry = data;
49                 printf ("collection generation %d\n", entry->generation);
50                 break;
51         }
52         case SGEN_PROTOCOL_ALLOC: {
53                 SGenProtocolAlloc *entry = data;
54                 printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
55                 break;
56         }
57         case SGEN_PROTOCOL_COPY: {
58                 SGenProtocolCopy *entry = data;
59                 printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
60                 break;
61         }
62         case SGEN_PROTOCOL_PIN: {
63                 SGenProtocolPin *entry = data;
64                 printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
65                 break;
66         }
67         case SGEN_PROTOCOL_MARK: {
68                 SGenProtocolMark *entry = data;
69                 printf ("mark obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
70                 break;
71         }
72         case SGEN_PROTOCOL_WBARRIER: {
73                 SGenProtocolWBarrier *entry = data;
74                 printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
75                 break;
76         }
77         case SGEN_PROTOCOL_GLOBAL_REMSET: {
78                 SGenProtocolGlobalRemset *entry = data;
79                 printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
80                 break;
81         }
82         case SGEN_PROTOCOL_PTR_UPDATE: {
83                 SGenProtocolPtrUpdate *entry = data;
84                 printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
85                                 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
86                 break;
87         }
88         case SGEN_PROTOCOL_CLEANUP: {
89                 SGenProtocolCleanup *entry = data;
90                 printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
91                 break;
92         }
93         case SGEN_PROTOCOL_EMPTY: {
94                 SGenProtocolEmpty *entry = data;
95                 printf ("empty start %p size %d\n", entry->start, entry->size);
96                 break;
97         }
98         case SGEN_PROTOCOL_THREAD_RESTART: {
99                 SGenProtocolThreadRestart *entry = data;
100                 printf ("thread_restart thread %p\n", entry->thread);
101                 break;
102         }
103         case SGEN_PROTOCOL_THREAD_REGISTER: {
104                 SGenProtocolThreadRegister *entry = data;
105                 printf ("thread_register thread %p\n", entry->thread);
106                 break;
107         }
108         case SGEN_PROTOCOL_THREAD_UNREGISTER: {
109                 SGenProtocolThreadUnregister *entry = data;
110                 printf ("thread_unregister thread %p\n", entry->thread);
111                 break;
112         }
113         case SGEN_PROTOCOL_MISSING_REMSET: {
114                 SGenProtocolMissingRemset *entry = data;
115                 printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
116                                 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
117                 break;
118         }
119         default:
120                 assert (0);
121         }
122 }
123
124 static gboolean
125 matches_interval (gpointer ptr, gpointer start, int size)
126 {
127         return ptr >= start && (char*)ptr < (char*)start + size;
128 }
129
130 static gboolean
131 is_match (gpointer ptr, int type, void *data)
132 {
133         switch (type) {
134         case SGEN_PROTOCOL_COLLECTION:
135         case SGEN_PROTOCOL_THREAD_RESTART:
136         case SGEN_PROTOCOL_THREAD_REGISTER:
137         case SGEN_PROTOCOL_THREAD_UNREGISTER:
138                 return TRUE;
139         case SGEN_PROTOCOL_ALLOC: {
140                 SGenProtocolAlloc *entry = data;
141                 return matches_interval (ptr, entry->obj, entry->size);
142         }
143         case SGEN_PROTOCOL_COPY: {
144                 SGenProtocolCopy *entry = data;
145                 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
146         }
147         case SGEN_PROTOCOL_PIN: {
148                 SGenProtocolPin *entry = data;
149                 return matches_interval (ptr, entry->obj, entry->size);
150         }
151         case SGEN_PROTOCOL_MARK: {
152                 SGenProtocolMark *entry = data;
153                 return matches_interval (ptr, entry->obj, entry->size);
154         }
155         case SGEN_PROTOCOL_WBARRIER: {
156                 SGenProtocolWBarrier *entry = data;
157                 return ptr == entry->ptr || ptr == entry->value;
158         }
159         case SGEN_PROTOCOL_GLOBAL_REMSET: {
160                 SGenProtocolGlobalRemset *entry = data;
161                 return ptr == entry->ptr || ptr == entry->value;
162         }
163         case SGEN_PROTOCOL_PTR_UPDATE: {
164                 SGenProtocolPtrUpdate *entry = data;
165                 return ptr == entry->ptr ||
166                         matches_interval (ptr, entry->old_value, entry->size) ||
167                         matches_interval (ptr, entry->new_value, entry->size);
168         }
169         case SGEN_PROTOCOL_CLEANUP: {
170                 SGenProtocolCleanup *entry = data;
171                 return matches_interval (ptr, entry->ptr, entry->size);
172         }
173         case SGEN_PROTOCOL_EMPTY: {
174                 SGenProtocolEmpty *entry = data;
175                 return matches_interval (ptr, entry->start, entry->size);
176         }
177         case SGEN_PROTOCOL_MISSING_REMSET: {
178                 SGenProtocolMissingRemset *entry = data;
179                 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
180         }
181         default:
182                 assert (0);
183         }
184 }
185
186 int
187 main (int argc, char *argv[])
188 {
189         int type;
190         void *data;
191         int num_nums = argc - 1;
192         int i;
193         long nums [num_nums];
194
195         for (i = 0; i < num_nums; ++i)
196                 nums [i] = strtoul (argv [i + 1], NULL, 16);
197
198         while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
199                 gboolean match = FALSE;
200                 for (i = 0; i < num_nums; ++i) {
201                         if (is_match ((gpointer) nums [i], type, data)) {
202                                 match = TRUE;
203                                 break;
204                         }
205                 }
206                 if (match)
207                         print_entry (type, data);
208                 free (data);
209         }
210
211         return 0;
212 }