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